From 92be1d1bf0ac24177f53a99ca534b58927c02082 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sat, 17 Aug 2024 00:14:10 +0100 Subject: [PATCH] Add /cancel Using cancel=True on /schedule was a PITA --- README.md | 5 ++-- matchy/cogs/matcher.py | 52 +++++++++++++++++++++++------------------- matchy/state.py | 20 ++++++++-------- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 65df9c3..0690ced 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,9 @@ Matchy supports a bunch of user, `matcher` and bot owner commands. `/` commands | /leave | user | Leaves the matchee list | | /pause | user | Pauses the user for `days: int` days | | /list | user | Lists the current matchees and scheduled matches | -| /match | user | Shares a preview of the matchee groups of size `group_min: int` with the user, offers a button to post the match to `matcher` users | -| /schedule | `matcher` | Shedules a match every week with `group_min: int` users on `weekday: int` day and at `hour: int` hour. Can pass `cancel: True` to stop the schedule | +| /match | user* | Shares a preview of the matchee groups of size `group_min: int` with the user. *Offers a button to post the match to `matcher` users | +| /schedule | `matcher` | Schedules a match every week with `group_min: int` users on `weekday: int` day and at `hour: int` hour. Can pass `cancel: True` to stop the schedule | +| /cancel | `matcher` | Cancels any scheduled matches in this channel | | $sync | bot owner | Syncs bot command data with the discord servers | | $close | bot owner | Closes the bot connection so the bot quits safely | | $grant | bot owner | Grants matcher to a given user (ID) | diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index 43fb840..fb1f0a0 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -89,7 +89,7 @@ class MatcherCog(commands.Cog): for (day, hour, min) in tasks: next_run = util.get_next_datetime(day, hour) date_str = util.datetime_as_discord_time(next_run) - msg += f"\nNext scheduled for {date_str}" + msg += f"\nNext scheduled at {date_str}" msg += f" with {min} members per group" await interaction.response.send_message(msg, ephemeral=True, silent=True) @@ -98,14 +98,12 @@ class MatcherCog(commands.Cog): @commands.guild_only() @app_commands.describe(members_min="Minimum matchees per match (defaults to 3)", weekday="Day of the week to run this (defaults 0, Monday)", - hour="Hour in the day (defaults to 9 utc)", - cancel="Cancel the scheduled match at this time") + hour="Hour in the day (defaults to 9 utc)") async def schedule(self, interaction: discord.Interaction, members_min: int | None = None, weekday: int | None = None, - hour: int | None = None, - cancel: bool = False): + hour: int | None = None): """Schedule a match using the input parameters""" # Set all the defaults @@ -124,30 +122,36 @@ class MatcherCog(commands.Cog): return # Add the scheduled task and save - success = self.state.set_channel_match_task( - channel_id, members_min, weekday, hour, not cancel) + self.state.set_channel_match_task( + channel_id, members_min, weekday, hour) # Let the user know what happened - if not cancel: - logger.info("Scheduled new match task in %s with min %s weekday %s hour %s", - channel_id, members_min, weekday, hour) - next_run = util.get_next_datetime(weekday, hour) - date_str = util.datetime_as_discord_time(next_run) + logger.info("Scheduled new match task in %s with min %s weekday %s hour %s", + channel_id, members_min, weekday, hour) + next_run = util.get_next_datetime(weekday, hour) + date_str = util.datetime_as_discord_time(next_run) - await interaction.response.send_message( - f"Done :) Next run will be on {date_str}\n" - + "Cancel this by re-sending the command with cancel=True", - ephemeral=True, silent=True) + await interaction.response.send_message( + f"Done :) Next run will be at {date_str}", + ephemeral=True, silent=True) - elif success: - logger.info("Removed task in %s on weekday %s hour %s", - channel_id, weekday, hour) - await interaction.response.send_message( - f"Done :) Schedule on day {weekday} and hour {hour} removed!", ephemeral=True, silent=True) + @app_commands.command(description="Cancel all scheduled matches in this channel") + @commands.guild_only() + async def cancel(self, interaction: discord.Interaction): + """Cancel scheduled matches in this channel""" + # Bail if not a matcher + if not self.state.get_user_has_scope(interaction.user.id, AuthScope.MATCHER): + await interaction.response.send_message("You'll need the 'matcher' scope to remove scheduled matches", + ephemeral=True, silent=True) + return - else: - await interaction.response.send_message( - f"No schedule for this channel on day {weekday} and hour {hour} found :(", ephemeral=True, silent=True) + # Add the scheduled task and save + channel_id = str(interaction.channel.id) + self.state.remove_channel_match_tasks(channel_id) + + await interaction.response.send_message( + "Done, all scheduled matches cleared in this channel!", + ephemeral=True, silent=True) @app_commands.command(description="Match up matchees") @commands.guild_only() diff --git a/matchy/state.py b/matchy/state.py index b00507d..2d8c468 100644 --- a/matchy/state.py +++ b/matchy/state.py @@ -338,7 +338,7 @@ class State(): yield (task[_Key.WEEKDAY], task[_Key.HOUR], task[_Key.MEMBERS_MIN]) @safe_write - def set_channel_match_task(self, channel_id: str, members_min: int, weekday: int, hour: int, set: bool) -> bool: + def set_channel_match_task(self, channel_id: str, members_min: int, weekday: int, hour: int): """Set up a match task on a channel""" channel = self._tasks.setdefault(str(channel_id), {}) matches = channel.setdefault(_Key.MATCH_TASKS, []) @@ -348,26 +348,24 @@ class State(): # Specifically check for the combination of weekday and hour if match[_Key.WEEKDAY] == weekday and match[_Key.HOUR] == hour: found = True - if set: - match[_Key.MEMBERS_MIN] = members_min - else: - matches.remove(match) - + match[_Key.MEMBERS_MIN] = members_min # Return true as we've successfully changed the data in place return True # If we didn't find it, add it to the schedule - if not found and set: + if not found: matches.append({ _Key.MEMBERS_MIN: members_min, _Key.WEEKDAY: weekday, _Key.HOUR: hour, }) - return True - - # We did not manage to remove the schedule (or add it? though that should be impossible) - return False + @safe_write + def remove_channel_match_tasks(self, channel_id: str): + """Simply delete the match tasks list""" + channel = self._tasks.setdefault(str(channel_id), {}) + if _Key.MATCH_TASKS in channel: + del channel[_Key.MATCH_TASKS] @property def _users(self) -> dict[str]: