1
Fork 0
mirror of https://github.com/allthingslinux/tux.git synced 2024-10-03 00:53:12 +00:00

docs(ban.py, kick.py, purge.py, report.py): add docstrings to methods for better code understanding

refactor(purge.py): remove unused imports and methods, use EmbedCreator for creating embeds
refactor(report.py): rename ConfirmModal to ReportModal for better semantics
feat(purge.py): add error handling for non-text channels and invalid number of messages
feat(report.py): add docstring to report method, improve report submission process

docs(slowmode.py, timeout.py, unban.py): add docstrings to methods for better code readability and understanding
refactor(slowmode.py): change default slowmode delay from 5 to 4 seconds for better user experience
style(slowmode.py, timeout.py, unban.py): add line breaks for better code readability
fix(unban.py): remove redundant logging of unban command usage, logging is now handled after successful unbanning

docs(warn.py): add docstrings to methods for better code readability and understanding
refactor(warn.py): remove error handling from create_infraction method to improve separation of concerns
This commit is contained in:
kzndotsh 2024-05-01 04:12:07 +00:00
parent 6d7821d336
commit 1a8c4a4801
8 changed files with 383 additions and 103 deletions

View file

@ -21,6 +21,26 @@ class Ban(commands.Cog):
infraction_type: InfractionType, infraction_type: InfractionType,
infraction_reason: str, infraction_reason: str,
) -> Infractions | None: ) -> Infractions | None:
"""
Inserts a new infraction into the database.
Parameters
----------
user_id : int
The ID of the user for whom the infraction is created.
moderator_id : int
The ID of the moderator who created the infraction.
infraction_type : InfractionType
The type of the infraction.
infraction_reason : str
The reason for the infraction.
Returns
-------
Infractions | None
The newly created infraction if successful, otherwise None.
"""
try: try:
return await self.db_controller.infractions.create_infraction( return await self.db_controller.infractions.create_infraction(
user_id=user_id, user_id=user_id,
@ -34,6 +54,15 @@ class Ban(commands.Cog):
return None return None
async def get_or_create_user(self, member: discord.Member) -> None: async def get_or_create_user(self, member: discord.Member) -> None:
"""
Retrieves or creates a user in the database.
Parameters
----------
member : discord.Member
The member to retrieve or create in the database.
"""
user = await self.db_controller.users.get_user_by_id(member.id) user = await self.db_controller.users.get_user_by_id(member.id)
if not user: if not user:
@ -48,6 +77,15 @@ class Ban(commands.Cog):
) )
async def get_or_create_moderator(self, interaction: discord.Interaction) -> None: async def get_or_create_moderator(self, interaction: discord.Interaction) -> None:
"""
Retrieves or creates a moderator in the database.
Parameters
----------
interaction : discord.Interaction
The interaction to retrieve or create the moderator from.
"""
moderator = await self.db_controller.users.get_user_by_id(interaction.user.id) moderator = await self.db_controller.users.get_user_by_id(interaction.user.id)
moderator_context = None moderator_context = None
if interaction.guild: if interaction.guild:
@ -70,6 +108,19 @@ class Ban(commands.Cog):
async def ban( async def ban(
self, interaction: discord.Interaction, member: discord.Member, reason: str | None = None self, interaction: discord.Interaction, member: discord.Member, reason: str | None = None
) -> None: ) -> None:
"""
Issues a ban to a member of the server.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
member : discord.Member
The member to ban.
reason : str | None, optional
The reason for issuing the ban, by default None.
"""
reason = reason or "No reason provided" reason = reason or "No reason provided"
await self.get_or_create_user(member) await self.get_or_create_user(member)

View file

