feat(moderation): added galacticbot importing

This commit is contained in:
Seaswimmer 2023-12-15 21:31:00 -05:00
parent 623d44b98b
commit 0c28d362be
Signed by untrusted user: cswimr
GPG key ID: 1EBC234EEDA901AE

View file

@ -313,8 +313,9 @@ class Moderation(commands.Cog):
return True return True
async def mysql_log(self, guild_id: str, author_id: str, moderation_type: str, target_id: int, role_id: int, duration, reason: str, database: mysql.connector.MySQLConnection = None): async def mysql_log(self, guild_id: str, author_id: str, moderation_type: str, target_id: int, role_id: int, duration, reason: str, database: mysql.connector.MySQLConnection = None, timestamp: int = None, resolved: bool = False, resolved_by: str = None, resolved_reason: str = None, expired: bool = None, changes: list = []):
timestamp = int(time.time()) if not timestamp:
timestamp = int(time.time())
if duration != "NULL": if duration != "NULL":
end_timedelta = datetime.fromtimestamp(timestamp) + duration end_timedelta = datetime.fromtimestamp(timestamp) + duration
@ -322,21 +323,37 @@ class Moderation(commands.Cog):
else: else:
end_timestamp = 0 end_timestamp = 0
if not expired:
if int(time.time()) > end_timestamp:
expired = 1
else:
expired = 0
if resolved_by is None:
resolved_by = "NULL"
if resolved_reason is None:
resolved_reason = "NULL"
if not database: if not database:
database = await self.connect() database = await self.connect()
close_db = True
else:
close_db = False
cursor = database.cursor() cursor = database.cursor()
moderation_id = await self.get_next_case_number(guild_id=guild_id, cursor=cursor) moderation_id = await self.get_next_case_number(guild_id=guild_id, cursor=cursor)
sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (moderation_id, timestamp, moderation_type, target_id, author_id, role_id, duration, end_timestamp, f"{reason}", 0, "NULL", "NULL", 0, json.dumps([])) val = (moderation_id, timestamp, moderation_type, target_id, author_id, role_id, duration, end_timestamp, {reason}, int(resolved), resolved_by, resolved_reason, expired, json.dumps(changes))
cursor.execute(sql, val) cursor.execute(sql, val)
cursor.close() cursor.close()
database.commit() database.commit()
database.close() if close_db:
database.close()
self.logger.debug("MySQL row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, 0, NULL, NULL, 0, []", guild_id, moderation_id, timestamp, moderation_type, target_id, author_id, role_id, duration, end_timestamp, reason) self.logger.debug("MySQL row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s", guild_id, moderation_id, timestamp, moderation_type, target_id, author_id, role_id, duration, end_timestamp, reason, int(resolved), resolved_by, resolved_reason, expired, changes)
return moderation_id return moderation_id
@ -369,23 +386,31 @@ class Moderation(commands.Cog):
async def fetch_user_dict(self, interaction: discord.Interaction, user_id: str): async def fetch_user_dict(self, interaction: discord.Interaction, user_id: str):
"""This method returns a dictionary containing either user information or a standard deleted user template.""" """This method returns a dictionary containing either user information or a standard deleted user template."""
try: if user_id == '?':
user = interaction.client.get_user(user_id)
if user is None:
user = await interaction.client.fetch_user(user_id)
user_dict = { user_dict = {
'id': user.id, 'id': '?',
'name': user.name, 'name': 'Unknown User',
'discriminator': user.discriminator 'discriminator':'0'
} }
except discord.errors.NotFound: else:
user_dict = { try:
'id': user_id, user = interaction.client.get_user(user_id)
'name': 'Deleted User', if user is None:
'discriminator': '0' user = await interaction.client.fetch_user(user_id)
}
user_dict = {
'id': user.id,
'name': user.name,
'discriminator': user.discriminator
}
except discord.errors.NotFound:
user_dict = {
'id': user_id,
'name': 'Deleted User',
'discriminator': '0'
}
return user_dict return user_dict
@ -1106,7 +1131,7 @@ class Moderation(commands.Cog):
except discord.NotFound: except discord.NotFound:
pass pass
resolve_query = f"UPDATE `{db}`.`moderation_{interaction.guild.id}` SET resolved = 1, expired = 1, changes = %s, resolved_by = %s, resolve_reason = %s WHERE moderation_id = %s" resolve_query = f"UPDATE `{db}`.`moderation_{interaction.guild.id}` SET resolved = 1, changes = %s, resolved_by = %s, resolve_reason = %s WHERE moderation_id = %s"
else: else:
resolve_query = f"UPDATE `{db}`.`moderation_{interaction.guild.id}` SET resolved = 1, changes = %s, resolved_by = %s, resolve_reason = %s WHERE moderation_id = %s" resolve_query = f"UPDATE `{db}`.`moderation_{interaction.guild.id}` SET resolved = 1, changes = %s, resolved_by = %s, resolve_reason = %s WHERE moderation_id = %s"
@ -1641,23 +1666,98 @@ class Moderation(commands.Cog):
@checks.admin() @checks.admin()
async def moderationset_import_galacticbot(self, ctx: commands.Context): async def moderationset_import_galacticbot(self, ctx: commands.Context):
"""Import moderations from GalacticBot. **UNFINISHED!**""" """Import moderations from GalacticBot. **UNFINISHED!**"""
message = await ctx.send("Are you sure you want to import GalacticBot moderations? **This will overwrite any moderations that already exist in this guild's moderation table.**") if ctx.message.attachments and ctx.message.attachments[0].content_type == 'application/json; charset=utf-8':
await message.edit(view=self.GalacticBotImportButtons(60, message)) message = await ctx.send("Are you sure you want to import GalacticBot moderations? **This will overwrite any moderations that already exist in this guild's moderation table.**")
await message.edit(view=self.GalacticBotImportButtons(60, ctx, message, self))
else:
await ctx.send("Please provide a valid GalacticBot moderation export file.")
class GalacticBotImportButtons(discord.ui.View): class GalacticBotImportButtons(discord.ui.View):
def __init__(self, timeout, message): def __init__(self, timeout, ctx, message, cog_instance):
super().__init__() super().__init__()
self.cog_instance = cog_instance
self.ctx: commands.Context = ctx
self.message: discord.Message = message self.message: discord.Message = message
self.config = Config.get_conf(None, cog_name='Moderation', identifier=481923957134912) self.config = Config.get_conf(None, cog_name='Moderation', identifier=481923957134912)
@discord.ui.button(label="Yes", style=discord.ButtonStyle.success) @discord.ui.button(label="Yes", style=discord.ButtonStyle.success)
async def import_button_y(self, interaction: discord.Interaction, button: discord.ui.Button): # pylint: disable=unused-argument async def import_button_y(self, interaction: discord.Interaction, button: discord.ui.Button): # pylint: disable=unused-argument
await self.message.edit("This command does nothing at the moment.", view=None) await self.message.delete()
await interaction.response.send_message("Deleting original table...", ephemeral=True)
database = await Moderation.connect(self.cog_instance)
cursor = database.cursor()
query = f"DROP TABLE IF EXISTS moderation_{self.ctx.guild.id};"
cursor.execute(query)
cursor.close()
database.commit()
database.close()
await interaction.edit_original_response(content="Creating new table...")
await Moderation.create_guild_table(self.cog_instance, self.ctx.guild)
await interaction.edit_original_response(content="Importing moderations...")
accepted_types = [
'NOTE',
'WARN',
'MUTE',
'UNMUTE',
'KICK',
'SOFTBAN',
'BAN',
'UNBAN'
]
file = await self.ctx.message.attachments[0].read()
data = sorted(json.loads(file), key=lambda x: x['case'])
for case in data:
if case['type'] not in accepted_types:
continue
timestamp = case['timestamp'] / 1000
if case['duration']:
duration = timedelta(milliseconds=case['duration'])
if case['resolved']:
resolved = 1
for change in case['changes']:
if change['type'] == 'RESOLVE':
resolved_by = change['staff']
resolved_reason = change['reason']
resolve_timestamp = change['timestamp'] / 1000
break
if resolved_by is None:
resolved_by = '?'
if resolved_reason is None:
resolved_reason = 'Could not get resolve reason during moderation import.'
changes = [
{
'type': "ORIGINAL",
'reason': case['reason'],
'user_id': case['executor'],
'timestamp': timestamp
},
{
'type': "RESOLVE",
'reason': resolved_reason,
'user_id': resolved_by,
'timestamp': resolve_timestamp
}
]
await Moderation.mysql_log(self.cog_instance, self.ctx.guild, case['executor'], case['type'], case['target'], 0, duration, case['reason'], timestamp=timestamp, resolved=resolved, resolved_by=resolved_by, resolved_reason=resolved_reason, changes=changes)
await interaction.edit_original_response(content="Import complete.")
@discord.ui.button(label="No", style=discord.ButtonStyle.danger) @discord.ui.button(label="No", style=discord.ButtonStyle.danger)
async def import_button_n(self, interaction: discord.Interaction, button: discord.ui.Button): # pylint: disable=unused-argument async def import_button_n(self, interaction: discord.Interaction, button: discord.ui.Button): # pylint: disable=unused-argument
await self.message.edit("Import cancelled.", view=None) await self.message.edit("Import cancelled.", view=None)
await self.message.delete(10) await self.message.delete(10)
await self.ctx.message.delete(10)
@commands.command(aliases=["tdc"]) @commands.command(aliases=["tdc"])
async def timedeltaconvert(self, ctx: commands.Context, *, duration: str): async def timedeltaconvert(self, ctx: commands.Context, *, duration: str):