WIP: Refactor Aurora (3.0.0) #29

Draft
cswimr wants to merge 347 commits from aurora-pydantic into main
5 changed files with 148 additions and 343 deletions
Showing only changes of commit d7ca5cab46 - Show all commits

View file

@ -20,7 +20,8 @@ from redbot.core import app_commands, commands, data_manager
from redbot.core.app_commands import Choice
from redbot.core.bot import Red
from redbot.core.commands.converter import parse_relativedelta, parse_timedelta
from redbot.core.utils.chat_formatting import box, error, humanize_list, humanize_timedelta, warning
from redbot.core.utils.chat_formatting import (box, error, humanize_list,
humanize_timedelta, warning)
from aurora.importers.aurora import ImportAuroraView
from aurora.importers.galacticbot import ImportGalacticBotView
@ -30,11 +31,17 @@ from aurora.menus.immune import Immune
from aurora.menus.overrides import Overrides
from aurora.models import Change, Moderation
from aurora.utilities.config import config, register_config
from aurora.utilities.database import connect, create_guild_table, fetch_case, mysql_log
from aurora.utilities.factory import addrole_embed, case_factory, changes_factory, evidenceformat_factory, guild_embed, immune_embed, message_factory, overrides_embed
from aurora.utilities.database import connect, create_guild_table
from aurora.utilities.factory import (addrole_embed, case_factory,
changes_factory, evidenceformat_factory,
guild_embed, immune_embed,
message_factory, overrides_embed)
from aurora.utilities.json import dump
from aurora.utilities.logger import logger
from aurora.utilities.utils import check_moddable, check_permissions, generate_dict, get_footer_image, log, send_evidenceformat, timedelta_from_relativedelta
from aurora.utilities.utils import (check_moddable, check_permissions,
get_footer_image, log, send_evidenceformat,
timedelta_from_relativedelta)
class Aurora(commands.Cog):
@ -142,7 +149,7 @@ class Aurora(commands.Cog):
if entry.user.id == self.bot.user.id:
return
duration = "NULL"
duration = None
if entry.reason:
reason = entry.reason + " (This action was performed without the bot.)"
@ -175,13 +182,14 @@ class Aurora(commands.Cog):
else:
return
await mysql_log(
Moderation.log(
self.bot,
entry.guild.id,
entry.user.id,
moderation_type,
"USER",
entry.target.id,
0,
None,
duration,
reason,
)
@ -231,23 +239,22 @@ class Aurora(commands.Cog):
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"NOTE",
"USER",
target.id,
0,
"NULL",
None,
None,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has received a note! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="warn")
async def warn(
@ -290,23 +297,22 @@ class Aurora(commands.Cog):
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"WARN",
"USER",
target.id,
0,
"NULL",
None,
None,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been warned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="addrole")
async def addrole(
@ -349,7 +355,7 @@ class Aurora(commands.Cog):
)
return
else:
parsed_time = "NULL"
parsed_time = None
if role.id not in addrole_whitelist:
await interaction.response.send_message(
@ -396,7 +402,8 @@ class Aurora(commands.Cog):
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
)
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"ADDROLE",
@ -407,12 +414,10 @@ class Aurora(commands.Cog):
reason,
)
await response.edit(
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}! (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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="removerole")
async def removerole(
@ -455,7 +460,7 @@ class Aurora(commands.Cog):
)
return
else:
parsed_time = "NULL"
parsed_time = None
if role.id not in addrole_whitelist:
await interaction.response.send_message(
@ -502,7 +507,8 @@ class Aurora(commands.Cog):
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
)
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"REMOVEROLE",
@ -513,12 +519,10 @@ class Aurora(commands.Cog):
reason,
)
await response.edit(
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}! (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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="mute")
async def mute(
@ -590,23 +594,22 @@ class Aurora(commands.Cog):
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"MUTE",
"USER",
target.id,
0,
None,
parsed_time,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been muted for {humanize_timedelta(timedelta=parsed_time)}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been muted for {humanize_timedelta(timedelta=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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="unmute")
async def unmute(
@ -665,23 +668,22 @@ class Aurora(commands.Cog):
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
moderation = await Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"UNMUTE",
"USER",
target.id,
0,
"NULL",
None,
None,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been unmuted! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="kick")
async def kick(
@ -726,23 +728,22 @@ class Aurora(commands.Cog):
await target.kick(reason=f"Kicked by {interaction.user.id} for: {reason}")
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"KICK",
"USER",
target.id,
0,
"NULL",
None,
None,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been kicked! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="ban")
@app_commands.choices(
@ -834,23 +835,22 @@ class Aurora(commands.Cog):
delete_message_seconds=delete_messages_seconds,
)
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"TEMPBAN",
"USER",
target.id,
0,
None,
parsed_time,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been banned for {humanize_timedelta(timedelta=parsed_time)}! (Case `#{moderation_id}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been banned for {humanize_timedelta(timedelta=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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
else:
await interaction.response.send_message(
content=f"{target.mention} has been banned!\n**Reason** - `{reason}`"
@ -878,7 +878,8 @@ class Aurora(commands.Cog):
delete_message_seconds=delete_messages_seconds,
)
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"BAN",
@ -889,12 +890,10 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been banned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="unban")
async def unban(
@ -955,23 +954,22 @@ class Aurora(commands.Cog):
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
moderation = Moderation.log(
interaction.client,
interaction.guild.id,
interaction.user.id,
"UNBAN",
"USER",
target.id,
0,
"NULL",
None,
None,
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been unbanned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
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)
await log(interaction, moderation.id)
await send_evidenceformat(interaction, moderation.id)
@app_commands.command(name="history")
async def history(
@ -1118,8 +1116,7 @@ class Aurora(commands.Cog):
moderation_list: List[Moderation] = []
for result in results:
result_dictionary = generate_dict(result)
moderation = Moderation.from_dict(interaction.client, result_dictionary)
moderation = Moderation.from_result(interaction.client, result, interaction.guild.id)
moderation_list.append(moderation)
case_quantity = len(moderation_list)
@ -1235,7 +1232,7 @@ class Aurora(commands.Cog):
embed = await case_factory(
interaction=interaction,
case_dict=await fetch_case(case, interaction.guild.id),
moderation=moderation,
)
await interaction.response.send_message(
content=f"✅ Moderation #{case:,} resolved!", embed=embed

View file

@ -7,7 +7,8 @@ from discord import ButtonStyle, Interaction, Message, ui
from redbot.core import commands
from redbot.core.utils.chat_formatting import box, warning
from ..utilities.database import connect, create_guild_table, mysql_log
from aurora.models import Change, Moderation
from aurora.utilities.database import connect, create_guild_table
class ImportGalacticBotView(ui.View):
@ -99,37 +100,37 @@ class ImportGalacticBotView(ui.View):
if resolved_timestamp is None:
resolved_timestamp = timestamp
changes = [
{
Change.from_dict({
"type": "ORIGINAL",
"reason": case["reason"],
"user_id": case["executor"],
"timestamp": timestamp,
},
{
}),
Change.from_dict({
"type": "RESOLVE",
"reason": resolved_reason,
"user_id": resolved_by,
"timestamp": resolved_timestamp,
},
}),
]
else:
resolved = 0
resolved = None
resolved_by = None
resolved_reason = None
changes = []
changes = None
if case["reason"] and case["reason"] != "N/A":
reason = case["reason"]
else:
reason = None
await mysql_log(
Moderation.log(
self.ctx.guild.id,
case["executor"],
case["type"],
case["targetType"],
case["target"],
0,
None,
duration,
reason,
timestamp=timestamp,

View file

@ -2,7 +2,7 @@ import json
import sqlite3
from datetime import datetime, timedelta
from time import time
from typing import Any, Dict, List, Literal, Optional, Union
from typing import Any, Dict, Iterable, List, Literal, Optional, Union
import discord
from discord import Forbidden, HTTPException, InvalidData, NotFound
@ -10,7 +10,7 @@ from pydantic import BaseModel, ConfigDict
from redbot.core.bot import Red
from aurora.utilities.logger import logger
from aurora.utilities.utils import generate_dict, get_next_case_number
from aurora.utilities.utils import get_next_case_number
class AuroraBaseModel(BaseModel):
@ -178,6 +178,41 @@ class Moderation(AuroraGuildModel):
def from_dict(cls, bot: Red, data: dict) -> "Moderation":
return cls(bot=bot, **data)
@classmethod
def from_result(bot: Red, result: Iterable, guild_id: int) -> dict:
if result[7] is not None:
hours, minutes, seconds = map(int, result[7].split(':'))
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
else:
duration = None
if result[14] is not None:
changes = json.loads(result[14])
change_obj_list = []
for change in changes:
change_obj_list.append(Change.from_dict(bot=bot, data=change))
case = {
"moderation_id": int(result[0]),
"guild_id": int(guild_id),
"timestamp": datetime.fromtimestamp(result[1]),
"moderation_type": str(result[2]),
"target_type": str(result[3]),
"target_id": int(result[4]),
"moderator_id": int(result[5]),
"role_id": int(result[6]) if result[6] is not None else None,
"duration": duration,
"end_timestamp": datetime.fromtimestamp(result[8]) if result[8] is not None else None,
"reason": result[9],
"resolved": bool(result[10]),
"resolved_by": result[11],
"resolve_reason": result[12],
"expired": bool(result[13]),
"changes": change_obj_list if result[14] else [],
"metadata": json.loads(result[15].replace('\\"', '"').replace('["{', '[{').replace('}"]', '}]')) if result[15] else {},
}
return case
@classmethod
def from_sql(cls, bot: Red, moderation_id: int, guild_id: int) -> "Moderation":
from aurora.utilities.database import connect
@ -190,8 +225,7 @@ class Moderation(AuroraGuildModel):
cursor.close()
if result and not moderation_id == 0:
case = generate_dict(bot, result, guild_id)
return cls.from_dict(bot, case)
return cls.from_result(bot, result, guild_id)
raise ValueError(f"Case {moderation_id} not found in moderation_{guild_id}!")

View file

@ -1,15 +1,11 @@
# pylint: disable=cyclic-import
import json
import sqlite3
import time
from datetime import datetime, timedelta
from discord import Guild
from redbot.core import data_manager
from .logger import logger
from .utils import (convert_timedelta_to_str, generate_dict,
get_next_case_number)
def connect() -> sqlite3.Connection:
@ -79,13 +75,13 @@ async def create_guild_table(guild: Guild):
"NULL",
0,
0,
None,
None,
None,
None,
0,
"NULL",
0,
"NULL",
0,
"NULL",
"NULL",
None,
None,
0,
json.dumps([]),
json.dumps({}),
@ -102,125 +98,3 @@ async def create_guild_table(guild: Guild):
)
database.close()
def mysql_log(
guild_id: str,
author_id: str,
moderation_type: str,
target_type: str,
target_id: int,
role_id: int,
duration: timedelta = None,
reason: str = None,
database: sqlite3.Connection = None,
timestamp: int = None,
resolved: bool = False,
resolved_by: str = None,
resolved_reason: str = None,
expired: bool = None,
changes: list = None,
metadata: dict = None,
) -> int:
if not timestamp:
timestamp = int(time.time())
if duration != "NULL" and duration is not None:
end_timedelta = datetime.fromtimestamp(timestamp) + duration
end_timestamp = int(end_timedelta.timestamp())
duration = convert_timedelta_to_str(duration)
else:
duration = None
end_timestamp = None
if not expired:
if int(time.time()) > end_timestamp:
expired = 1
else:
expired = 0
if reason == "NULL":
reason = None
if resolved_by == "NULL":
resolved_by = None
if resolved_reason == "NULL":
resolved_reason = None
if role_id == 0:
role_id = None
if not database:
database = connect()
close_db = True
else:
close_db = False
cursor = database.cursor()
moderation_id = get_next_case_number(guild_id=guild_id, cursor=cursor)
sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
val = (
moderation_id,
timestamp,
moderation_type,
target_type,
target_id,
author_id,
role_id,
duration,
end_timestamp,
reason,
int(resolved),
resolved_by,
resolved_reason,
expired,
json.dumps(changes if changes else []),
json.dumps(metadata if metadata else {}),
)
cursor.execute(sql, val)
cursor.close()
database.commit()
if close_db:
database.close()
logger.debug(
"Row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
guild_id,
moderation_id,
timestamp,
moderation_type,
target_type,
target_id,
author_id,
role_id,
duration,
end_timestamp,
reason,
int(resolved),
resolved_by,
resolved_reason,
expired,
changes,
metadata,
)
return moderation_id
async def fetch_case(moderation_id: int, guild_id: str) -> dict:
"""This method fetches a case from the database and returns the case's dictionary."""
database = connect()
cursor = database.cursor()
query = f"SELECT * FROM moderation_{guild_id} WHERE moderation_id = ?;"
cursor.execute(query, (moderation_id,))
result = cursor.fetchone()
cursor.close()
database.close()
return generate_dict(result)

View file

@ -1,13 +1,11 @@
# pylint: disable=cyclic-import
import json
from datetime import datetime, timedelta
from typing import Optional, Union
from dateutil.relativedelta import relativedelta as rd
from discord import File, Guild, Interaction, Member, SelectOption, User
from discord.errors import Forbidden, NotFound
from discord.errors import Forbidden
from redbot.core import commands, data_manager
from redbot.core.bot import Red
from redbot.core.utils.chat_formatting import error
from aurora.utilities.config import config
@ -125,123 +123,32 @@ def get_next_case_number(guild_id: str, cursor=None) -> int:
return (result[0] + 1) if result else 1
def generate_dict(bot: Red, result: dict, guild_id: int) -> dict:
from aurora.models import Change
if result[7] is not None:
hours, minutes, seconds = map(int, result[7].split(':'))
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
else:
duration = None
if result[14] is not None:
changes = json.loads(result[14])
change_obj_list = []
for change in changes:
change_obj_list.append(Change.from_dict(bot=bot, data=change))
case = {
"moderation_id": int(result[0]),
"guild_id": int(guild_id),
"timestamp": datetime.fromtimestamp(result[1]),
"moderation_type": str(result[2]),
"target_type": str(result[3]),
"target_id": int(result[4]),
"moderator_id": int(result[5]),
"role_id": int(result[6]) if result[6] is not None else None,
"duration": duration,
"end_timestamp": datetime.fromtimestamp(result[8]) if result[8] is not None else None,
"reason": result[9],
"resolved": bool(result[10]),
"resolved_by": result[11],
"resolve_reason": result[12],
"expired": bool(result[13]),
"changes": change_obj_list if result[14] else [],
"metadata": json.loads(result[15].replace('\\"', '"').replace('["{', '[{').replace('}"]', '}]')) if result[15] else {},
}
return case
async def fetch_user_dict(client: commands.Bot, user_id: str) -> dict:
"""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"}
else:
try:
user = client.get_user(int(user_id))
if user is None:
user = await client.fetch_user(int(user_id))
user_dict = {
"id": user.id,
"name": user.name,
"discriminator": user.discriminator,
}
except NotFound:
user_dict = {
"id": user_id,
"name": "Deleted User",
"discriminator": "0",
}
return user_dict
async def fetch_channel_dict(guild: Guild, channel_id: int) -> dict:
"""This function returns a dictionary containing either channel information or a standard deleted channel template."""
try:
channel = guild.get_channel(int(channel_id))
if not channel:
channel = await guild.fetch_channel(channel_id)
channel_dict = {
"id": channel.id,
"name": channel.name,
"mention": channel.mention,
}
except NotFound:
channel_dict = {"id": channel_id, "name": "Deleted Channel", "mention": None}
return channel_dict
async def fetch_role_dict(guild: Guild, role_id: int) -> dict:
"""This function returns a dictionary containing either role information or a standard deleted role template."""
role = guild.get_role(int(role_id))
if not role:
role_dict = {"id": role_id, "name": "Deleted Role"}
role_dict = {"id": role.id, "name": role.name}
return role_dict
async def log(interaction: Interaction, moderation_id: int, resolved: bool = False) -> None:
"""This function sends a message to the guild's configured logging channel when an infraction takes place."""
from .database import fetch_case
from .factory import log_factory
from aurora.models import Moderation
from aurora.utilities.factory import log_factory
logging_channel_id = await config.guild(interaction.guild).log_channel()
if logging_channel_id != " ":
logging_channel = interaction.guild.get_channel(logging_channel_id)
case = await fetch_case(moderation_id, interaction.guild.id)
if case:
try:
moderation = Moderation.from_sql(interaction.client, moderation_id)
embed = await log_factory(
interaction=interaction, case_dict=case, resolved=resolved
interaction=interaction, moderation=moderation, resolved=resolved
)
try:
await logging_channel.send(embed=embed)
except Forbidden:
return
except ValueError:
return
async def send_evidenceformat(interaction: Interaction, case_dict: dict) -> None:
async def send_evidenceformat(interaction: Interaction, moderation_id: int) -> None:
"""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 .factory import evidenceformat_factory
from aurora.models import Moderation
from aurora.utilities.factory import evidenceformat_factory
send_evidence_bool = (
await config.user(interaction.user).auto_evidenceformat()
@ -251,19 +158,11 @@ async def send_evidenceformat(interaction: Interaction, case_dict: dict) -> None
if send_evidence_bool is False:
return
content = await evidenceformat_factory(interaction=interaction, case_dict=case_dict)
moderation = Moderation.from_sql(interaction.client, moderation_id)
content = await evidenceformat_factory(interaction=interaction, moderation=moderation)
await interaction.followup.send(content=content, ephemeral=True)
def convert_timedelta_to_str(td: timedelta) -> str:
"""This function converts a timedelta object to a string."""
total_seconds = int(td.total_seconds())
hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60
return f"{hours}:{minutes}:{seconds}"
def get_bool_emoji(value: Optional[bool]) -> str:
"""Returns a unicode emoji based on a boolean value."""
if value is True: