diff --git a/.env.example b/.env.example deleted file mode 100644 index f74c661..0000000 --- a/.env.example +++ /dev/null @@ -1 +0,0 @@ -TOKEN= \ No newline at end of file diff --git a/cogs/notifications.py b/cogs/notifications.py index 0bbb947..4b01b08 100644 --- a/cogs/notifications.py +++ b/cogs/notifications.py @@ -28,7 +28,7 @@ class NotificationsView(discord.ui.View): def __init__(self, bot, categories): super().__init__() self.bot = bot - + print(self.bot.guilds) # del this line (but keep empty) for category in categories: role = self.bot.guilds[0].get_role(category["role"]) self.add_item(RoleButton(role)) diff --git a/cogs/reminders.py b/cogs/reminders.py index 6f080de..588f821 100644 --- a/cogs/reminders.py +++ b/cogs/reminders.py @@ -1,6 +1,8 @@ import discord from discord.ext import commands, tasks from datetime import datetime, timedelta +from random import choice +from string import ascii_lowercase, ascii_uppercase from util import is_discord_member from timeutil import UserFriendlyTime @@ -19,7 +21,8 @@ async def remind_me(self, ctx, *, time: UserFriendlyTime): user_id=ctx.author.id, channel_id=ctx.channel.id, message=message, - timestamp=time.dt + timestamp=time.dt, + key=''.join(choice(ascii_lowercase + ascii_uppercase, k=ctx.bot.config["reminder_key_length"])) ) await ctx.reply(f"{ctx.author.mention}: I will remind you at {time.dt.strftime('%Y-%m-%d %H:%M:%S')} UTC with the message: {message}") @@ -32,9 +35,9 @@ async def my_reminders(self, ctx): return await ctx.reply(f"{ctx.author.display_name}: You have no reminders set.") elif len(reminders) < 25: embed = discord.Embed(title=f"{ctx.author.display_name}'s Reminders", color=discord.Color.blue()) - for message, _, timestamp in reminders: + for message, _, timestamp, key in reminders: embed.add_field( - name=f"Reminder at {timestamp.strftime('%Y-%m-%d %H:%M:%S')}", + name=f"Reminder at {timestamp.strftime('%Y-%m-%d %H:%M:%S')}; key={key}", value=f"Message: {message}", inline=False ) @@ -53,5 +56,23 @@ async def check_reminders(self): # If the bot cannot send messages to the channel, skip it continue + @is_discord_member() + @commands.command(name='delete_reminder', aliased=['delreminder']) + async def delete_reminder(self, ctx, *, key: str) -> None: + """Delete all reminders of the user with the given key.""" + for char in key: + if not char in ascii_lowercase + ascii_uppercase: + return await ctx.reply(f"{ctx.author.display_name}: Key contains non alphabetical characters.") + + reminders = await self.bot.database.get_reminders(ctx.author.id) + if not reminders: + return await ctx.reply(f"{ctx.author.display_name}: You have no reminders to delete.") + + if not any(reminder[3] == key for reminder in reminders): + return await ctx.reply(f"{ctx.author.display_name}: {key} not valid for any of your reminders.") + + await self.bot.database.delete_reminder(user_id=ctx.author.id, key=key) + await ctx.reply(f"{ctx.author.mention}: Reminder deleted successfully.") + async def setup(bot): - await bot.add_cog(Reminders(bot)) \ No newline at end of file + await bot.add_cog(Reminders(bot)) diff --git a/config.example.yaml b/config.example.yaml index b63995a..17db6ea 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -33,6 +33,10 @@ fractalDeets: maxIterations: 10000 messiness: 30 zoom: 3.5 +spirographDeets: + height: 2000 + width: 2000 + length: 1000 automod_regexes: - "^test(ing)?$" - "f[0o]+" diff --git a/database.py b/database.py index e8110e8..678f179 100644 --- a/database.py +++ b/database.py @@ -55,7 +55,8 @@ async def connect(self): user_id INTEGER, channel_id INTEGER, message TEXT, - timestamp DATETIME + timestamp DATETIME, + key TEXT )""" ) await cursor.execute( @@ -224,7 +225,7 @@ async def get_timers(self, user_id): await self.connection.commit() return rows - async def add_reminder(self, user_id, channel_id, message, timestamp): + async def add_reminder(self, *, user_id, channel_id, message, timestamp, key: str): """Add a reminder for a user. The reminder is stored in the database with the user's ID, message, and timestamp. Args: @@ -234,11 +235,11 @@ async def add_reminder(self, user_id, channel_id, message, timestamp): timestamp (datetime): The time when the reminder should be triggered """ async with self.connection.cursor() as cur: - query = "INSERT INTO reminders(user_id, channel_id, message, timestamp) VALUES(?, ?, ?, ?)" - await cur.execute(query, (user_id, channel_id, message, timestamp)) + query = "INSERT INTO reminders(user_id, channel_id, message, timestamp, key) VALUES(?, ?, ?, ?, \)" + await cur.execute(query, (user_id, channel_id, message, timestamp, key)) await self.connection.commit() - async def get_reminders(self, user_id): + async def get_reminders(self, user_id) -> list[tuple[str, str, str, str]]: # I suppose the DB just returns strings and not Python objects """Get all reminders for a user. The reminders are returned as a list of tuples with the message and timestamp of each reminder. Args: @@ -248,7 +249,7 @@ async def get_reminders(self, user_id): list: A list of tuples with the message, channel and timestamp of each reminder """ async with self.connection.cursor() as cur: - query = "SELECT message, channel_id, timestamp FROM reminders WHERE user_id = ?" + query = "SELECT message, channel_id, timestamp, key FROM reminders WHERE user_id = ?" await cur.execute(query, (user_id,)) rows = await cur.fetchall() return rows @@ -261,7 +262,19 @@ async def pop_expired_reminders(self): rows = await cur.fetchall() await self.connection.commit() return rows - + + async def delete_reminder(self, *, user_id, key: str) -> None: + """Remove reminder from the user, filtered by key, from the database. + + Args: + user_id (int): The id of the user wanting to delete a reminder + key (str): The key we use to filter out the reminder + """ + async with self.connection.cursor() as cur: + query = "DELETE FROM reminders WHERE user_id = ? AND key = ? RETURNING message" + await cur.execute(query, (user_id, key)) + await self.connection.commit() + async def add_tempban(self, user_id, reason, timestamp): """Add a temporary ban for a user. The ban is stored in the database with the user's ID, reason, and expiration time. diff --git a/latest.log b/latest.log new file mode 100644 index 0000000..e69de29