@ -121,6 +121,26 @@ class Kick(commands.Cog):
infraction_type: InfractionType, infraction_type: InfractionType,
infraction_reason: str, infraction_reason: str,
) -> Infractions | None: ) -> Infractions | None:
"""
Inserts an infraction into the database.
Parameters
----------
user_id : int
The user ID who is being infracted.
moderator_id : int
The moderator ID who is creating the infraction.
infraction_type : InfractionType
The type of infraction.
infraction_reason : str
The reason for the infraction.
Returns
-------
Infractions | None
The newly created infraction if successful, None otherwise.
"""
try: try:
return await self.db_controller.infractions.create_infraction( return await self.db_controller.infractions.create_infraction(
user_id=user_id, user_id=user_id,
@ -134,6 +154,15 @@ class Kick(commands.Cog):
return None return None
async def get_or_create_user(self, member: discord.Member) -> None: async def get_or_create_user(self, member: discord.Member) -> None:
"""
Retrieves or creates a user in the database.
Parameters
----------
member : discord.Member
The member to retrieve or create in the database.
"""
user = await self.db_controller.users.get_user_by_id(member.id) user = await self.db_controller.users.get_user_by_id(member.id)
if not user: if not user:
@ -148,6 +177,15 @@ class Kick(commands.Cog):
) )
async def get_or_create_moderator(self, interaction: discord.Interaction) -> None: async def get_or_create_moderator(self, interaction: discord.Interaction) -> None:
"""
Retrieves or creates a moderator in the database.
Parameters
----------
interaction : discord.Interaction
The interaction to retrieve or create in the database.
"""
moderator = await self.db_controller.users.get_user_by_id(interaction.user.id) moderator = await self.db_controller.users.get_user_by_id(interaction.user.id)
moderator_context = None moderator_context = None
if interaction.guild: if interaction.guild:
@ -170,6 +208,19 @@ class Kick(commands.Cog):
async def kick( async def kick(
self, interaction: discord.Interaction, member: discord.Member, reason: str | None = None self, interaction: discord.Interaction, member: discord.Member, reason: str | None = None
) -> None: ) -> None:
"""
Issues a kick to a member of the server.
Parameters
----------
interaction : discord.Interaction
The interaction context for this command.
member : discord.Member
The Discord member to be kicked.
reason : str | None, optional
The reason for kicking the member, by default None.
"""
reason = reason or "No reason provided" reason = reason or "No reason provided"
await self.get_or_create_user(member) await self.get_or_create_user(member)

View file

