diff --git a/moderation/moderation.py b/moderation/moderation.py index 5863647..b72a17d 100644 --- a/moderation/moderation.py +++ b/moderation/moderation.py @@ -24,7 +24,7 @@ from .utilities.config import config, register_config from .utilities.database import connect, create_guild_table, fetch_case, mysql_log from .utilities.embed_factory import embed_factory from .utilities.logger import logger -from .utilities.utils import check_conf, check_moddable, check_permissions, fetch_channel_dict, fetch_user_dict, generate_dict, log +from .utilities.utils import check_conf, check_moddable, check_permissions, fetch_channel_dict, fetch_user_dict, generate_dict, log, send_evidenceformat class Moderation(commands.Cog): @@ -188,6 +188,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has received a note! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="warn") async def warn(self, interaction: discord.Interaction, target: discord.Member, reason: str, silent: bool = None): """Warn a user. @@ -218,6 +221,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been warned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + async def blacklist_autocomplete(self, interaction: discord.Interaction, current: str,) -> list[app_commands.Choice[str]]: # pylint: disable=unused-argument """Autocompletes a blacklist role.""" blacklist_roles = await config.guild(interaction.guild).blacklist_roles() @@ -282,6 +288,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been blacklisted with the {role_obj.name} role for {humanize.precisedelta(matching_role['duration'])}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="mute") async def mute(self, interaction: discord.Interaction, target: discord.Member, duration: str, reason: str, silent: bool = None): """Mute a user. @@ -330,6 +339,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been muted for {humanize.precisedelta(parsed_time)}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="unmute") async def unmute(self, interaction: discord.Interaction, target: discord.Member, reason: str = None, silent: bool = None): """Unmute a user. @@ -370,6 +382,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been unmuted! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="kick") async def kick(self, interaction: discord.Interaction, target: discord.Member, reason: str, silent: bool = None): """Kick a user. @@ -402,6 +417,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been kicked! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="ban") @app_commands.choices(delete_messages=[ Choice(name="None", value=0), @@ -456,6 +474,9 @@ class Moderation(commands.Cog): moderation_id = await mysql_log(interaction.guild.id, interaction.user.id, 'TEMPBAN', target.id, 0, parsed_time, reason) await interaction.edit_original_response(content=f"{target.mention} has been banned for {humanize.precisedelta(parsed_time)}! (Case `#{moderation_id}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) else: await interaction.response.send_message(content=f"{target.mention} has been banned!\n**Reason** - `{reason}`") @@ -474,6 +495,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been banned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="unban") async def unban(self, interaction: discord.Interaction, target: discord.User, reason: str = None, silent: bool = None): """Unban a user. @@ -516,6 +540,9 @@ class Moderation(commands.Cog): await interaction.edit_original_response(content=f"{target.mention} has been unbanned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`") await log(interaction, moderation_id) + case = await fetch_case(moderation_id, interaction.guild.id) + await send_evidenceformat(interaction, case) + @app_commands.command(name="history") async def history(self, interaction: discord.Interaction, target: discord.User = None, moderator: discord.User = None, pagesize: app_commands.Range[int, 1, 20] = None, page: int = 1, ephemeral: bool = None, inline: bool = None, export: bool = False): """List previous infractions. @@ -1011,6 +1038,18 @@ class Moderation(commands.Cog): async def moderationset(self, ctx: commands.Context): """Manage moderation commands.""" + @moderationset.command(name='autoevidence') + async def moderationset_autoevidence(self, ctx: commands.Context, enabled: bool): + """Toggle if the evidenceformat codeblock should be sent automatically.""" + await config.user(ctx.author).auto_evidenceformat.set(enabled) + await ctx.send(f"Auto evidenceformat setting set to {enabled}") + + @moderationset_autoevidence.command(name='autoevidence') + async def moderationset_autoevidence(self, ctx: commands.Context, enabled: bool): + """Toggle if the evidenceformat codeblock should be sent automatically.""" + await config.guild(ctx.guild).auto_evidenceformat.set(enabled) + await ctx.send(f"Auto evidenceformat setting set to {enabled}") + @moderationset.command(name='list', aliases=['view', 'show']) async def moderationset_list(self, ctx: commands.Context): """List all moderation settings.""" diff --git a/moderation/utilities/config.py b/moderation/utilities/config.py index f9caaa1..5c89788 100644 --- a/moderation/utilities/config.py +++ b/moderation/utilities/config.py @@ -19,11 +19,13 @@ def register_config(config: Config): history_inline = False, history_pagesize = 5, history_inline_pagesize = 6, + auto_evidenceformat = False, blacklist_roles = [] ) config.register_user( history_ephemeral = None, history_inline = None, history_pagesize = None, - history_inline_pagesize = None + history_inline_pagesize = None, + auto_evidenceformat = None ) diff --git a/moderation/utilities/utils.py b/moderation/utilities/utils.py index 322b2c8..1e61002 100644 --- a/moderation/utilities/utils.py +++ b/moderation/utilities/utils.py @@ -112,7 +112,7 @@ async def check_moddable( async def get_next_case_number(guild_id: str, cursor=None): - """This method returns the next case number from the MySQL table for a specific guild.""" + """This function returns the next case number from the MySQL table for a specific guild.""" from .database import connect if not cursor: @@ -147,7 +147,7 @@ def generate_dict(result): async def fetch_user_dict(interaction: Interaction, user_id: str): - """This method returns a dictionary containing either user information or a standard deleted user template.""" + """This function returns a dictionary containing either user information or a standard deleted user template.""" if user_id == "?": user_dict = {"id": "?", "name": "Unknown User", "discriminator": "0"} @@ -174,7 +174,7 @@ async def fetch_user_dict(interaction: Interaction, user_id: str): async def fetch_channel_dict(interaction: Interaction, channel_id: str): - """This method returns a dictionary containing either channel information or a standard deleted channel template.""" + """This function returns a dictionary containing either channel information or a standard deleted channel template.""" try: channel = interaction.guild.get_channel(channel_id) if not channel: @@ -189,7 +189,7 @@ async def fetch_channel_dict(interaction: Interaction, channel_id: str): async def fetch_role_dict(interaction: Interaction, role_id: str): - """This method returns a dictionary containing either role information or a standard deleted role template.""" + """This function returns a dictionary containing either role information or a standard deleted role template.""" role = interaction.guild.get_role(role_id) if not role: role_dict = {"id": role_id, "name": "Deleted Role"} @@ -200,7 +200,7 @@ async def fetch_role_dict(interaction: Interaction, role_id: str): async def log(interaction: Interaction, moderation_id: int, resolved: bool = False): - """This method sends a message to the guild's configured logging channel when an infraction takes place.""" + """This function sends a message to the guild's configured logging channel when an infraction takes place.""" from .database import fetch_case from .embed_factory import embed_factory @@ -217,3 +217,19 @@ async def log(interaction: Interaction, moderation_id: int, resolved: bool = Fal await logging_channel.send(embed=embed) except Forbidden: return + +async def send_evidenceformat(interaction: Interaction, case_dict: dict): + """This function sends an ephemeral message to the moderator who took the moderation action, with a pre-made codeblock for use in the mod-evidence channel.""" + from .embed_factory import embed_factory + from .config import config + + send_evidence_bool = (await config.user(interaction.user).auto_evidenceformat() + or await config.guild(interaction.guild).auto_evidenceformat() + or False) + if send_evidence_bool is False: + return + + content = await embed_factory( + "evidenceformat", await interaction.client.get_embed_color(None), interaction=interaction, case_dict=case_dict + ) + await interaction.followup.send(content=content, ephemeral=True)