Pull out all strings the bot says to a class
Also implement a randomised wrapper
This commit is contained in:
parent
934c2e24fc
commit
125105469a
6 changed files with 150 additions and 53 deletions
|
@ -12,6 +12,7 @@ import matchy.matching as matching
|
|||
from matchy.state import State, AuthScope
|
||||
import matchy.util as util
|
||||
import matchy.state as state
|
||||
import matchy.cogs.strings as strings
|
||||
|
||||
|
||||
logger = logging.getLogger("cog")
|
||||
|
@ -41,8 +42,8 @@ class MatcherCog(commands.Cog):
|
|||
self.state.set_user_active_in_channel(
|
||||
interaction.user.id, interaction.channel.id)
|
||||
await interaction.response.send_message(
|
||||
f"Roger roger {interaction.user.mention}!\n"
|
||||
+ f"Added you to {interaction.channel.mention}!",
|
||||
strings.acknowledgement(interaction.user.mention) + "\n"
|
||||
+ strings.user_added(interaction.channel.mention),
|
||||
ephemeral=True, silent=True)
|
||||
|
||||
@app_commands.command(description="Leave the matchees for this channel")
|
||||
|
@ -54,7 +55,7 @@ class MatcherCog(commands.Cog):
|
|||
self.state.set_user_active_in_channel(
|
||||
interaction.user.id, interaction.channel.id, False)
|
||||
await interaction.response.send_message(
|
||||
f"No worries {interaction.user.mention}. Come back soon :)", ephemeral=True, silent=True)
|
||||
strings.user_leave(interaction.user.mention), ephemeral=True, silent=True)
|
||||
|
||||
@app_commands.command(description="Pause your matching in this channel for a number of days")
|
||||
@commands.guild_only()
|
||||
|
@ -69,8 +70,8 @@ class MatcherCog(commands.Cog):
|
|||
self.state.set_user_paused_in_channel(
|
||||
interaction.user.id, interaction.channel.id, until)
|
||||
await interaction.response.send_message(
|
||||
f"Sure thing {interaction.user.mention}!\n"
|
||||
+ f"Paused you until {util.datetime_as_discord_time(until)}!",
|
||||
strings.acknowledgement(interaction.user.mention) + "\n"
|
||||
+ strings.paused(until),
|
||||
ephemeral=True, silent=True)
|
||||
|
||||
@app_commands.command(description="List the matchees for this channel")
|
||||
|
@ -86,23 +87,19 @@ class MatcherCog(commands.Cog):
|
|||
|
||||
if matchees:
|
||||
mentions = [m.mention for m in matchees]
|
||||
msg += f"There are {len(matchees)} active matchees:\n"
|
||||
msg += f"{util.format_list(mentions)}\n"
|
||||
msg += strings.active_matchees(mentions) + "\n"
|
||||
|
||||
if paused:
|
||||
mentions = [m.mention for m in paused]
|
||||
msg += f"\nThere are {len(mentions)} paused matchees:\n"
|
||||
msg += f"{util.format_list([m.mention for m in paused])}\n"
|
||||
msg += "\n" + strings.paused_matchees(mentions) + "\n"
|
||||
|
||||
tasks = self.state.get_channel_match_tasks(interaction.channel.id)
|
||||
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"\nA match is scheduled at {date_str}"
|
||||
msg += f" with {min} members per group\n"
|
||||
msg += "\n" + strings.scheduled(next_run, min) + "\n"
|
||||
|
||||
if not msg:
|
||||
msg = "There are no matchees in this channel and no scheduled matches :("
|
||||
msg = strings.no_scheduled()
|
||||
|
||||
await interaction.response.send_message(msg, ephemeral=True, silent=True)
|
||||
|
||||
|
@ -129,7 +126,7 @@ class MatcherCog(commands.Cog):
|
|||
|
||||
# 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 schedule a match",
|
||||
await interaction.response.send_message(strings.need_matcher_scope(),
|
||||
ephemeral=True, silent=True)
|
||||
return
|
||||
|
||||
|
@ -141,10 +138,9 @@ class MatcherCog(commands.Cog):
|
|||
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 at {date_str}",
|
||||
strings.scheduled_success(next_run),
|
||||
ephemeral=True, silent=True)
|
||||
|
||||
@app_commands.command(description="Cancel all scheduled matches in this channel")
|
||||
|
@ -153,7 +149,7 @@ class MatcherCog(commands.Cog):
|
|||
"""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",
|
||||
await interaction.response.send_message(strings.need_matcher_scope(),
|
||||
ephemeral=True, silent=True)
|
||||
return
|
||||
|
||||
|
@ -162,8 +158,7 @@ class MatcherCog(commands.Cog):
|
|||
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)
|
||||
strings.cancelled(), ephemeral=True, silent=True)
|
||||
|
||||
@app_commands.command(description="Match up matchees")
|
||||
@commands.guild_only()
|
||||
|
@ -185,24 +180,23 @@ class MatcherCog(commands.Cog):
|
|||
|
||||
# Let the user know when there's nobody to match
|
||||
if not groups:
|
||||
await interaction.response.send_message("Nobody to match up :(", ephemeral=True, silent=True)
|
||||
await interaction.response.send_message(strings.nobody_to_match(), ephemeral=True, silent=True)
|
||||
return
|
||||
|
||||
# Post about all the groups with a button to send to the channel
|
||||
groups_list = '\n'.join(
|
||||
", ".join([m.mention for m in g]) for g in groups)
|
||||
msg = f"Roger! I've generated example groups for ya:\n\n{groups_list}"
|
||||
msg = strings.generated_groups(groups_list)
|
||||
view = discord.utils.MISSING
|
||||
|
||||
if self.state.get_user_has_scope(interaction.user.id, AuthScope.MATCHER):
|
||||
# Otherwise set up the button
|
||||
msg += "\n\nClick the button to match up groups and send them to the channel.\n"
|
||||
msg += "\n\n" + strings.click_to_match() + "\n"
|
||||
view = discord.ui.View(timeout=None)
|
||||
view.add_item(DynamicGroupButton(members_min))
|
||||
else:
|
||||
# Let a non-matcher know why they don't have the button
|
||||
msg += f"\n\nYou'll need the {AuthScope.MATCHER}"
|
||||
msg += " scope to post this to the channel, sorry!"
|
||||
msg += "\n\n" + strings.need_matcher_to_post()
|
||||
|
||||
await interaction.response.send_message(msg, ephemeral=True, silent=True, view=view)
|
||||
|
||||
|
@ -215,13 +209,12 @@ class MatcherCog(commands.Cog):
|
|||
for (channel, min) in self.state.get_active_match_tasks():
|
||||
logger.info("Scheduled match task triggered in %s", channel)
|
||||
msg_channel = self.bot.get_channel(int(channel))
|
||||
await matching.match_groups_in_channel(self.state, msg_channel, min)
|
||||
await match_groups_in_channel(self.state, msg_channel, min)
|
||||
|
||||
for (channel, _) in self.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("Arf arf! just a reminder I'll be doin a matcherino in here in T-24hrs!"
|
||||
+ "\nUse /join if you haven't already, or /pause if you want to skip a week :)")
|
||||
await msg_channel.send(strings.reminder())
|
||||
|
||||
|
||||
# Increment when adjusting the custom_id so we don't confuse old users
|
||||
|
@ -260,7 +253,30 @@ class DynamicGroupButton(discord.ui.DynamicItem[discord.ui.Button],
|
|||
intrctn.guild.name, intrctn.channel.name)
|
||||
|
||||
# Let the user know we've recieved the message
|
||||
await intrctn.response.send_message(content="Matchy is matching matchees...", ephemeral=True)
|
||||
await intrctn.response.send_message(content=strings.matching(), ephemeral=True)
|
||||
|
||||
# Perform the match
|
||||
await matching.match_groups_in_channel(self.state, intrctn.channel, self.min)
|
||||
await match_groups_in_channel(self.state, intrctn.channel, self.min)
|
||||
|
||||
|
||||
async def match_groups_in_channel(state: State, channel: discord.channel, min: int):
|
||||
"""Match up the groups in a given channel"""
|
||||
groups = matching.active_members_to_groups(state, channel, min)
|
||||
|
||||
# Send the groups
|
||||
for group in groups:
|
||||
message = await channel.send(
|
||||
f"Matched up {util.format_list([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(
|
||||
name=util.format_list([m.display_name for m in group]),
|
||||
message=message,
|
||||
reason="Creating a matching thread")
|
||||
|
||||
# Close off with a message
|
||||
await channel.send(strings.matching_done())
|
||||
# Save the groups to the history
|
||||
state.log_groups(groups)
|
||||
|
||||
logger.info("Done! Matched into %s groups.", len(groups))
|
||||
|
|
|
@ -52,4 +52,4 @@ class OwnerCog(commands.Cog):
|
|||
logger.info("Granting user %s matcher scope", user)
|
||||
await ctx.reply("Done!", ephemeral=True)
|
||||
else:
|
||||
await ctx.reply("Likely not a user...", ephemeral=True)
|
||||
await ctx.reply(f"{user} is not a user?", ephemeral=True)
|
||||
|
|
83
matchy/cogs/strings.py
Normal file
83
matchy/cogs/strings.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
"""
|
||||
All the possible strings for things that matchy can say
|
||||
Some can be selected randomly to give the bot some flavor
|
||||
"""
|
||||
from matchy.util import randomised, datetime_as_discord_time, format_list
|
||||
from matchy.state import AuthScope
|
||||
|
||||
|
||||
# Acknowledge something
|
||||
@randomised
|
||||
def acknowledgement(m): return [
|
||||
f"Roger roger {m}!",
|
||||
f"Sure thing {m}!"
|
||||
]
|
||||
|
||||
|
||||
def user_added(c):
|
||||
return f"Added you to {c}!"
|
||||
|
||||
|
||||
def user_leave(m):
|
||||
return f"No worries {m}. Come back soon :)"
|
||||
|
||||
|
||||
def paused(t):
|
||||
return f"Paused you until {datetime_as_discord_time(t)}!"
|
||||
|
||||
|
||||
def active_matchees(ms):
|
||||
return f"There are {len(ms)} active matchees:\n{format_list(ms)}"
|
||||
|
||||
|
||||
def paused_matchees(ms):
|
||||
return f"There are {len(ms)} paused matchees:\n{format_list(ms)}"
|
||||
|
||||
|
||||
def scheduled(next, n):
|
||||
return f"A match is scheduled at {datetime_as_discord_time(next)} with {n} members per group\n"
|
||||
|
||||
|
||||
def no_scheduled():
|
||||
return "There are no matchees in this channel and no scheduled matches :("
|
||||
|
||||
|
||||
def need_matcher_scope():
|
||||
return "You'll need the 'matcher' scope to do this"
|
||||
|
||||
|
||||
def scheduled_success(d):
|
||||
return f"Done :) Next run will be at {datetime_as_discord_time(d)}"
|
||||
|
||||
|
||||
def cancelled():
|
||||
return "Done, all scheduled matches cleared in this channel!"
|
||||
|
||||
|
||||
def nobody_to_match():
|
||||
return "Nobody to match up :("
|
||||
|
||||
|
||||
def generated_groups(g):
|
||||
return "Roger! I've generated example groups for ya:\n\n{g}"
|
||||
|
||||
|
||||
def click_to_match():
|
||||
return "Click the button to match up groups and send them to the channel."
|
||||
|
||||
|
||||
def need_matcher_to_post():
|
||||
return f"You'll need the {AuthScope.MATCHER} scope to post this to the channel, sorry!"
|
||||
|
||||
|
||||
def reminder():
|
||||
return """Arf arf! just a reminder I'll be doin a matcherino in here in T-24hrs!
|
||||
Use /join if you haven't already, or /pause if you want to skip a week :)"""
|
||||
|
||||
|
||||
def matching():
|
||||
return "Matchy is matching matchees..."
|
||||
|
||||
|
||||
def matching_done():
|
||||
return "That's all folks, happy matching and remember - DFTBA!"
|
|
@ -179,29 +179,6 @@ def members_to_groups(matchees: list[Member],
|
|||
assert False
|
||||
|
||||
|
||||
async def match_groups_in_channel(state: State, channel: discord.channel, min: int):
|
||||
"""Match up the groups in a given channel"""
|
||||
groups = active_members_to_groups(state, channel, min)
|
||||
|
||||
# Send the groups
|
||||
for group in groups:
|
||||
message = await channel.send(
|
||||
f"Matched up {util.format_list([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(
|
||||
name=util.format_list([m.display_name for m in group]),
|
||||
message=message,
|
||||
reason="Creating a matching thread")
|
||||
|
||||
# Close off with a message
|
||||
await channel.send("That's all folks, happy matching and remember - DFTBA!")
|
||||
# Save the groups to the history
|
||||
state.log_groups(groups)
|
||||
|
||||
logger.info("Done! Matched into %s groups.", len(groups))
|
||||
|
||||
|
||||
def get_matchees_in_channel(state: State, channel: discord.channel):
|
||||
"""Fetches the matchees in a channel"""
|
||||
# Reactivate any unpaused users
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from datetime import datetime, timedelta
|
||||
from functools import reduce
|
||||
import random
|
||||
|
||||
|
||||
def get_day_with_suffix(day):
|
||||
|
@ -59,3 +60,11 @@ def set_nested_value(d, *keys, value=None):
|
|||
d[leaf] = value
|
||||
elif leaf in d:
|
||||
del d[leaf]
|
||||
|
||||
|
||||
def randomised(func):
|
||||
"Randomise which in a list we actually return"
|
||||
def wrapper(*args, **kwargs):
|
||||
vals = func(*args, **kwargs)
|
||||
return random.choice(vals) if isinstance(vals, list) else vals
|
||||
return wrapper
|
||||
|
|
|
@ -38,3 +38,15 @@ def test_set_nested_dict_value():
|
|||
}
|
||||
util.set_nested_value(d, "x", "y", "z", "val", value=52)
|
||||
assert 52 == util.get_nested_value(d, "x", "y", "z", "val")
|
||||
|
||||
|
||||
def test_randomized():
|
||||
|
||||
def string():
|
||||
return "foo"
|
||||
|
||||
def list():
|
||||
return ["foo", "bar"]
|
||||
|
||||
assert util.randomised(string)() == "foo"
|
||||
assert util.randomised(list)() in list()
|
||||
|
|
Loading…
Add table
Reference in a new issue