diff --git a/bot/cogs/logging/message_log.py b/bot/cogs/logging/message_log.py index b80529b..86d01a3 100644 --- a/bot/cogs/logging/message_log.py +++ b/bot/cogs/logging/message_log.py @@ -75,11 +75,12 @@ async def on_message_edit(self, before: Message, after: Message) -> None: """ # Add this message to set of ignored messages for raw events, these trigger even if # the message was cached, and to prevent double logging, we need to ignore them - self._handled_cached.add((after.guild.id, after.id)) if self.is_ignored(message=after, event=Event.message_edit): return + self._handled_cached.add((after.guild.id, after.id)) + response = ( f"**Author:** {after.author.mention}\n" f"**Channel:** {after.channel.mention}" diff --git a/bot/cogs/moderation/slowmode.py b/bot/cogs/moderation/slowmode.py index 0cc550c..7820b32 100644 --- a/bot/cogs/moderation/slowmode.py +++ b/bot/cogs/moderation/slowmode.py @@ -25,7 +25,7 @@ async def slow_mode(self, ctx: Context, duration: Duration) -> None: await ctx.channel.edit(slowmode_delay=duration) if duration: - log_msg = f"ser {ctx.author} applied slowmode to #{ctx.channel} for {stringify_duration(duration)}" + log_msg = f"User {ctx.author} applied slowmode to #{ctx.channel} for {stringify_duration(duration)}" msg = f"⏱️ Applied slowmode for this channel, time delay: {stringify_duration(duration)}." else: log_msg = f"User {ctx.author} removed slowmode from #{ctx.channel}" diff --git a/bot/cogs/utility/reminders.py b/bot/cogs/utility/reminders.py new file mode 100644 index 0000000..7f38c99 --- /dev/null +++ b/bot/cogs/utility/reminders.py @@ -0,0 +1,75 @@ +from collections import defaultdict + +from discord import Color, Embed, Member +from discord.ext.commands import Cog, Context, group +from discord.ext.commands.errors import BadArgument + +from bot.core.bot import Bot +from bot.utils.converters import Duration +from bot.utils.time import stringify_duration +from bot.utils.timer import Timer + + +class Reminders(Cog): + def __init__(self, bot: Bot): + self.bot = bot + self.reminders = defaultdict(list) + self.timer = Timer("reminder") + + async def _remind(self, author: Member, message: str) -> None: + self.reminders[author].remove(message) + + embed = Embed( + title="Your reminder has arrived", + description=message, + color=Color.blue() + ) + await author.send(embed=embed) + + @group(invoke_without_command=True, aliases=["reminders", "remind"]) + async def reminder(self, ctx: Context) -> None: + """Commands for configuring the reminders.""" + await ctx.send_help(ctx.command) + + @reminder.command(alias=["create", "make", "remind"]) + async def add(self, ctx: Context, duration: Duration, *, message: str) -> None: + """ + Send a reminder of given `message` after the specified `duration` expires. + """ + if duration == float("inf"): + raise BadArgument(":x: Duration can't be infinite") + + self.reminders[ctx.author].append(message) + _task_name = f"{ctx.author.id}.{len(self.reminders[ctx.author])}" + self.timer.delay(duration, _task_name, self._remind(ctx.author, message)) + + await ctx.send( + f"You'll be reminded in {stringify_duration(duration)}: {message} " + f"(Reminder ID: {len(self.reminders[ctx.author])})." + ) + + @reminder.command(aliases=["delete", "cancel", "abort"]) + async def remove(self, ctx: Context, reminder_id: int) -> None: + """ + Remove given reminder based on the `reminder_id` + + Reminder IDs are ordered numbers from 1, based on the order + you created your reminders. For example reminder id 2 will be + the second active reminder. + """ + reminder_amount = len(self.reminders[ctx.author]) + if reminder_amount < reminder_id: + if reminder_amount == 0: + await ctx.send(":x: Sorry, you don't have any active reminders.") + else: + await ctx.send(f":x: Sorry, you don't have reminder with this ID. (Maximum ID: {reminder_amount})") + return + + self.timer.abort(f"{ctx.author.id}.{reminder_id}") + del self.reminders[ctx.author][reminder_id - 1] + + await ctx.send(f"Reminder {reminder_id} has been cancelled.") + + +def setup(bot: Bot) -> None: + bot.add_cog(Reminders(bot))