mirror of
https://github.com/allthingslinux/tux.git
synced 2024-10-02 16:43:12 +00:00
feat(emojis): add new snippetban and snippetunban emojis
feat(setup.py): add new Setup class for server setup refactor(moderation): move handle_case_response method to ModerationCogBase class for code reusability fix(moderation): replace async create_embed method with synchronous one feat(moderation): add support for case handling in ban command feat(cases.py): update snippetban and snippetunban emoji ids refactor(cases.py): replace async create_embed method with synchronous one refactor(jail.py, kick.py): remove redundant code and simplify jail and kick commands feat(jail.py, kick.py): improve error handling and logging for jail and kick commands style(jail.py, kick.py): improve code readability and maintainability by removing unnecessary imports and functions refactor(snippetban.py, snippetunban.py, timeout.py): simplify case handling logic and error handling feat(snippetban.py, snippetunban.py): add reason parameter to usage and make error messages ephemeral fix(timeout.py): move send_dm call after successful timeout to ensure user is notified only when action is successful refactor(unban.py, unjail.py): simplify unban and unjail commands by removing redundant code feat(unjail.py): add error handling for missing jail role or jail channel fix(unjail.py): ensure atomicity when removing jail role and adding previous roles to prevent partial role assignment refactor(untimeout.py, warn.py): remove redundant code and simplify case response handling fix(untimeout.py, warn.py): move send_dm call to after timeout/warn action to ensure it's sent after action is successful
This commit is contained in:
parent
9e11b5fb67
commit
8e3d8cdc66
15 changed files with 242 additions and 666 deletions
BIN
assets/emojis/snippetban.png
Normal file
BIN
assets/emojis/snippetban.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
assets/emojis/snippetunban.png
Normal file
BIN
assets/emojis/snippetunban.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8 KiB |
85
tux/cogs/guild/setup.py
Normal file
85
tux/cogs/guild/setup.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
import discord
|
||||
from discord import app_commands
|
||||
from discord.ext import commands
|
||||
|
||||
from tux.database.controllers import DatabaseController
|
||||
from tux.utils import checks
|
||||
|
||||
|
||||
class Setup(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot) -> None:
|
||||
self.bot = bot
|
||||
self.db = DatabaseController()
|
||||
self.config = DatabaseController().guild_config
|
||||
|
||||
setup = app_commands.Group(name="setup", description="Set up Tux for your server.")
|
||||
|
||||
@setup.command(name="jail")
|
||||
@commands.guild_only()
|
||||
@checks.ac_has_pl(7)
|
||||
async def setup_jail(self, interaction: discord.Interaction) -> None:
|
||||
"""
|
||||
Set up the jail role channel permissions for the server.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
interaction : discord.Interaction
|
||||
The discord interaction object.
|
||||
"""
|
||||
|
||||
if interaction.guild is None:
|
||||
return
|
||||
|
||||
jail_role_id = await self.config.get_guild_config_field_value(interaction.guild.id, "jail_role_id")
|
||||
if not jail_role_id:
|
||||
await interaction.response.send_message("No jail role has been set up for this server.", ephemeral=True)
|
||||
return
|
||||
|
||||
jail_role = interaction.guild.get_role(jail_role_id)
|
||||
if not jail_role:
|
||||
await interaction.response.send_message("The jail role has been deleted.", ephemeral=True)
|
||||
return
|
||||
|
||||
jail_channel_id = await self.config.get_guild_config_field_value(interaction.guild.id, "jail_channel_id")
|
||||
if not jail_channel_id:
|
||||
await interaction.response.send_message("No jail channel has been set up for this server.", ephemeral=True)
|
||||
return
|
||||
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
|
||||
await self._set_permissions_for_channels(interaction, jail_role, jail_channel_id)
|
||||
|
||||
await interaction.edit_original_response(
|
||||
content="Permissions have been set up for the jail role.",
|
||||
)
|
||||
|
||||
async def _set_permissions_for_channels(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
jail_role: discord.Role,
|
||||
jail_channel_id: int,
|
||||
) -> None:
|
||||
if interaction.guild is None:
|
||||
return
|
||||
|
||||
for channel in interaction.guild.channels:
|
||||
if not isinstance(channel, discord.TextChannel | discord.VoiceChannel | discord.ForumChannel):
|
||||
continue
|
||||
|
||||
if (
|
||||
jail_role in channel.overwrites
|
||||
and channel.overwrites[jail_role].send_messages is False
|
||||
and channel.overwrites[jail_role].read_messages is False
|
||||
and channel.id != jail_channel_id
|
||||
):
|
||||
continue
|
||||
|
||||
await channel.set_permissions(jail_role, send_messages=False, read_messages=False)
|
||||
if channel.id == jail_channel_id:
|
||||
await channel.set_permissions(jail_role, send_messages=True, read_messages=True)
|
||||
|
||||
await interaction.edit_original_response(content=f"Setting up permissions for {channel.name}.")
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
await bot.add_cog(Setup(bot))
|
|
@ -4,7 +4,9 @@ import discord
|
|||
from discord.ext import commands
|
||||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from tux.database.controllers import DatabaseController
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.embeds import create_embed_footer, create_error_embed
|
||||
|
||||
|
||||
|
@ -14,7 +16,7 @@ class ModerationCogBase(commands.Cog):
|
|||
self.db = DatabaseController()
|
||||
self.config = DatabaseController().guild_config
|
||||
|
||||
async def create_embed(
|
||||
def create_embed(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
title: str,
|
||||
|
@ -22,6 +24,7 @@ class ModerationCogBase(commands.Cog):
|
|||
color: int,
|
||||
icon_url: str,
|
||||
timestamp: datetime | None = None,
|
||||
thumbnail_url: str | None = None,
|
||||
) -> discord.Embed:
|
||||
"""
|
||||
Create an embed for moderation actions.
|
||||
|
@ -49,6 +52,7 @@ class ModerationCogBase(commands.Cog):
|
|||
|
||||
embed = discord.Embed(color=color, timestamp=timestamp or ctx.message.created_at)
|
||||
embed.set_author(name=title, icon_url=icon_url)
|
||||
embed.set_thumbnail(url=thumbnail_url)
|
||||
|
||||
footer_text, footer_icon_url = create_embed_footer(ctx)
|
||||
embed.set_footer(text=footer_text, icon_url=footer_icon_url)
|
||||
|
@ -166,3 +170,42 @@ class ModerationCogBase(commands.Cog):
|
|||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case_type: CaseType,
|
||||
case_id: int | None,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
duration: str | None = None,
|
||||
):
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if case_id is not None:
|
||||
embed = self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case_id} ({duration} {case_type})" if duration else f"Case #{case_id} ({case_type})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
|
||||
else:
|
||||
embed = self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #0 ({duration} {case_type})" if duration else f"Case #0 ({case_type})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
|
|
|
@ -3,9 +3,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import BanFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -48,6 +46,7 @@ class Ban(ModerationCogBase):
|
|||
discord.HTTPException
|
||||
If an error occurs while banning the user.
|
||||
"""
|
||||
|
||||
if ctx.guild is None:
|
||||
logger.warning("Ban command used outside of a guild context.")
|
||||
return
|
||||
|
@ -74,48 +73,7 @@ class Ban(ModerationCogBase):
|
|||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} ({case.case_type}) {action}",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case {action} ({CaseType.BAN})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
await self.handle_case_response(ctx, CaseType.BAN, case.case_id, flags.reason, target)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
|
@ -23,8 +23,8 @@ emojis: dict[str, int] = {
|
|||
"timeout": 1268115809083981886,
|
||||
"warn": 1268115764498399264,
|
||||
"jail": 1268115750392954880,
|
||||
"snippetban": 1275782294363312172, # Placeholder
|
||||
"snippetunban": 1275782294363312172, # Placeholder
|
||||
"snippetban": 1277174953950576681,
|
||||
"snippetunban": 1277174953292337222,
|
||||
}
|
||||
|
||||
|
||||
|
@ -269,7 +269,7 @@ class Cases(ModerationCogBase):
|
|||
|
||||
fields = self._create_case_fields(moderator, target, reason)
|
||||
|
||||
embed = await self.create_embed(
|
||||
embed = self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} ({case.case_type}) {action}",
|
||||
fields=fields,
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import discord
|
||||
from discord import app_commands
|
||||
from discord.ext import commands
|
||||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import JailFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -16,74 +13,6 @@ class Jail(ModerationCogBase):
|
|||
def __init__(self, bot: commands.Bot) -> None:
|
||||
super().__init__(bot)
|
||||
|
||||
@app_commands.command(
|
||||
name="setup_jail",
|
||||
)
|
||||
@commands.guild_only()
|
||||
@checks.ac_has_pl(7)
|
||||
async def setup_jail(self, interaction: discord.Interaction) -> None:
|
||||
"""
|
||||
Set up the jail role channel permissions for the server.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
interaction : discord.Interaction
|
||||
The discord interaction object.
|
||||
"""
|
||||
|
||||
if interaction.guild is None:
|
||||
return
|
||||
|
||||
jail_role_id = await self.config.get_guild_config_field_value(interaction.guild.id, "jail_role_id")
|
||||
if not jail_role_id:
|
||||
await interaction.response.send_message("No jail role has been set up for this server.", ephemeral=True)
|
||||
return
|
||||
|
||||
jail_role = interaction.guild.get_role(jail_role_id)
|
||||
if not jail_role:
|
||||
await interaction.response.send_message("The jail role has been deleted.", ephemeral=True)
|
||||
return
|
||||
|
||||
jail_channel_id = await self.config.get_guild_config_field_value(interaction.guild.id, "jail_channel_id")
|
||||
if not jail_channel_id:
|
||||
await interaction.response.send_message("No jail channel has been set up for this server.", ephemeral=True)
|
||||
return
|
||||
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
|
||||
await self._set_permissions_for_channels(interaction, jail_role, jail_channel_id)
|
||||
|
||||
await interaction.edit_original_response(
|
||||
content="Permissions have been set up for the jail role.",
|
||||
)
|
||||
|
||||
async def _set_permissions_for_channels(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
jail_role: discord.Role,
|
||||
jail_channel_id: int,
|
||||
) -> None:
|
||||
if interaction.guild is None:
|
||||
return
|
||||
|
||||
for channel in interaction.guild.channels:
|
||||
if not isinstance(channel, discord.TextChannel | discord.VoiceChannel | discord.ForumChannel):
|
||||
continue
|
||||
|
||||
if (
|
||||
jail_role in channel.overwrites
|
||||
and channel.overwrites[jail_role].send_messages is False
|
||||
and channel.overwrites[jail_role].read_messages is False
|
||||
and channel.id != jail_channel_id
|
||||
):
|
||||
continue
|
||||
|
||||
await channel.set_permissions(jail_role, send_messages=False, read_messages=False)
|
||||
if channel.id == jail_channel_id:
|
||||
await channel.set_permissions(jail_role, send_messages=True, read_messages=True)
|
||||
|
||||
await interaction.edit_original_response(content=f"Setting up permissions for {channel.name}.")
|
||||
|
||||
@commands.hybrid_command(
|
||||
name="jail",
|
||||
aliases=["j"],
|
||||
|
@ -91,7 +20,7 @@ class Jail(ModerationCogBase):
|
|||
)
|
||||
@commands.guild_only()
|
||||
@checks.has_pl(2)
|
||||
async def jail(
|
||||
async def jail( # noqa: PLR0911
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
target: discord.Member,
|
||||
|
@ -137,38 +66,55 @@ class Jail(ModerationCogBase):
|
|||
|
||||
case_target_roles = [role.id for role in target_roles]
|
||||
|
||||
await self._jail_user(ctx, target, flags, jail_role, target_roles)
|
||||
|
||||
case = await self._insert_jail_case(ctx, target, flags.reason, case_target_roles)
|
||||
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, target)
|
||||
|
||||
async def _insert_jail_case(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
target: discord.Member,
|
||||
reason: str,
|
||||
case_target_roles: list[int] | None = None,
|
||||
) -> Case | None:
|
||||
if not ctx.guild:
|
||||
logger.warning("Jail command used outside of a guild context.")
|
||||
return None
|
||||
|
||||
try:
|
||||
return await self.db.case.insert_case(
|
||||
case = await self.db.case.insert_case(
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.JAIL,
|
||||
case_reason=reason,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
case_target_roles=case_target_roles,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to insert jail case for {target}. {e}")
|
||||
await ctx.send(f"Failed to insert jail case for {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return None
|
||||
|
||||
def _get_manageable_roles(self, target: discord.Member, jail_role: discord.Role) -> list[discord.Role]:
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to jail {target}. {e}")
|
||||
await ctx.send(f"Failed to jail {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
try:
|
||||
if target_roles:
|
||||
await target.remove_roles(*target_roles, reason=flags.reason, atomic=False)
|
||||
await target.add_roles(jail_role, reason=flags.reason)
|
||||
|
||||
except (discord.Forbidden, discord.HTTPException) as e:
|
||||
logger.error(f"Failed to jail {target}. {e}")
|
||||
await ctx.send(f"Failed to jail {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "jailed")
|
||||
await self.handle_case_response(ctx, CaseType.JAIL, case.case_id, flags.reason, target)
|
||||
|
||||
def _get_manageable_roles(
|
||||
self,
|
||||
target: discord.Member,
|
||||
jail_role: discord.Role,
|
||||
) -> list[discord.Role]:
|
||||
"""
|
||||
Get the roles that can be managed by the bot.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : discord.Member
|
||||
The member to jail.
|
||||
jail_role : discord.Role
|
||||
The jail role.
|
||||
|
||||
Returns
|
||||
-------
|
||||
list[discord.Role]
|
||||
The roles that can be managed by the bot.
|
||||
"""
|
||||
|
||||
return [
|
||||
role
|
||||
for role in target.roles
|
||||
|
@ -182,70 +128,6 @@ class Jail(ModerationCogBase):
|
|||
and role.is_assignable()
|
||||
]
|
||||
|
||||
async def _jail_user(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
target: discord.Member,
|
||||
flags: JailFlags,
|
||||
jail_role: discord.Role,
|
||||
target_roles: list[discord.Role],
|
||||
) -> None:
|
||||
try:
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "jailed")
|
||||
|
||||
if target_roles:
|
||||
await target.remove_roles(*target_roles, reason=flags.reason, atomic=False)
|
||||
await target.add_roles(jail_role, reason=flags.reason)
|
||||
|
||||
except (discord.Forbidden, discord.HTTPException) as e:
|
||||
logger.error(f"Failed to jail {target}. {e}")
|
||||
await ctx.send(f"Failed to jail {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
fields = [
|
||||
("Moderator", f"__{ctx.author}__\n`{ctx.author.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
embed = await self._create_case_embed(ctx, case, action, fields, target)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
|
||||
async def _create_case_embed(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
fields: list[tuple[str, str, bool]],
|
||||
target: discord.Member | discord.User,
|
||||
) -> discord.Embed:
|
||||
title = f"Case #{case.case_number} ({case.case_type}) {action}" if case else f"Case {action} ({CaseType.JAIL})"
|
||||
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=title,
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
return embed
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
await bot.add_cog(Jail(bot))
|
||||
|
|
|
@ -3,9 +3,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import KickFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -75,48 +73,7 @@ class Kick(ModerationCogBase):
|
|||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} {action} ({case.case_type})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case {action} ({CaseType.KICK})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
await self.handle_case_response(ctx, CaseType.KICK, case.case_id, flags.reason, target)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
|
@ -3,10 +3,8 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.database.controllers.case import CaseController
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import SnippetBanFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -20,7 +18,7 @@ class SnippetBan(ModerationCogBase):
|
|||
@commands.hybrid_command(
|
||||
name="snippetban",
|
||||
aliases=["sb"],
|
||||
usage="snippetban [target]",
|
||||
usage="snippetban [target] [reason] <silent>",
|
||||
)
|
||||
@commands.guild_only()
|
||||
@checks.has_pl(3)
|
||||
|
@ -49,60 +47,25 @@ class SnippetBan(ModerationCogBase):
|
|||
return
|
||||
|
||||
if await self.is_snippetbanned(ctx.guild.id, target.id):
|
||||
await ctx.send("User is already snippet banned.", delete_after=30)
|
||||
await ctx.send("User is already snippet banned.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
case = await self.db.case.insert_case(
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.SNIPPETBAN,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "Snippet banned")
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} ({case.case_type}) {action}",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case {action} ({CaseType.SNIPPETBAN})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
try:
|
||||
case = await self.db.case.insert_case(
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.SNIPPETBAN,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to ban {target}. {e}")
|
||||
await ctx.send(f"Failed to ban {target}. {e}", delete_after=30)
|
||||
return
|
||||
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "snippet banned")
|
||||
await self.handle_case_response(ctx, CaseType.SNIPPETBAN, case.case_id, flags.reason, target)
|
||||
|
||||
async def is_snippetbanned(self, guild_id: int, user_id: int) -> bool:
|
||||
"""
|
||||
|
|
|
@ -3,10 +3,8 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.database.controllers.case import CaseController
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import SnippetUnbanFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -20,7 +18,7 @@ class SnippetUnban(ModerationCogBase):
|
|||
@commands.hybrid_command(
|
||||
name="snippetunban",
|
||||
aliases=["sub"],
|
||||
usage="snippetunban [target]",
|
||||
usage="snippetunban [target] [reason] <silent>",
|
||||
)
|
||||
@commands.guild_only()
|
||||
@checks.has_pl(3)
|
||||
|
@ -48,62 +46,26 @@ class SnippetUnban(ModerationCogBase):
|
|||
logger.warning("Snippet ban command used outside of a guild context.")
|
||||
return
|
||||
|
||||
# Check if the user is already snippet banned
|
||||
if not await self.is_snippetbanned(ctx.guild.id, target.id):
|
||||
await ctx.send("User is not snippet banned.", delete_after=30)
|
||||
await ctx.send("User is not snippet banned.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
case = await self.db.case.insert_case(
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.SNIPPETUNBAN,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "Snippet unbanned")
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} ({case.case_type}) {action}",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case {action} ({CaseType.SNIPPETUNBAN})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
try:
|
||||
case = await self.db.case.insert_case(
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.SNIPPETUNBAN,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to snippet unban {target}. {e}")
|
||||
await ctx.send(f"Failed to snippet unban {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "snippet unbanned")
|
||||
await self.handle_case_response(ctx, CaseType.SNIPPETUNBAN, case.case_id, flags.reason, target)
|
||||
|
||||
async def is_snippetbanned(self, guild_id: int, user_id: int) -> bool:
|
||||
"""
|
||||
|
|
|
@ -6,9 +6,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import TimeoutFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -106,7 +104,6 @@ class Timeout(ModerationCogBase):
|
|||
duration = parse_time_string(flags.duration)
|
||||
|
||||
try:
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, f"timed out for {flags.duration}")
|
||||
await target.timeout(duration, reason=flags.reason)
|
||||
|
||||
except discord.DiscordException as e:
|
||||
|
@ -122,49 +119,8 @@ class Timeout(ModerationCogBase):
|
|||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.handle_case_response(ctx, flags, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
flags: TimeoutFlags,
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} {action} ({flags.duration} {case.case_type})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #0 {action} ({flags.duration} {CaseType.TIMEOUT})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, f"timed out for {flags.duration}")
|
||||
await self.handle_case_response(ctx, CaseType.TIMEOUT, case.case_id, flags.reason, target, flags.duration)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
|
@ -3,9 +3,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import UnbanFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -35,8 +33,6 @@ class Unban(ModerationCogBase):
|
|||
----------
|
||||
ctx : commands.Context[commands.Bot]
|
||||
The context object for the command.
|
||||
target : discord.Member
|
||||
The member to unban.
|
||||
flags : UnbanFlags
|
||||
The flags for the command (username_or_id: str, reason: str).
|
||||
|
||||
|
@ -76,48 +72,7 @@ class Unban(ModerationCogBase):
|
|||
case_reason=flags.reason,
|
||||
)
|
||||
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, user)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} ({case.case_type}) {action}",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case {action} ({CaseType.UNBAN})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
await self.handle_case_response(ctx, CaseType.UNBAN, case.case_id, flags.reason, user)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
|
@ -3,9 +3,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import UnjailFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -22,7 +20,7 @@ class Unjail(ModerationCogBase):
|
|||
)
|
||||
@commands.guild_only()
|
||||
@checks.has_pl(2)
|
||||
async def unjail(
|
||||
async def unjail( # noqa: PLR0911
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
target: discord.Member,
|
||||
|
@ -51,151 +49,55 @@ class Unjail(ModerationCogBase):
|
|||
if not await self.check_conditions(ctx, target, moderator, "unjail"):
|
||||
return
|
||||
|
||||
jail_role = await self._get_jail_role(ctx)
|
||||
if not jail_role:
|
||||
jail_role_id = await self.config.get_jail_role_id(ctx.guild.id)
|
||||
jail_role = ctx.guild.get_role(jail_role_id) if jail_role_id else None
|
||||
|
||||
jail_channel_id = await self.config.get_jail_channel_id(ctx.guild.id)
|
||||
|
||||
if not all([jail_role_id, jail_role, jail_channel_id]):
|
||||
error_msgs = {
|
||||
not jail_role_id: "No jail role has been set up for this server.",
|
||||
not jail_role: "The jail role has been deleted.",
|
||||
not jail_channel_id: "No jail channel has been set up for this server.",
|
||||
}
|
||||
|
||||
for condition, msg in error_msgs.items():
|
||||
if condition:
|
||||
await ctx.send(msg, delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
if jail_role not in target.roles:
|
||||
await ctx.send("The member is not jailed.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
if not await self._check_jail_channel(ctx):
|
||||
return
|
||||
|
||||
case = await self.db.case.get_last_jail_case_by_target_id(ctx.guild.id, target.id)
|
||||
if not case:
|
||||
await ctx.send("No jail case found for this member.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
await self._unjail_user(ctx, target, jail_role, case, flags.reason)
|
||||
|
||||
unjail_case = await self._insert_unjail_case(ctx, target, flags.reason)
|
||||
|
||||
await self.handle_case_response(ctx, unjail_case, "created", flags.reason, target)
|
||||
|
||||
async def _get_jail_role(self, ctx: commands.Context[commands.Bot]) -> discord.Role | None:
|
||||
if ctx.guild is None:
|
||||
logger.warning("Unjail command used outside of a guild context.")
|
||||
return None
|
||||
|
||||
jail_role_id = await self.config.get_jail_role_id(ctx.guild.id)
|
||||
if not jail_role_id:
|
||||
await ctx.send("No jail role has been set up for this server.", delete_after=30, ephemeral=True)
|
||||
return None
|
||||
|
||||
jail_role = ctx.guild.get_role(jail_role_id)
|
||||
if not jail_role:
|
||||
await ctx.send("The jail role has been deleted.", delete_after=30, ephemeral=True)
|
||||
return None
|
||||
|
||||
return jail_role
|
||||
|
||||
async def _check_jail_channel(self, ctx: commands.Context[commands.Bot]) -> bool:
|
||||
if ctx.guild is None:
|
||||
logger.warning("Unjail command used outside of a guild context.")
|
||||
return False
|
||||
|
||||
jail_channel_id = await self.config.get_jail_channel_id(ctx.guild.id)
|
||||
if not jail_channel_id:
|
||||
await ctx.send("No jail channel has been set up for this server.", delete_after=30, ephemeral=True)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def _unjail_user(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
target: discord.Member,
|
||||
jail_role: discord.Role,
|
||||
case: Case,
|
||||
reason: str,
|
||||
) -> None:
|
||||
if ctx.guild is None:
|
||||
logger.warning("Unjail command used outside of a guild context.")
|
||||
return
|
||||
|
||||
try:
|
||||
await target.remove_roles(jail_role, reason=reason)
|
||||
|
||||
previous_roles = [await commands.RoleConverter().convert(ctx, str(role)) for role in case.case_target_roles]
|
||||
|
||||
if previous_roles:
|
||||
await target.add_roles(*previous_roles, reason=reason, atomic=False)
|
||||
await target.remove_roles(jail_role, reason=flags.reason, atomic=True)
|
||||
await target.add_roles(*previous_roles, reason=flags.reason, atomic=True)
|
||||
else:
|
||||
await ctx.send("No previous roles found for the member.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
except (discord.Forbidden, discord.HTTPException) as e:
|
||||
logger.error(f"Failed to unjail member {target}. {e}")
|
||||
await ctx.send(f"Failed to unjail member {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
async def _insert_unjail_case(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
target: discord.Member,
|
||||
reason: str,
|
||||
) -> Case | None:
|
||||
if not ctx.guild:
|
||||
logger.warning("Unjail command used outside of a guild context.")
|
||||
return None
|
||||
|
||||
try:
|
||||
return await self.db.case.insert_case(
|
||||
guild_id=ctx.guild.id,
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.UNJAIL,
|
||||
case_reason=reason,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to insert unjail case for {target}. {e}")
|
||||
await ctx.send(f"Failed to insert unjail case for {target}. {e}", delete_after=30, ephemeral=True)
|
||||
return None
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
fields = [
|
||||
("Moderator", f"__{ctx.author}__\n`{ctx.author.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
embed = await self._create_case_embed(ctx, case, action, fields, target)
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
|
||||
async def _create_case_embed(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
fields: list[tuple[str, str, bool]],
|
||||
target: discord.Member | discord.User,
|
||||
) -> discord.Embed:
|
||||
title = (
|
||||
f"Case #{case.case_number} ({case.case_type}) {action}" if case else f"Case {action} ({CaseType.UNJAIL})"
|
||||
unjail_case = await self.db.case.insert_case(
|
||||
guild_id=ctx.guild.id,
|
||||
case_target_id=target.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.UNJAIL,
|
||||
case_reason=flags.reason,
|
||||
)
|
||||
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=title,
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
return embed
|
||||
await self.handle_case_response(ctx, CaseType.UNJAIL, unjail_case.case_id, flags.reason, target)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
|
@ -3,9 +3,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import UntimeoutFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -59,7 +57,6 @@ class Untimeout(ModerationCogBase):
|
|||
await ctx.send(f"{target} is not currently timed out.", delete_after=30, ephemeral=True)
|
||||
|
||||
try:
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "untimed out")
|
||||
await target.timeout(None, reason=flags.reason)
|
||||
except discord.DiscordException as e:
|
||||
await ctx.send(f"Failed to untimeout {target}. {e}", delete_after=30, ephemeral=True)
|
||||
|
@ -74,49 +71,8 @@ class Untimeout(ModerationCogBase):
|
|||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.handle_case_response(ctx, flags, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
flags: UntimeoutFlags,
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} {action} ({case.case_type})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #0 {action} ({CaseType.UNTIMEOUT})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
await self.send_dm(ctx, flags.silent, target, flags.reason, "untimed out")
|
||||
await self.handle_case_response(ctx, CaseType.UNTIMEOUT, case.case_id, flags.reason, target)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
|
@ -3,9 +3,7 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from prisma.models import Case
|
||||
from tux.utils import checks
|
||||
from tux.utils.constants import Constants as CONST
|
||||
from tux.utils.flags import WarnFlags
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
@ -61,48 +59,7 @@ class Warn(ModerationCogBase):
|
|||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
await self.handle_case_response(ctx, case, "created", flags.reason, target)
|
||||
|
||||
async def handle_case_response(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
case: Case | None,
|
||||
action: str,
|
||||
reason: str,
|
||||
target: discord.Member | discord.User,
|
||||
previous_reason: str | None = None,
|
||||
) -> None:
|
||||
moderator = ctx.author
|
||||
|
||||
fields = [
|
||||
("Moderator", f"__{moderator}__\n`{moderator.id}`", True),
|
||||
("Target", f"__{target}__\n`{target.id}`", True),
|
||||
("Reason", f"> {reason}", False),
|
||||
]
|
||||
|
||||
if previous_reason:
|
||||
fields.append(("Previous Reason", f"> {previous_reason}", False))
|
||||
|
||||
if case is not None:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case #{case.case_number} ({case.case_type}) {action}",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
embed.set_thumbnail(url=target.avatar)
|
||||
else:
|
||||
embed = await self.create_embed(
|
||||
ctx,
|
||||
title=f"Case {action} ({CaseType.WARN})",
|
||||
fields=fields,
|
||||
color=CONST.EMBED_COLORS["CASE"],
|
||||
icon_url=CONST.EMBED_ICONS["ACTIVE_CASE"],
|
||||
)
|
||||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
await self.handle_case_response(ctx, CaseType.WARN, case.case_id, flags.reason, target)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
|
|
Loading…
Reference in a new issue