@ -1,51 +1,16 @@
import json
import os
from pathlib import Path
import discord import discord
from discord import app_commands from discord import app_commands
from discord.ext import commands from discord.ext import commands
from loguru import logger from loguru import logger
from tux.utils.constants import Constants as CONST from tux.utils.embeds import EmbedCreator
config_file = Path("config/settings.json")
config = json.loads(config_file.read_text())
role_ids = CONST.USER_IDS
testing_role_id = role_ids["TESTING"] if os.getenv("STAGING") == "True" else "foobar"
class Purge(commands.Cog): class Purge(commands.Cog):
def __init__(self, bot: commands.Bot) -> None: def __init__(self, bot: commands.Bot) -> None:
self.bot = bot self.bot = bot
async def send_embed( @app_commands.checks.has_any_role("Root", "Admin", "Sr. Mod", "Mod")
self,
interaction: discord.Interaction,
title: str,
description: str,
color: discord.Colour,
error_info: str | None = None,
) -> None:
embed = discord.Embed(
title=title, description=description, color=color, timestamp=interaction.created_at
)
if error_info:
embed.add_field(name="Error Details", value=f"`{error_info}`", inline=False)
embed.set_footer(
text=f"Requested by {interaction.user.display_name}",
icon_url=interaction.user.display_avatar.url,
)
await interaction.followup.send(embed=embed) # Send the embed to the interaction
@app_commands.checks.has_any_role(
role_ids["ADMIN"],
role_ids["OWNER"],
role_ids["MOD"],
role_ids["JR MOD"],
*testing_role_id,
)
@app_commands.command( @app_commands.command(
name="purge", description="Deletes a set number of messages in a channel." name="purge", description="Deletes a set number of messages in a channel."
) )
@ -53,19 +18,30 @@ class Purge(commands.Cog):
async def purge_messages( async def purge_messages(
self, interaction: discord.Interaction, number_messages: int = 10 self, interaction: discord.Interaction, number_messages: int = 10
) -> None: ) -> None:
"""
Deletes a set number of messages in a channel.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
number_messages : int, optional
The number of messages to be purged, by default 10.
"""
if not interaction.channel or interaction.channel.type != discord.ChannelType.text: if not interaction.channel or interaction.channel.type != discord.ChannelType.text:
return None return await interaction.response.send_message(
"This command can only be used in text channels.", ephemeral=True
)
if number_messages <= 0: if number_messages <= 0:
await interaction.response.defer(ephemeral=True) await interaction.response.defer(ephemeral=True)
return await self.send_embed( embed = EmbedCreator.create_error_embed(
interaction, title="Invalid Number",
"Error", description="Please provide a number greater than 0.",
"The number of messages to purge must be greater than 0.",
discord.Colour.red(),
) )
embed = discord.Embed return await interaction.followup.send(embed=embed, ephemeral=True)
try: try:
await interaction.response.defer(ephemeral=True) await interaction.response.defer(ephemeral=True)
@ -74,33 +50,28 @@ class Purge(commands.Cog):
deleted = await interaction.channel.purge(limit=number_messages) deleted = await interaction.channel.purge(limit=number_messages)
description = f"Deleted {len(deleted)} messages in {interaction.channel.mention}" description = f"Deleted {len(deleted)} messages in {interaction.channel.mention}"
await self.send_embed(interaction, "Success!", description, discord.Colour.blue()) embed = EmbedCreator.create_success_embed(
title="Purge Successful",
description=description,
interaction=interaction,
)
logger.info( logger.info(
f"{interaction.user} purged {len(deleted)} messages from {interaction.channel.name}" f"{interaction.user} purged {len(deleted)} messages from {interaction.channel.name}"
) )
except discord.Forbidden as e: await interaction.edit_original_response(embed=embed)
logger.error(f"Failed to purge messages in {interaction.channel.name}: {e}")
await self.send_embed( except Exception as error:
interaction, embed = EmbedCreator.create_error_embed(
"Permission Denied", title="Purge Failed",
"Failed to purge messages due to insufficient permissions.", description=f"Failed to purge messages in {interaction.channel.mention}.",
discord.Colour.red(), interaction=interaction,
error_info=str(e),
) )
embed.timestamp = interaction.created_at # Add timestamp to the error embed
except discord.HTTPException as e: logger.error(f"Failed to purge messages in {interaction.channel.name}. Error: {error}")
logger.error(f"Failed to purge messages in {interaction.channel.name}: {e}")
await self.send_embed( await interaction.edit_original_response(embed=embed)
interaction,
"Error",
f"An error occurred while purging messages: {e}",
discord.Colour.red(),
)
async def setup(bot: commands.Bot) -> None: async def setup(bot: commands.Bot) -> None:

View file

