From 4543d57d2644e6a99bed20acc1bb01ffc919bd50 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 9 Aug 2024 00:06:23 +0100 Subject: [PATCH] Cleanup, refactor and simplification --- matchy.py | 75 +++++++++++++++++++------------------------------------ util.py | 15 +++++++++++ 2 files changed, 40 insertions(+), 50 deletions(-) create mode 100644 util.py diff --git a/matchy.py b/matchy.py index c00418d..40dc7b2 100755 --- a/matchy.py +++ b/matchy.py @@ -3,79 +3,57 @@ import random import logging from discord import app_commands from discord.ext import commands - +import util # Config contains # TOKEN : str - Discord bot token # SERVERS : list[int] - ids of the servers to have commands active # OWNERS : list[int] - ids of owners able to use the owner commands import config -handler = logging.StreamHandler() +# Set up a logger for matchy logger = logging.getLogger("matchy") logger.setLevel(logging.INFO) +# Create the discord commands bot intents = discord.Intents.default() intents.message_content = True intents.members = True bot = commands.Bot(command_prefix='$', description="Matchy matches matchees", intents=intents) -# Find a role by name -def find_role_by_name(roles: list[discord.Role], name: str) -> discord.Role: - for r in roles: - if r.name == name: - return r - return None - -# Get the ordinal for an int -def get_ordinal(num : int): - if num > 9: - secondToLastDigit = str(num)[-2] - if secondToLastDigit == '1': - return str(num)+'th' - lastDigit = num % 10 - if (lastDigit == 1): - return str(num)+'st' - elif (lastDigit == 2): - return str(num)+'nd' - elif (lastDigit == 3): - return str(num)+'rd' - else: - return str(num)+'th' - guilds = [] -def sync_guilds(): - # Cache the guild info - for guild in bot.guilds: - if guild.id in config.SERVERS: - guilds.append(guild) +def cache_guilds(): + """Sync current bot guilds to a list to use""" + guilds = list(g for g in bot.guilds if g.id in config.SERVERS) logger.info(f"Synced {len(guilds)} guild(s)") @bot.event async def on_ready(): - sync_guilds() + """Cache some info once ready""" + cache_guilds() logger.info("Bot is up and ready!") @bot.command() -async def sync(ctx): - if ctx.author.id not in config.OWNERS: - logger.warning(f"User {ctx.author} unauthorised for sync") - return - - # Sync the commands +@commands.check(lambda ctx: ctx.message.author.id in config.OWNERS) +async def sync(ctx: discord.ext.commands.context.Context): + """Handle sync command""" + # Sync the commands with the discord API synced = await bot.tree.sync() logger.info(f"Synced {len(synced)} command(s)") - - sync_guilds() + # Cache the guild information + cache_guilds() + await ctx.reply("Done!", ephemeral=True) @bot.tree.command(description = "Match matchees into groups", guilds = list(g for g in guilds if g.id in config.SERVERS)) @app_commands.describe(per_group = "Matchees per group") -async def match(interaction: discord.Interaction, per_group: int): +async def match(interaction: discord.Interaction, per_group: int = 3): + """Match groups of channel members""" + logger.info(f"User {interaction.user} requested /match {per_group}") # Grab the roles - matchee_role = find_role_by_name(interaction.guild.roles, "Matchee") - matcher_role = find_role_by_name(interaction.guild.roles, "Matcher") + matchee_role = next(r for r in interaction.guild.roles if r.name == "Matchee") + matcher_role = next(r for r in interaction.guild.roles if r.name == "Matcher") if not matchee_role or not matcher_role: await interaction.response.send_message("Server has missing matchy roles :(", ephemeral=True) return @@ -89,10 +67,7 @@ async def match(interaction: discord.Interaction, per_group: int): await interaction.channel.send(f"{interaction.user.display_name} asked me to match groups of {per_group}! :partying_face:") # Find all the members in the role - matchees = [] - for member in interaction.channel.members: - if not member.bot and matchee_role in member.roles: - matchees.append(member) + matchees = list( m for m in interaction.channel.members if not m.bot and matchee_role in m.roles) logger.info(f"{len(matchees)} matchees found") # Shuffle the people for randomness @@ -100,9 +75,7 @@ async def match(interaction: discord.Interaction, per_group: int): # Calculate the number of groups to generate total_num = len(matchees) - num_groups = total_num//per_group - if not num_groups: # Account for when it rounds down to 0 - num_groups = 1 + num_groups = max(total_num//per_group, 1) logger.info(f"Creating {num_groups} groups") @@ -111,9 +84,11 @@ async def match(interaction: discord.Interaction, per_group: int): for idx, group in enumerate(groups): mentions = [m.mention for m in group] logger.info(f"Sending group: {list(m.name for m in group)}") - await interaction.channel.send(f"{get_ordinal(idx+1)} group: " + ", ".join(mentions)) + await interaction.channel.send(f"{util.get_ordinal(idx+1)} group: " + ", ".join(mentions)) logger.info(f"Done") await interaction.response.send_message("Done :)", ephemeral=True, silent=True) +# Kick off the bot run cycle +handler = logging.StreamHandler() bot.run(config.TOKEN, log_handler=handler, root_logger=True) diff --git a/util.py b/util.py new file mode 100644 index 0000000..c0db10b --- /dev/null +++ b/util.py @@ -0,0 +1,15 @@ +# Get the ordinal for an int +def get_ordinal(num : int): + if num > 9: + secondToLastDigit = str(num)[-2] + if secondToLastDigit == '1': + return str(num)+'th' + lastDigit = num % 10 + if (lastDigit == 1): + return str(num)+'st' + elif (lastDigit == 2): + return str(num)+'nd' + elif (lastDigit == 3): + return str(num)+'rd' + else: + return str(num)+'th' \ No newline at end of file