2024-04-01 00:45:28 +00:00
|
|
|
import datetime
|
|
|
|
|
|
|
|
import discord
|
|
|
|
from discord import app_commands
|
|
|
|
from discord.ext import commands
|
|
|
|
from loguru import logger
|
2024-04-14 19:59:45 +00:00
|
|
|
from pytz import UTC
|
|
|
|
|
|
|
|
from prisma.models import Infractions
|
|
|
|
from tux.database.controllers import DatabaseController
|
|
|
|
from tux.utils.embeds import EmbedCreator
|
|
|
|
from tux.utils.enums import InfractionType
|
2024-04-01 00:45:28 +00:00
|
|
|
|
|
|
|
|
2024-04-14 19:59:45 +00:00
|
|
|
class Timeout(commands.Cog):
|
2024-04-01 00:45:28 +00:00
|
|
|
def __init__(self, bot: commands.Bot) -> None:
|
|
|
|
self.bot = bot
|
2024-04-26 12:39:44 +00:00
|
|
|
self.db_controller = DatabaseController()
|
2024-04-14 19:59:45 +00:00
|
|
|
|
|
|
|
async def insert_infraction(
|
|
|
|
self,
|
|
|
|
user_id: int,
|
|
|
|
moderator_id: int,
|
|
|
|
infraction_type: InfractionType,
|
|
|
|
infraction_reason: str,
|
|
|
|
expires_at: datetime.datetime | None = None,
|
|
|
|
) -> Infractions | None:
|
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
2024-05-01 04:12:07 +00:00
|
|
|
"""
|
|
|
|
Inserts an infraction into the database.
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
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,
|
|
|
|
)
|
2024-04-01 00:45:28 +00:00
|
|
|
|
2024-04-26 12:39:44 +00:00
|
|
|
async def get_or_create_user(self, member: discord.Member) -> None:
|
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
2024-05-01 04:12:07 +00:00
|
|
|
"""
|
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
2024-04-26 12:39:44 +00:00
|
|
|
user = await self.db_controller.users.get_user_by_id(member.id)
|
|
|
|
|
|
|
|
if not user:
|
|
|
|
await self.db_controller.users.create_user(
|
|
|
|
user_id=member.id,
|
|
|
|
name=member.name,
|
|
|
|
display_name=member.display_name,
|
|
|
|
mention=member.mention,
|
|
|
|
bot=member.bot,
|
|
|
|
created_at=member.created_at,
|
|
|
|
joined_at=member.joined_at,
|
|
|
|
)
|
|
|
|
|
|
|
|
async def get_or_create_moderator(self, interaction: discord.Interaction) -> None:
|
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
2024-05-01 04:12:07 +00:00
|
|
|
"""
|
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
2024-04-26 12:39:44 +00:00
|
|
|
moderator = await self.db_controller.users.get_user_by_id(interaction.user.id)
|
|
|
|
moderator_context = None
|
|
|
|
if interaction.guild:
|
|
|
|
moderator_context = interaction.guild.get_member(interaction.user.id)
|
|
|
|
|
|
|
|
if not moderator:
|
|
|
|
await self.db_controller.users.create_user(
|
|
|
|
user_id=interaction.user.id,
|
|
|
|
name=interaction.user.name,
|
|
|
|
display_name=interaction.user.display_name,
|
|
|
|
mention=interaction.user.mention,
|
|
|
|
bot=interaction.user.bot,
|
|
|
|
created_at=interaction.user.created_at,
|
|
|
|
joined_at=moderator_context.joined_at if moderator_context else None,
|
|
|
|
)
|
|
|
|
|
|
|
|
@app_commands.checks.has_any_role("Root", "Admin", "Sr. Mod", "Mod")
|
|
|
|
@app_commands.command(name="timeout", description="Issues a timeout to a member of the server.")
|
2024-04-01 00:45:28 +00:00
|
|
|
@app_commands.describe(
|
2024-04-26 12:39:44 +00:00
|
|
|
member="The member to timeout",
|
|
|
|
reason="The reason for issuing the timeout",
|
|
|
|
days="Number of days for the timeout",
|
|
|
|
hours="Number of hours for the timeout",
|
|
|
|
minutes="Number of minutes for the timeout",
|
|
|
|
seconds="Number of seconds for the timeout",
|
2024-04-01 00:45:28 +00:00
|
|
|
)
|
|
|
|
async def timeout(
|
|
|
|
self,
|
|
|
|
interaction: discord.Interaction,
|
|
|
|
member: discord.Member,
|
2024-04-26 12:39:44 +00:00
|
|
|
reason: str | None = None,
|
2024-04-01 00:45:28 +00:00
|
|
|
days: int = 0,
|
|
|
|
hours: int = 0,
|
|
|
|
minutes: int = 0,
|
|
|
|
seconds: int = 0,
|
|
|
|
) -> None:
|
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
2024-05-01 04:12:07 +00:00
|
|
|
"""
|
|
|
|
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
|
|
|
|
"""
|
|
|
|
|
2024-04-14 19:59:45 +00:00
|
|
|
reason = reason or "No reason provided"
|
|
|
|
|
2024-04-01 00:45:28 +00:00
|
|
|
duration = datetime.timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
|
2024-04-14 19:59:45 +00:00
|
|
|
|
2024-04-26 12:39:44 +00:00
|
|
|
await self.get_or_create_user(member)
|
|
|
|
await self.get_or_create_moderator(interaction)
|
|
|
|
|
2024-04-01 00:45:28 +00:00
|
|
|
try:
|
|
|
|
await member.timeout(duration, reason=reason)
|
2024-04-14 19:59:45 +00:00
|
|
|
|
|
|
|
new_timeout = await self.insert_infraction(
|
|
|
|
user_id=member.id,
|
|
|
|
moderator_id=interaction.user.id,
|
|
|
|
infraction_type=InfractionType.TIMEOUT,
|
|
|
|
infraction_reason=reason,
|
|
|
|
expires_at=datetime.datetime.now(UTC) + duration,
|
2024-04-01 00:45:28 +00:00
|
|
|
)
|
2024-04-14 19:59:45 +00:00
|
|
|
|
2024-04-26 12:39:44 +00:00
|
|
|
timeout_id = new_timeout.id if new_timeout else "Unknown"
|
|
|
|
|
2024-04-14 19:59:45 +00:00
|
|
|
embed = EmbedCreator.create_infraction_embed(
|
|
|
|
title="",
|
|
|
|
description="",
|
2024-04-26 12:39:44 +00:00
|
|
|
interaction=interaction,
|
2024-04-01 00:45:28 +00:00
|
|
|
)
|
2024-04-14 19:59:45 +00:00
|
|
|
embed.add_field(name="Action", value="Timeout", inline=True)
|
2024-04-26 12:39:44 +00:00
|
|
|
embed.add_field(name="Case ID", value=f"`{timeout_id}`", inline=True)
|
2024-04-14 19:59:45 +00:00
|
|
|
embed.add_field(name="Reason", value=f"`{reason}`", inline=False)
|
2024-04-26 12:39:44 +00:00
|
|
|
embed.add_field(name="Moderator", value=f"{interaction.user.display_name}", inline=True)
|
|
|
|
embed.add_field(name="Member", value=f"{member.display_name}", inline=True)
|
2024-04-14 19:59:45 +00:00
|
|
|
|
2024-04-26 12:39:44 +00:00
|
|
|
logger.info(f"Timeout issued to {member.display_name} ({member.id}) for: {reason}")
|
2024-04-14 19:59:45 +00:00
|
|
|
|
|
|
|
except Exception as error:
|
2024-04-26 12:39:44 +00:00
|
|
|
msg = f"Failed to issue timeout to {member.display_name}."
|
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
2024-05-01 04:12:07 +00:00
|
|
|
|
2024-04-14 19:59:45 +00:00
|
|
|
embed = EmbedCreator.create_error_embed(
|
2024-04-26 12:39:44 +00:00
|
|
|
title="Timeout Failed",
|
|
|
|
description=msg,
|
|
|
|
interaction=interaction,
|
2024-04-01 00:45:28 +00:00
|
|
|
)
|
2024-04-14 19:59:45 +00:00
|
|
|
|
|
|
|
logger.error(f"{msg} Error: {error}")
|
|
|
|
|
|
|
|
await interaction.response.send_message(embed=embed)
|
2024-04-01 00:45:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def setup(bot: commands.Bot) -> None:
|
2024-04-14 19:59:45 +00:00
|
|
|
await bot.add_cog(Timeout(bot))
|