@ -6,7 +6,7 @@ from tux.utils.constants import Constants as CONST
from tux.utils.embeds import EmbedCreator from tux.utils.embeds import EmbedCreator
class ConfirmModal(discord.ui.Modal): class ReportModal(discord.ui.Modal):
def __init__(self, *, title: str = "Submit an anonymous report", bot: commands.Bot) -> None: def __init__(self, *, title: str = "Submit an anonymous report", bot: commands.Bot) -> None:
super().__init__(title=title) super().__init__(title=title)
self.bot = bot self.bot = bot
@ -29,15 +29,28 @@ class ConfirmModal(discord.ui.Modal):
) )
async def on_submit(self, interaction: discord.Interaction) -> None: async def on_submit(self, interaction: discord.Interaction) -> None:
"""
Sends the report to the moderation team.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
"""
embed = EmbedCreator.create_log_embed( embed = EmbedCreator.create_log_embed(
title=(f"Anonymous report for {self.short.value}"), # type: ignore title=(f"Anonymous report for {self.short.value}"), # type: ignore
description=self.long.value, # type: ignore description=self.long.value, # type: ignore
interaction=None,
) )
# Get the channel to send the report to
channel = self.bot.get_channel(self.channel) or await self.bot.fetch_channel(self.channel) channel = self.bot.get_channel(self.channel) or await self.bot.fetch_channel(self.channel)
# Create a webhook in the channel to send the report
webhook: discord.Webhook | None = None webhook: discord.Webhook | None = None
# Check if the channel is a text channel
if isinstance(channel, discord.TextChannel): if isinstance(channel, discord.TextChannel):
webhook = await channel.create_webhook( webhook = await channel.create_webhook(
name="Tux", name="Tux",
@ -45,9 +58,12 @@ class ConfirmModal(discord.ui.Modal):
) )
if webhook: if webhook:
# Send the report to the webhook
await webhook.send(embed=embed) await webhook.send(embed=embed)
# Delete the webhook after sending the report
await webhook.delete(reason="Report sent") await webhook.delete(reason="Report sent")
# Send a confirmation message to the user
await interaction.response.send_message( await interaction.response.send_message(
"The report has been sent to the moderation team. Thank you for your help!", "The report has been sent to the moderation team. Thank you for your help!",
ephemeral=True, ephemeral=True,
@ -60,7 +76,16 @@ class Report(commands.Cog):
@app_commands.command(name="report", description="Report a user or issue anonymously") @app_commands.command(name="report", description="Report a user or issue anonymously")
async def report(self, interaction: discord.Interaction) -> None: async def report(self, interaction: discord.Interaction) -> None:
modal = ConfirmModal(bot=self.bot) """
Opens the report modal for users to submit an anonymous report.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
"""
modal = ReportModal(bot=self.bot)
await interaction.response.send_modal(modal) await interaction.response.send_modal(modal)

View file

@ -12,13 +12,26 @@ class Slowmode(commands.Cog):
@app_commands.checks.has_any_role("Root", "Admin", "Sr. Mod", "Mod", "Jr. Mod") @app_commands.checks.has_any_role("Root", "Admin", "Sr. Mod", "Mod", "Jr. Mod")
@app_commands.command(name="slowmode", description="Sets slowmode for the current channel.") @app_commands.command(name="slowmode", description="Sets slowmode for the current channel.")
@app_commands.describe(delay="The slowmode time in seconds, max is 21600, default is 5") @app_commands.describe(delay="The slowmode time in seconds, max is 21600, default is 4")
async def set_slowmode( async def set_slowmode(
self, self,
interaction: discord.Interaction, interaction: discord.Interaction,
delay: int = 5, delay: int = 4,
channel: discord.TextChannel | discord.ForumChannel | discord.Thread | None = None, channel: discord.TextChannel | discord.ForumChannel | discord.Thread | None = None,
) -> None: ) -> None:
"""
Sets slowmode for the current channel.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
delay : int, optional
The slowmode time in seconds, max is 21600, by default 4
channel : discord.TextChannel | discord.ForumChannel | discord.Thread | None, optional
The channel to set slowmode in, by default None
"""
# Get the target channel (default to the current channel if not provided) # Get the target channel (default to the current channel if not provided)
target_channel = channel or interaction.channel target_channel = channel or interaction.channel
@ -33,7 +46,9 @@ class Slowmode(commands.Cog):
description="Failed to set slowmode. Please provide a valid channel.", description="Failed to set slowmode. Please provide a valid channel.",
interaction=interaction, interaction=interaction,
) )
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
logger.error(f"Failed to set slowmode. Invalid channel: {channel}") logger.error(f"Failed to set slowmode. Invalid channel: {channel}")
# Check if the delay is within the valid range # Check if the delay is within the valid range
@ -43,19 +58,24 @@ class Slowmode(commands.Cog):
description="The slowmode delay must be between 0 and 21600 seconds.", description="The slowmode delay must be between 0 and 21600 seconds.",
interaction=interaction, interaction=interaction,
) )
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
logger.error(f"Failed to set slowmode. Invalid delay: {delay}") logger.error(f"Failed to set slowmode. Invalid delay: {delay}")
try: try:
# If the target channel is a valid channel, set the slowmode # If the target channel is a valid channel, set the slowmode
if isinstance(target_channel, discord.TextChannel | discord.ForumChannel): if isinstance(target_channel, discord.TextChannel | discord.ForumChannel):
await target_channel.edit(slowmode_delay=delay) await target_channel.edit(slowmode_delay=delay)
embed = EmbedCreator.create_info_embed( embed = EmbedCreator.create_info_embed(
title="Slowmode Set", title="Slowmode Set",
description=f"Slowmode set to {delay} seconds in {target_channel.mention}.", description=f"Slowmode set to {delay} seconds in {target_channel.mention}.",
interaction=interaction, interaction=interaction,
) )
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
logger.info(f"Slowmode set to {delay} seconds in {target_channel.mention}.") logger.info(f"Slowmode set to {delay} seconds in {target_channel.mention}.")
else: else:
@ -64,7 +84,9 @@ class Slowmode(commands.Cog):
description="Failed to set slowmode. Please provide a valid channel.", description="Failed to set slowmode. Please provide a valid channel.",
interaction=interaction, interaction=interaction,
) )
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
logger.error(f"Failed to set slowmode. Invalid channel: {channel}") logger.error(f"Failed to set slowmode. Invalid channel: {channel}")
except Exception as error: except Exception as error:
@ -75,6 +97,7 @@ class Slowmode(commands.Cog):
) )
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
logger.error(f"Failed to set slowmode. Error: {error}") logger.error(f"Failed to set slowmode. Error: {error}")

