From 3d2960b37a26124c5df390da313b56102cc813d5 Mon Sep 17 00:00:00 2001 From: SeaswimmerTheFsh Date: Sun, 22 Oct 2023 13:28:50 -0400 Subject: [PATCH] feat(moderation): do not run tasks or catch events for guilds that have the cog disabled --- moderation/moderation.py | 124 ++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 60 deletions(-) diff --git a/moderation/moderation.py b/moderation/moderation.py index e391a6f..66ecf9d 100644 --- a/moderation/moderation.py +++ b/moderation/moderation.py @@ -11,7 +11,7 @@ from redbot.core.app_commands import Choice class Moderation(commands.Cog): - """Custom cog moderation cog, meant to copy GalacticBot. + """Custom moderation cog. Developed by SeaswimmerTheFsh.""" def __init__(self, bot): @@ -45,7 +45,8 @@ class Moderation(commands.Cog): guilds: list[discord.Guild] = self.bot.guilds try: for guild in guilds: - await self.create_guild_table(guild) + if not await self.bot.cog_disabled_in_guild(self, guild): + await self.create_guild_table(guild) except ConnectionRefusedError: return @@ -55,52 +56,54 @@ class Moderation(commands.Cog): @commands.Cog.listener('on_guild_join') async def db_generate_guild_join(self, guild: discord.Guild): """This method prepares the database schema whenever the bot joins a guild.""" - conf = await self.check_conf([ - 'mysql_address', - 'mysql_database', - 'mysql_username', - 'mysql_password' - ]) - if conf: - self.logger.error("Failed to create a table for %s, due to MySQL connection configuration being unset.", guild.id) - return - try: - await self.create_guild_table(guild) - except ConnectionRefusedError: - return + if not await self.bot.cog_disabled_in_guild(self, guild): + conf = await self.check_conf([ + 'mysql_address', + 'mysql_database', + 'mysql_username', + 'mysql_password' + ]) + if conf: + self.logger.error("Failed to create a table for %s, due to MySQL connection configuration being unset.", guild.id) + return + try: + await self.create_guild_table(guild) + except ConnectionRefusedError: + return @commands.Cog.listener('on_audit_log_entry_create') async def autologger(self, entry: discord.AuditLogEntry): """This method automatically logs moderations done by users manually ("right clicks").""" - if await self.config.guild(entry.guild.id).ignore_other_bots() is True: - if entry.user.bot or entry.target.bot: - return - else: - if entry.user.id == self.bot.user.id: - return - duration = "NULL" - if entry.reason: - reason = entry.reason + " (This action was performed without the bot.)" - else: - reason = "This action was performed without the bot." - if entry.action == discord.AuditLogAction.kick: - moderation_type = 'KICK' - elif entry.action == discord.AuditLogAction.ban: - moderation_type = 'BAN' - elif entry.action == discord.AuditLogAction.unban: - moderation_type = 'UNBAN' - elif entry.action == discord.AuditLogAction.member_update: - if entry.after.timed_out_until is not None: - timed_out_until_aware = entry.after.timed_out_until.replace(tzinfo=timezone.utc) - duration_datetime = timed_out_until_aware - datetime.now(tz=timezone.utc) - minutes = round(duration_datetime.total_seconds() / 60) - duration = timedelta(minutes=minutes) - moderation_type = 'MUTE' + if not await self.bot.cog_disabled_in_guild(self, entry.guild): + if await self.config.guild(entry.guild.id).ignore_other_bots() is True: + if entry.user.bot or entry.target.bot: + return else: - moderation_type = 'UNMUTE' - else: - return - await self.mysql_log(entry.guild.id, entry.user.id, moderation_type, entry.target.id, duration, reason) + if entry.user.id == self.bot.user.id: + return + duration = "NULL" + if entry.reason: + reason = entry.reason + " (This action was performed without the bot.)" + else: + reason = "This action was performed without the bot." + if entry.action == discord.AuditLogAction.kick: + moderation_type = 'KICK' + elif entry.action == discord.AuditLogAction.ban: + moderation_type = 'BAN' + elif entry.action == discord.AuditLogAction.unban: + moderation_type = 'UNBAN' + elif entry.action == discord.AuditLogAction.member_update: + if entry.after.timed_out_until is not None: + timed_out_until_aware = entry.after.timed_out_until.replace(tzinfo=timezone.utc) + duration_datetime = timed_out_until_aware - datetime.now(tz=timezone.utc) + minutes = round(duration_datetime.total_seconds() / 60) + duration = timedelta(minutes=minutes) + moderation_type = 'MUTE' + else: + moderation_type = 'UNMUTE' + else: + return + await self.mysql_log(entry.guild.id, entry.user.id, moderation_type, entry.target.id, duration, reason) async def connect(self): """Connects to the MySQL database, and returns a connection object.""" @@ -679,24 +682,25 @@ class Moderation(commands.Cog): db = await self.config.mysql_database() guilds: list[discord.Guild] = self.bot.guilds for guild in guilds: - tempban_query = f"SELECT target_id, moderation_id FROM moderation_{guild.id} WHERE end_timestamp != 0 AND end_timestamp <= %s AND moderation_type = 'TEMPBAN' AND expired = 0" - try: - cursor.execute(tempban_query, (time.time(),)) - result = cursor.fetchall() - except mysql.connector.errors.ProgrammingError: - continue - target_ids = [row[0] for row in result] - moderation_ids = [row[1] for row in result] - for target_id, moderation_id in zip(target_ids, moderation_ids): - user: discord.User = await self.bot.fetch_user(target_id) - await guild.unban(user, reason=f"Automatic unban from case #{moderation_id}") - embed = await self.embed_factory('message', guild, f'Automatic unban from case #{moderation_id}', 'unbanned') + if not await self.bot.cog_disabled_in_guild(self, guild): + tempban_query = f"SELECT target_id, moderation_id FROM moderation_{guild.id} WHERE end_timestamp != 0 AND end_timestamp <= %s AND moderation_type = 'TEMPBAN' AND expired = 0" try: - await user.send(embed=embed) - except discord.errors.HTTPException: - pass - expiry_query = f"UPDATE `{db}`.`moderation_{guild.id}` SET expired = 1 WHERE (end_timestamp != 0 AND end_timestamp <= %s AND expired = 0) OR (expired = 0 AND resolved = 1)" - cursor.execute(expiry_query, (time.time(),)) + cursor.execute(tempban_query, (time.time(),)) + result = cursor.fetchall() + except mysql.connector.errors.ProgrammingError: + continue + target_ids = [row[0] for row in result] + moderation_ids = [row[1] for row in result] + for target_id, moderation_id in zip(target_ids, moderation_ids): + user: discord.User = await self.bot.fetch_user(target_id) + await guild.unban(user, reason=f"Automatic unban from case #{moderation_id}") + embed = await self.embed_factory('message', guild, f'Automatic unban from case #{moderation_id}', 'unbanned') + try: + await user.send(embed=embed) + except discord.errors.HTTPException: + pass + expiry_query = f"UPDATE `{db}`.`moderation_{guild.id}` SET expired = 1 WHERE (end_timestamp != 0 AND end_timestamp <= %s AND expired = 0) OR (expired = 0 AND resolved = 1)" + cursor.execute(expiry_query, (time.time(),)) database.commit() cursor.close() database.close()