From b86aaf70164023615c3426dadde89ab6f1783ccf Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 11:57:44 +0100 Subject: [PATCH 01/18] Add cadence values to the matchy tasks cadence - Run this task every "x" weeks cadence - Unix seconds timestamp for the start of this cadence --- matchy/state.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/matchy/state.py b/matchy/state.py index d498af6..9fd16bb 100644 --- a/matchy/state.py +++ b/matchy/state.py @@ -16,7 +16,7 @@ logger = logging.getLogger("state") logger.setLevel(logging.INFO) # Warning: Changing any of the below needs proper thought to ensure backwards compatibility -_VERSION = 4 +_VERSION = 5 def _migrate_to_v1(d: dict): @@ -64,12 +64,24 @@ def _migrate_to_v4(d: dict): del d[_Key._HISTORY] +def _migrate_to_v5(d: dict): + """v5 added weekly cadence""" + tasks = d.get(_Key.TASKS, {}) + for tasks in tasks.values(): + match_tasks = tasks.get(_Key.MATCH_TASKS, []) + for match in match_tasks: + # All previous matches were every week starting from now + match[_Key.CADENCE] = 1 + match[_Key.CADENCE_START] = int(datetime.now().timestamp()) + + # Set of migration functions to apply _MIGRATIONS = [ _migrate_to_v1, _migrate_to_v2, _migrate_to_v3, _migrate_to_v4, + _migrate_to_v5 ] @@ -94,6 +106,8 @@ class _Key(str): MEMBERS_MIN = "members_min" WEEKDAY = "weekdays" HOUR = "hours" + CADENCE = "cadence" + CADENCE_START = "CADENCE_START" # Unused _MATCHEES = "matchees" @@ -139,6 +153,8 @@ _SCHEMA = Schema( _Key.MEMBERS_MIN: Use(int), _Key.WEEKDAY: Use(int), _Key.HOUR: Use(int), + _Key.CADENCE: Use(int), + _Key.CADENCE_START: Use(int), } ] } From e9cccefacbc1cd2d4c8630b616a6c5aa1e371198 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 12:09:59 +0100 Subject: [PATCH 02/18] Add cadence argument to the /schedule command This allows setting the cadence, or changing it. When changing the initial start time will be reset --- matchy/cogs/matcher.py | 11 +++++++---- matchy/state.py | 14 ++++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index 394fb79..10ed62b 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -110,7 +110,8 @@ class MatcherCog(commands.Cog): interaction: discord.Interaction, members_min: int | None = None, weekday: int | None = None, - hour: int | None = None): + hour: int | None = None, + cadence: int | None = None): """Schedule a match using the input parameters""" # Set all the defaults @@ -120,6 +121,8 @@ class MatcherCog(commands.Cog): weekday = 0 if hour is None: hour = 9 + if cadence is None: + cadence = 1 channel_id = str(interaction.channel.id) # Bail if not a matcher @@ -130,11 +133,11 @@ class MatcherCog(commands.Cog): # Add the scheduled task and save state.State.set_channel_match_task( - channel_id, members_min, weekday, hour) + channel_id, members_min, weekday, hour, cadence) # Let the user know what happened - logger.info("Scheduled new match task in %s with min %s weekday %s hour %s", - channel_id, members_min, weekday, hour) + logger.info("Scheduled new match task in %s with min %s weekday %s hour %s and cadence %s", + channel_id, members_min, weekday, hour, cadence) next_run = util.get_next_datetime(weekday, hour) view = discord.ui.View(timeout=None) diff --git a/matchy/state.py b/matchy/state.py index 9fd16bb..66cb1a2 100644 --- a/matchy/state.py +++ b/matchy/state.py @@ -72,7 +72,7 @@ def _migrate_to_v5(d: dict): for match in match_tasks: # All previous matches were every week starting from now match[_Key.CADENCE] = 1 - match[_Key.CADENCE_START] = int(datetime.now().timestamp()) + match[_Key.CADENCE_START] = datetime_to_ts(datetime.now()) # Set of migration functions to apply @@ -107,7 +107,7 @@ class _Key(str): WEEKDAY = "weekdays" HOUR = "hours" CADENCE = "cadence" - CADENCE_START = "CADENCE_START" + CADENCE_START = "cadence_start" # Unused _MATCHEES = "matchees" @@ -154,7 +154,7 @@ _SCHEMA = Schema( _Key.WEEKDAY: Use(int), _Key.HOUR: Use(int), _Key.CADENCE: Use(int), - _Key.CADENCE_START: Use(int), + _Key.CADENCE_START: Use(str), } ] } @@ -357,7 +357,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): + def set_channel_match_task(self, channel_id: str, members_min: int, weekday: int, hour: int, cadence: int): """Set up a match task on a channel""" channel = self._tasks.setdefault(str(channel_id), {}) matches = channel.setdefault(_Key.MATCH_TASKS, []) @@ -368,6 +368,10 @@ class _State(): if match[_Key.WEEKDAY] == weekday and match[_Key.HOUR] == hour: found = True match[_Key.MEMBERS_MIN] = members_min + # If the cadence has changed, update it and reset the start + if cadence != match[_Key.CADENCE]: + match[_Key.CADENCE] = cadence + match[_Key.CADENCE_START] = datetime_to_ts(datetime.now()) # Return true as we've successfully changed the data in place return True @@ -377,6 +381,8 @@ class _State(): _Key.MEMBERS_MIN: members_min, _Key.WEEKDAY: weekday, _Key.HOUR: hour, + _Key.CADENCE: cadence, + _Key.CADENCE_START: datetime_to_ts(datetime.now()) }) @safe_write From d83f933f1d262d11169cc123416870675574104b Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 12:20:55 +0100 Subject: [PATCH 03/18] Only yield matching tasks if the weekly cadence has been hit --- matchy/state.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/matchy/state.py b/matchy/state.py index 66cb1a2..56fbb1d 100644 --- a/matchy/state.py +++ b/matchy/state.py @@ -340,7 +340,10 @@ class _State(): for channel, tasks in self._tasks.items(): for match in tasks.get(_Key.MATCH_TASKS, []): - if match[_Key.WEEKDAY] == weekday and match[_Key.HOUR] == hour: + # Take into account the weekly cadence + start = ts_to_datetime(match[_Key.CADENCE_START]) + weeks = int((time - start).days / 7) + if match[_Key.WEEKDAY] == weekday and match[_Key.HOUR] == hour and weeks % match[_Key.CADENCE] == 0: yield (channel, match[_Key.MEMBERS_MIN]) def get_channel_match_tasks(self, channel_id: str) -> Generator[int, int, int]: From 93590d14b7ac03e06b39910ebb32d56f629d8d9d Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 12:22:54 +0100 Subject: [PATCH 04/18] Ensure a cadence of 0 does not get used The user surely meant 1 --- matchy/cogs/matcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index 10ed62b..9734a2c 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -121,7 +121,7 @@ class MatcherCog(commands.Cog): weekday = 0 if hour is None: hour = 9 - if cadence is None: + if cadence is None or cadence == 0: cadence = 1 channel_id = str(interaction.channel.id) From 2ad7ed2ff2858ec839eb70ea2a5c5e70f3d9b114 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 14:20:34 +0100 Subject: [PATCH 05/18] Fix not returning values from safe_write functions --- matchy/state.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matchy/state.py b/matchy/state.py index 56fbb1d..fe24411 100644 --- a/matchy/state.py +++ b/matchy/state.py @@ -232,11 +232,12 @@ class _State(): @wraps(func) def inner(self, *args, **kwargs): tmp = _State(self._dict, self._file) - func(tmp, *args, **kwargs) + ret = func(tmp, *args, **kwargs) _SCHEMA.validate(tmp._dict) if tmp._file: _save(tmp._file, tmp._dict) self._dict = tmp._dict + return ret return inner From 7491a4d2f855bcb6adc6ee4b4abab76a05625769 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 14:20:47 +0100 Subject: [PATCH 06/18] Account for the cadence in all the messages --- matchy/cogs/matcher.py | 16 +++++++------- matchy/cogs/strings.py | 10 ++++----- matchy/state.py | 45 +++++++++++++++++++++---------------- matchy/util.py | 28 ++++++++++++++++------- tests/util_test.py | 50 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 40 deletions(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index 9734a2c..d8f9d39 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -92,8 +92,8 @@ class MatcherCog(commands.Cog): msg += "\n" + strings.paused_matchees(mentions) + "\n" tasks = state.State.get_channel_match_tasks(interaction.channel.id) - for (day, hour, min) in tasks: - next_run = util.get_next_datetime(day, hour) + for (day, hour, min, cadence, cadence_start) in tasks: + next_run = util.get_next_datetime_with_cadence(day, hour, datetime.now(), cadence, cadence_start) msg += "\n" + strings.scheduled(next_run, min) if not msg: @@ -132,19 +132,19 @@ class MatcherCog(commands.Cog): return # Add the scheduled task and save - state.State.set_channel_match_task( - channel_id, members_min, weekday, hour, cadence) + (_, _, _, _, cadence_start) = state.State.set_channel_match_task( + channel_id, members_min, weekday, hour, cadence) # Let the user know what happened logger.info("Scheduled new match task in %s with min %s weekday %s hour %s and cadence %s", channel_id, members_min, weekday, hour, cadence) - next_run = util.get_next_datetime(weekday, hour) + next_run = util.get_next_datetime_with_cadence(weekday, hour, datetime.now(), cadence, cadence_start) view = discord.ui.View(timeout=None) view.add_item(ScheduleButton()) await interaction.response.send_message( - strings.scheduled_success(next_run), + strings.scheduled_success(next_run, cadence), ephemeral=True, silent=True, view=view) @app_commands.command(description="Cancel all scheduled matches in this channel") @@ -307,8 +307,8 @@ class ScheduleButton(discord.ui.Button): msg += strings.scheduled_matches() if tasks: - for (day, hour, min) in tasks: - next_run = util.get_next_datetime(day, hour) + for (day, hour, min, cadence, cadence_start) in tasks: + next_run = util.get_next_datetime(day, hour, datetime.now(), cadence, cadence_start) msg += strings.scheduled(next_run, min) await interaction.channel.send(msg) diff --git a/matchy/cogs/strings.py b/matchy/cogs/strings.py index 297e51b..a617194 100644 --- a/matchy/cogs/strings.py +++ b/matchy/cogs/strings.py @@ -85,11 +85,11 @@ def need_matcher_scope(): return [ @randomised -def scheduled_success(d): return [ - f"Done :) Next run will be at {datetime_as_discord_time(d)}", - f"Woohoo! Scheduled for {datetime_as_discord_time(d)}", - f"Yessir, will do a matcho at {datetime_as_discord_time(d)}", - f"Arf Arf! Bork bork bark {datetime_as_discord_time(d)}", +def scheduled_success(d, cadence): return [ + f"Done :) Next run will be at {datetime_as_discord_time(d)} and every {cadence} week(s) after", + f"Woohoo! Scheduled for {datetime_as_discord_time(d)} plus each {cadence} week(s) after", + f"Yessir, will do a matcho every {cadence} week(s), first one is {datetime_as_discord_time(d)}", + f"Arf Arf! Bork bork bark {datetime_as_discord_time(d)} berk {cadence} week(s) arf", ] diff --git a/matchy/state.py b/matchy/state.py index fe24411..5af6096 100644 --- a/matchy/state.py +++ b/matchy/state.py @@ -358,7 +358,7 @@ class _State(): ) for tasks in all_tasks: for task in tasks: - yield (task[_Key.WEEKDAY], task[_Key.HOUR], task[_Key.MEMBERS_MIN]) + yield _task_to_tuple(task) @safe_write def set_channel_match_task(self, channel_id: str, members_min: int, weekday: int, hour: int, cadence: int): @@ -366,28 +366,27 @@ class _State(): channel = self._tasks.setdefault(str(channel_id), {}) matches = channel.setdefault(_Key.MATCH_TASKS, []) - found = False - for match in matches: + for match_task in matches: # Specifically check for the combination of weekday and hour - if match[_Key.WEEKDAY] == weekday and match[_Key.HOUR] == hour: - found = True - match[_Key.MEMBERS_MIN] = members_min + if match_task[_Key.WEEKDAY] == weekday and match_task[_Key.HOUR] == hour: + match_task[_Key.MEMBERS_MIN] = members_min # If the cadence has changed, update it and reset the start - if cadence != match[_Key.CADENCE]: - match[_Key.CADENCE] = cadence - match[_Key.CADENCE_START] = datetime_to_ts(datetime.now()) - # Return true as we've successfully changed the data in place - return True + if cadence != match_task[_Key.CADENCE]: + match_task[_Key.CADENCE] = cadence + match_task[_Key.CADENCE_START] = datetime_to_ts(datetime.now()) + # Return as we've successfully changed the data in place + return _task_to_tuple(match_task) # If we didn't find it, add it to the schedule - if not found: - matches.append({ - _Key.MEMBERS_MIN: members_min, - _Key.WEEKDAY: weekday, - _Key.HOUR: hour, - _Key.CADENCE: cadence, - _Key.CADENCE_START: datetime_to_ts(datetime.now()) - }) + match_task = { + _Key.MEMBERS_MIN: members_min, + _Key.WEEKDAY: weekday, + _Key.HOUR: hour, + _Key.CADENCE: cadence, + _Key.CADENCE_START: datetime_to_ts(datetime.now()) + } + matches.append(match_task) + return _task_to_tuple(match_task) @safe_write def remove_channel_match_tasks(self, channel_id: str): @@ -405,6 +404,14 @@ class _State(): return self._dict[_Key.TASKS] +def _task_to_tuple(task): + return (task[_Key.WEEKDAY], + task[_Key.HOUR], + task[_Key.MEMBERS_MIN], + task[_Key.CADENCE], + ts_to_datetime(task[_Key.CADENCE_START])) + + def load_from_file(file: str) -> _State: """ Load the state from a files diff --git a/matchy/util.py b/matchy/util.py index 95274e3..b8fb71e 100644 --- a/matchy/util.py +++ b/matchy/util.py @@ -18,20 +18,32 @@ def format_list(list: list) -> str: return list[0] if list else '' -def get_next_datetime(weekday, hour) -> datetime: +def get_next_datetime(weekday: int, hour: int, start: datetime) -> datetime: """Get the next datetime for the given weekday and hour""" - now = datetime.now() - days_until_next_week = (weekday - now.weekday() + 7) % 7 + + days_until_next_week_run = (weekday - start.weekday() + 7) % 7 # Account for when we're already beyond the time now - if days_until_next_week == 0 and now.hour >= hour: - days_until_next_week = 7 + if days_until_next_week_run == 0 and start.hour >= hour: + days_until_next_week_run = 7 # Calculate the next datetime - next_date = now + timedelta(days=days_until_next_week) - next_date = next_date.replace(hour=hour, minute=0, second=0, microsecond=0) + next_date = start + timedelta(days=days_until_next_week_run) - return next_date + return next_date.replace(hour=hour, minute=0, second=0, microsecond=0) + + +def get_next_datetime_with_cadence(weekday: int, hour: int, start: datetime, cadence: int, cadence_start: datetime): + """Get the next datetime for given weekday, hour and cadence values""" + + # Get the first run based on the cadence + next_time = get_next_datetime(weekday, hour, cadence_start) + + # Walk forwards until we get the actual time + while next_time < start: + next_time += timedelta(weeks=cadence) + + return next_time def datetime_as_discord_time(time: datetime) -> str: diff --git a/tests/util_test.py b/tests/util_test.py index 9bda465..b2971ed 100644 --- a/tests/util_test.py +++ b/tests/util_test.py @@ -1,4 +1,6 @@ import matchy.util as util +from datetime import datetime, timedelta +import pytest def test_iterate_all_shifts(): @@ -50,3 +52,51 @@ def test_randomized(): assert util.randomised(string)() == "foo" assert util.randomised(list)() in list() + + +@pytest.mark.parametrize( + "weekday, hour, start, expected", + [ + pytest.param( + 0, 0, datetime(2024, 9, 22), + datetime(2024, 9, 23), id="tomorrow" + ), + pytest.param( + 4, 16, datetime(2024, 9, 22), + datetime(2024, 9, 27, 16), id="complicated" + ), + ], +) +def test_get_next_datetime(weekday, hour, start, expected): + value = util.get_next_datetime(weekday, hour, start) + assert value == expected + + +@pytest.mark.parametrize( + "weekday, hour, start, cadence, cadence_start, expected", + [ + pytest.param( + 0, 0, datetime(2024, 9, 22), + 1, datetime(2024, 9, 22), + datetime(2024, 9, 23), id="tomorrow" + ), + pytest.param( + 0, 0, datetime(2024, 9, 22), + 2, datetime(2024, 9, 22), + datetime(2024, 9, 23), id="every-other" + ), + pytest.param( + 0, 0, datetime(2024, 9, 22), + 2, datetime(2024, 9, 14), + datetime(2024, 9, 30), id="every-other-before" + ), + pytest.param( + 0, 0, datetime(2024, 9, 22), + 3, datetime(2024, 9, 14), + datetime(2024, 10, 7), id="every-third" + ), + ], +) +def test_get_next_datetime_with_cadence(weekday, hour, start, expected, cadence, cadence_start): + value = util.get_next_datetime_with_cadence(weekday, hour, start, cadence, cadence_start) + assert value == expected From 39bb8dbf190cf52d653931cb553b9a0277fa5ecb Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 14:23:59 +0100 Subject: [PATCH 07/18] Remove unused timedelta import --- tests/util_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util_test.py b/tests/util_test.py index b2971ed..60f6806 100644 --- a/tests/util_test.py +++ b/tests/util_test.py @@ -1,5 +1,5 @@ import matchy.util as util -from datetime import datetime, timedelta +from datetime import datetime import pytest From 6d6f9d25f90f8b373c813c209930ffe8a48b5949 Mon Sep 17 00:00:00 2001 From: mdiluz Date: Sun, 22 Sep 2024 14:30:27 +0100 Subject: [PATCH 08/18] Update the readme with the new cadence value --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e582c97..fc7008d 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Matchy supports a bunch of user, `matcher` and bot owner commands. `/` commands | /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` | 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 | +| /schedule | `matcher` | Schedules a match every week with `group_min: int` users on `weekday: int` and at `hour: int`, on a weekly `cadence: int`.
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 | From e3d96faaa7c0b8751d073bb5386e327270292070 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 14:38:09 +0100 Subject: [PATCH 09/18] Call the write next datetime function when sending to the channel --- matchy/cogs/matcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index d8f9d39..aa911c4 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -308,7 +308,7 @@ class ScheduleButton(discord.ui.Button): if tasks: for (day, hour, min, cadence, cadence_start) in tasks: - next_run = util.get_next_datetime(day, hour, datetime.now(), cadence, cadence_start) + next_run = util.get_next_datetime_with_cadence(day, hour, datetime.now(), cadence, cadence_start) msg += strings.scheduled(next_run, min) await interaction.channel.send(msg) From 367d12578ce29049ec33a05d1fde28e3eadadef2 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 15:14:19 +0100 Subject: [PATCH 10/18] Add a thread message with suggestions --- matchy/cogs/matcher.py | 5 ++++- matchy/cogs/strings.py | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index aa911c4..f5ff5f1 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -272,11 +272,14 @@ async def match_groups_in_channel(channel: discord.channel, min: int): strings.matched_up([m.mention for m in group])) # Set up a thread for this match if the bot has permissions to do so if channel.permissions_for(channel.guild.me).create_public_threads: - await channel.create_thread( + thread = await channel.create_thread( name=strings.thread_title([m.display_name for m in group]), message=message, reason="Creating a matching thread") + # Send a message with a suggested time to the channel + await thread.send(f"{strings.thread_message()} {strings.time_suggestion()}") + # Close off with a message await channel.send(strings.matching_done()) # Save the groups to the history diff --git a/matchy/cogs/strings.py b/matchy/cogs/strings.py index a617194..042322a 100644 --- a/matchy/cogs/strings.py +++ b/matchy/cogs/strings.py @@ -174,6 +174,33 @@ def matched_up(ms): return [ ] +@randomised +def thread_message(): return [ + "Hey peeps :)", + "How is everyone?", + "Bork!", + "Hey kiddos :)", + "Ahoy!", + "Great to see y'all here.", + "Icebreaker! What's your favourite pokemon?", + "I'm hungry, would a lasagna count as a sandwich?", + "What's your favourite keyboard key?", + "I'm confused thinking... Is a train just a sideways elevator?", + "Humans are weird, why do you have moustaches above your eyes?" +] + + +@randomised +def time_suggestion(): return [ + "Can I suggest a quick call on Wednesday?", + "Remember to organise a chat if you're up for it!", + "How about throwing something in the calendar for Friday?", + "Would 10am on Thursday work for people?", + "How about a call this afternoon?", + "Would a chat the start of a weekday work?" +] + + @randomised def thread_title(ms): return [ f"{format_list(ms)}", From 455f202364036be03b104955cde479282e991f31 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 15:47:28 +0100 Subject: [PATCH 11/18] Add placeholder code for getting previous runs --- matchy/cogs/matcher.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index aa911c4..4a4e15d 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -210,15 +210,23 @@ class MatcherCog(commands.Cog): async def run_hourly_tasks(self): """Run any hourly tasks we have""" + # Send a reminder for anything that will be active in 1 day + for (channel, _) in state.State.get_active_match_tasks(datetime.now() + timedelta(days=1)): + logger.info("Reminding about scheduled task in %s", channel) + msg_channel = self.bot.get_channel(int(channel)) + await msg_channel.send(strings.reminder()) + + # Match groups for anything active right now for (channel, min) in state.State.get_active_match_tasks(): logger.info("Scheduled match task triggered in %s", channel) msg_channel = self.bot.get_channel(int(channel)) await match_groups_in_channel(msg_channel, min) - for (channel, _) in state.State.get_active_match_tasks(datetime.now() + timedelta(days=1)): - logger.info("Reminding about scheduled task in %s", channel) + # Send a reminder to threads for a match that happened two days ago + for (channel, min) in state.State.get_active_match_tasks(datetime.now() - timedelta(days=2)): + logger.info("Sending reminders to threads in %s", channel) msg_channel = self.bot.get_channel(int(channel)) - await msg_channel.send(strings.reminder()) + # TODO: Send a reminder per thread # Increment when adjusting the custom_id so we don't confuse old users From f7898892e6f59a183465db41956948333923119d Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sun, 22 Sep 2024 16:30:49 +0100 Subject: [PATCH 12/18] Send a reminder to innactive threads This sends a reminder message to any thread with 1 or less messages This picks up only active threads too --- matchy/cogs/matcher.py | 9 +++++++-- matchy/cogs/strings.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/matchy/cogs/matcher.py b/matchy/cogs/matcher.py index 4a4e15d..f62ee6a 100644 --- a/matchy/cogs/matcher.py +++ b/matchy/cogs/matcher.py @@ -223,10 +223,15 @@ class MatcherCog(commands.Cog): await match_groups_in_channel(msg_channel, min) # Send a reminder to threads for a match that happened two days ago - for (channel, min) in state.State.get_active_match_tasks(datetime.now() - timedelta(days=2)): + for (channel, _) in state.State.get_active_match_tasks(datetime.now() - timedelta(days=2)): logger.info("Sending reminders to threads in %s", channel) msg_channel = self.bot.get_channel(int(channel)) - # TODO: Send a reminder per thread + # Find any threads that need + for thread in msg_channel.threads: + # Only regard threads the bot created + # And that have no additional messages + if thread.owner.id == self.bot.user.id and thread.message_count <= 1: + await thread.send(strings.thread_reminder()) # Increment when adjusting the custom_id so we don't confuse old users diff --git a/matchy/cogs/strings.py b/matchy/cogs/strings.py index a617194..c31ae06 100644 --- a/matchy/cogs/strings.py +++ b/matchy/cogs/strings.py @@ -145,6 +145,16 @@ Make sure you're /pause'd if you need to be, or /join in ASAP!""", ] +@randomised +def thread_reminder(): return [ + "Hey friends, just checking in! No worries if you're too busy this week", + "Bork bork, quick reminder in case y'all forgot!", + "Hey matchees, how's your week going?", + "Hey everyone, don't forget to check in with eachother!", + "Quick friendly nudge, how're you all doing?", +] + + @randomised def matching(): return [ "Matchy is matching matchees...", From 10e3dd3b36579665f07846e708ab2f00cacfa0d0 Mon Sep 17 00:00:00 2001 From: mdiluz Date: Tue, 24 Sep 2024 11:31:37 +0100 Subject: [PATCH 13/18] Add more random suggestion options --- matchy/cogs/strings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/matchy/cogs/strings.py b/matchy/cogs/strings.py index 042322a..80da0cb 100644 --- a/matchy/cogs/strings.py +++ b/matchy/cogs/strings.py @@ -197,7 +197,10 @@ def time_suggestion(): return [ "How about throwing something in the calendar for Friday?", "Would 10am on Thursday work for people?", "How about a call this afternoon?", - "Would a chat the start of a weekday work?" + "Would a chat the start of a weekday work?", + "How's about organising a quick call sometime this week?", + "When's everyone available for a short hangout?", + "It's best to pick a time to drop in a call or meet up, if everyone is up for it!", ] From 77d533fbcb340ccccc4d9c7a346fec847a68a8bc Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 9 Oct 2024 12:00:08 +0000 Subject: [PATCH 14/18] Update dependency coverage to v7.6.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fdcdbe6..e920edd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.6.1 +coverage==7.6.2 discord.py==2.4.0 dpytest==0.7.0 flake8==7.1.1 From fb4647c4e05d8820230a27e66cd564f1ac3cb655 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 13 Oct 2024 23:00:08 +0000 Subject: [PATCH 15/18] Update dependency coverage to v7.6.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e920edd..de53231 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.6.2 +coverage==7.6.3 discord.py==2.4.0 dpytest==0.7.0 flake8==7.1.1 From e8f5350b8e497c08507c7746e09a9d0552e0c5bd Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Dec 2024 17:00:08 +0000 Subject: [PATCH 16/18] Update dependency coverage to v7.6.10 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index de53231..9d49ee1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -coverage==7.6.3 +coverage==7.6.10 discord.py==2.4.0 dpytest==0.7.0 flake8==7.1.1 From 84f18bceecd9a21c7184e99f27316f38553ccdc8 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 2 Jan 2025 06:00:08 +0000 Subject: [PATCH 17/18] Update dependency pytest-asyncio to v0.25.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index de53231..8ade5c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ discord.py==2.4.0 dpytest==0.7.0 flake8==7.1.1 pytest==8.3.3 -pytest-asyncio==0.24.0 +pytest-asyncio==0.25.1 pytest-cov==5.0.0 schema==0.7.7 \ No newline at end of file From c8bfa837aad4dd59747c0f3fee9cfdbe128f91f1 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 8 Jan 2025 07:00:08 +0000 Subject: [PATCH 18/18] Update dependency pytest-asyncio to v0.25.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fa2e8d1..99d752f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ discord.py==2.4.0 dpytest==0.7.0 flake8==7.1.1 pytest==8.3.3 -pytest-asyncio==0.25.1 +pytest-asyncio==0.25.2 pytest-cov==5.0.0 schema==0.7.7 \ No newline at end of file