View file

@ -25,20 +25,46 @@ class Timeout(commands.Cog):
infraction_reason: str, infraction_reason: str,
expires_at: datetime.datetime | None = None, expires_at: datetime.datetime | None = None,
) -> Infractions | None: ) -> Infractions | None:
try: """
return await self.db_controller.infractions.create_infraction( Inserts an infraction into the database.
user_id=user_id,
moderator_id=moderator_id,
infraction_type=infraction_type,
infraction_reason=infraction_reason,
expires_at=expires_at,
)
except Exception as error: Parameters
logger.error(f"Failed to create infraction for user {user_id}. Error: {error}") ----------
return None user_id : int
The ID of the user to issue the infraction to.
moderator_id : int
The ID of the moderator issuing the infraction.
infraction_type : InfractionType
The type of infraction to issue.
infraction_reason : str
The reason for issuing the infraction.
expires_at : datetime.datetime | None, optional
The expiration date for the infraction, by default None.
Returns
-------
Infractions | None
The infraction that was created, or None if an error occurred.
"""
return await self.db_controller.infractions.create_infraction(
user_id=user_id,
moderator_id=moderator_id,
infraction_type=infraction_type,
infraction_reason=infraction_reason,
expires_at=expires_at,
)
async def get_or_create_user(self, member: discord.Member) -> None: async def get_or_create_user(self, member: discord.Member) -> None:
"""
Retrieves a user from the database or creates a new user if not found.
Parameters
----------
member : discord.Member
The member to retrieve or create in the database.
"""
user = await self.db_controller.users.get_user_by_id(member.id) user = await self.db_controller.users.get_user_by_id(member.id)
if not user: if not user:
@ -53,6 +79,15 @@ class Timeout(commands.Cog):
) )
async def get_or_create_moderator(self, interaction: discord.Interaction) -> None: async def get_or_create_moderator(self, interaction: discord.Interaction) -> None:
"""
Retrieves a moderator from the database or creates a new moderator if not found.
Parameters
----------
interaction : discord.Interaction
The interaction to retrieve or create in the database.
"""
moderator = await self.db_controller.users.get_user_by_id(interaction.user.id) moderator = await self.db_controller.users.get_user_by_id(interaction.user.id)
moderator_context = None moderator_context = None
if interaction.guild: if interaction.guild:
@ -89,6 +124,27 @@ class Timeout(commands.Cog):
minutes: int = 0, minutes: int = 0,
seconds: int = 0, seconds: int = 0,
) -> None: ) -> None:
"""
Issues a timeout to a member of the server.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
member : discord.Member
The member to issue the timeout to.
reason : str | None, optional
The reason for issuing the timeout, by default None
days : int, optional
The number of days for the timeout, by default 0
hours : int, optional
The number of hours for the timeout, by default 0
minutes : int, optional
The number of minutes for the timeout, by default 0
seconds : int, optional
The number of seconds for the timeout, by default 0
"""
reason = reason or "No reason provided" reason = reason or "No reason provided"
duration = datetime.timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds) duration = datetime.timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
@ -124,6 +180,7 @@ class Timeout(commands.Cog):
except Exception as error: except Exception as error:
msg = f"Failed to issue timeout to {member.display_name}." msg = f"Failed to issue timeout to {member.display_name}."
embed = EmbedCreator.create_error_embed( embed = EmbedCreator.create_error_embed(
title="Timeout Failed", title="Timeout Failed",
description=msg, description=msg,

View file

@ -21,19 +21,43 @@ class Unban(commands.Cog):
infraction_type: InfractionType, infraction_type: InfractionType,
infraction_reason: str, infraction_reason: str,
) -> Infractions | None: ) -> Infractions | None:
try: """
return await self.db_controller.infractions.create_infraction( Inserts an infraction into the database.
user_id=user_id,
moderator_id=moderator_id,
infraction_type=infraction_type,
infraction_reason=infraction_reason,
)
except Exception as error: Parameters
logger.error(f"Failed to create infraction for user {user_id}. Error: {error}") ----------
return None user_id : int
The ID of the user to issue the infraction to.
moderator_id : int
The ID of the moderator issuing the infraction.
infraction_type : InfractionType
The type of infraction to issue.
infraction_reason : str
The reason for issuing the infraction.
Returns
-------
Infractions | None
The infraction that was created, or None if an error occurred.
"""
return await self.db_controller.infractions.create_infraction(
user_id=user_id,
moderator_id=moderator_id,
infraction_type=infraction_type,
infraction_reason=infraction_reason,
)
async def get_or_create_user(self, member: discord.User) -> None: async def get_or_create_user(self, member: discord.User) -> None:
"""
Retrieves a user from the database or creates a new user if not found.
Parameters
----------
member : discord.User
The user to retrieve or create in the database.
"""
user = await self.db_controller.users.get_user_by_id(member.id) user = await self.db_controller.users.get_user_by_id(member.id)
if not user: if not user:
@ -48,6 +72,15 @@ class Unban(commands.Cog):
) )
async def get_or_create_moderator(self, interaction: discord.Interaction) -> None: async def get_or_create_moderator(self, interaction: discord.Interaction) -> None:
"""
Retrieves a moderator from the database or creates a new moderator if not found.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
"""
moderator = await self.db_controller.users.get_user_by_id(interaction.user.id) moderator = await self.db_controller.users.get_user_by_id(interaction.user.id)
moderator_context = None moderator_context = None
if interaction.guild: if interaction.guild:
@ -72,15 +105,37 @@ class Unban(commands.Cog):
async def unban( async def unban(
self, interaction: discord.Interaction, username_or_id: str, reason: str | None = None self, interaction: discord.Interaction, username_or_id: str, reason: str | None = None
) -> None: ) -> None:
"""
Unbans a member from the server.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
username_or_id : str
The username or ID of the member to unban.
reason : str | None, optional
The reason for unbanning the member, by default None
Raises:
-------
ValueError
If the user is not found in the ban list.
"""
if interaction.guild is None: if interaction.guild is None:
return return
# Get the list of banned users in the guild
banned_users = [ban.user async for ban in interaction.guild.bans()] banned_users = [ban.user async for ban in interaction.guild.bans()]
try: try:
# If the username_or_id is an integer, search for the user by ID
user_id = int(username_or_id) user_id = int(username_or_id)
user_to_unban = discord.utils.get(banned_users, id=user_id) user_to_unban = discord.utils.get(banned_users, id=user_id)
except ValueError: except ValueError:
# If the username_or_id is not an integer, search for the user by username
user_to_unban = discord.utils.find(lambda u: u.name == username_or_id, banned_users) user_to_unban = discord.utils.find(lambda u: u.name == username_or_id, banned_users)
if user_to_unban is None: if user_to_unban is None:
@ -89,10 +144,6 @@ class Unban(commands.Cog):
) )
return return
logger.info(
f"{interaction.user} used the unban command in {interaction.channel} to unban user {user_to_unban.display_name}."
)
try: try:
await interaction.guild.unban(user_to_unban, reason=reason) await interaction.guild.unban(user_to_unban, reason=reason)
@ -122,15 +173,19 @@ class Unban(commands.Cog):
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)
logger.info(f"User {user_to_unban.display_name} has been unbanned.")
except Exception as error: except Exception as error:
logger.error(f"Failed to unban user {user_to_unban.display_name}. Error: {error}") msg = f"Failed to unban user {user_to_unban.display_name}."
embed = EmbedCreator.create_error_embed( embed = EmbedCreator.create_error_embed(
title="Unban", title="Unban",
description=f"Failed to unban {user_to_unban.display_name}.", description=msg,
interaction=interaction, interaction=interaction,
) )
logger.error(f"{msg} Error: {error}")
await interaction.response.send_message(embed=embed) await interaction.response.send_message(embed=embed)

View file

@ -21,19 +21,43 @@ class Warn(commands.Cog):
infraction_type: InfractionType, infraction_type: InfractionType,
infraction_reason: str, infraction_reason: str,
) -> Infractions | None: ) -> Infractions | None:
try: """
return await self.db_controller.infractions.create_infraction( Inserts an infraction into the database.
user_id=user_id,
moderator_id=moderator_id,
infraction_type=infraction_type,
infraction_reason=infraction_reason,
)
except Exception as error: Parameters
logger.error(f"Failed to create infraction for user {user_id}. Error: {error}") ----------
return None user_id : int
The ID of the user to issue the infraction to.
moderator_id : int
The ID of the moderator issuing the infraction.
infraction_type : InfractionType
The type of infraction to issue.
infraction_reason : str
The reason for issuing the infraction.
Returns
-------
Infractions | None
The infraction that was created, or None if an error occurred.
"""
return await self.db_controller.infractions.create_infraction(
user_id=user_id,
moderator_id=moderator_id,
infraction_type=infraction_type,
infraction_reason=infraction_reason,
)
async def get_or_create_user(self, member: discord.Member) -> None: async def get_or_create_user(self, member: discord.Member) -> None:
"""
Retrieves a user from the database or creates a new user if not found.
Parameters
----------
member : discord.Member
The member to retrieve or create in the database.
"""
user = await self.db_controller.users.get_user_by_id(member.id) user = await self.db_controller.users.get_user_by_id(member.id)
if not user: if not user:
@ -48,6 +72,15 @@ class Warn(commands.Cog):
) )
async def get_or_create_moderator(self, interaction: discord.Interaction) -> None: async def get_or_create_moderator(self, interaction: discord.Interaction) -> None:
"""
Retrieves a moderator from the database or creates a new moderator if not found.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
"""
moderator = await self.db_controller.users.get_user_by_id(interaction.user.id) moderator = await self.db_controller.users.get_user_by_id(interaction.user.id)
moderator_context = None moderator_context = None
if interaction.guild: if interaction.guild:
@ -70,6 +103,19 @@ class Warn(commands.Cog):
async def warn( async def warn(
self, interaction: discord.Interaction, member: discord.Member, reason: str | None = None self, interaction: discord.Interaction, member: discord.Member, reason: str | None = None
) -> None: ) -> None:
"""
Issues a warning to a member of the server.
Parameters
----------
interaction : discord.Interaction
The interaction that triggered the command.
member : discord.Member
The member to warn.
reason : str | None, optional
The reason for issuing the warning.
"""
reason = reason or "No reason provided" reason = reason or "No reason provided"
await self.get_or_create_user(member) await self.get_or_create_user(member)
@ -99,6 +145,7 @@ class Warn(commands.Cog):
except Exception as error: except Exception as error:
msg = f"Failed to issue warning to {member.display_name}." msg = f"Failed to issue warning to {member.display_name}."
embed = EmbedCreator.create_error_embed( embed = EmbedCreator.create_error_embed(
title="Warning Failed", title="Warning Failed",
description=msg, description=msg,