Compare commits

...

11 commits

3 changed files with 149 additions and 164 deletions

View file

@ -48,7 +48,7 @@ class Aurora(commands.Cog):
This cog stores all of its data in an SQLite database."""
__author__ = ["SeaswimmerTheFsh"]
__version__ = "2.0.6"
__version__ = "2.1.6"
async def red_delete_data_for_user(self, *, requester, user_id: int):
if requester == "discord_deleted_user":
@ -180,50 +180,47 @@ class Aurora(commands.Cog):
### COMMANDS
#######################################################################################################################
@app_commands.command(name="note")
@commands.hybrid_command(name="note")
@commands.mod_or_permissions(moderate_members=True)
@app_commands.describe(
target="Who are you noting?",
reason="Why are you noting this user?",
silent="Should the user be messaged?",
)
async def note(
self,
interaction: discord.Interaction,
ctx: commands.Context,
target: discord.User,
reason: str,
silent: bool = None,
):
"""Add a note to a user.
Parameters
-----------
target: discord.User
Who are you noting?
reason: str
Why are you noting this user?
silent: bool
Should the user be messaged?"""
if not await check_moddable(target, interaction, ["moderate_members"]):
"""Add a note to a user."""
if not await check_moddable(target, ctx, ["moderate_members"]):
return
await interaction.response.send_message(
message = await ctx.send(
content=f"{target.mention} has recieved a note!\n**Reason** - `{reason}`"
)
if silent is None:
silent = not await config.guild(interaction.guild).dm_users()
silent = not await config.guild(ctx.guild).dm_users()
if silent is False:
try:
embed = await message_factory(
await self.bot.get_embed_color(interaction.channel),
guild=interaction.guild,
moderator=interaction.user,
await self.bot.get_embed_color(ctx.channel),
guild=ctx.guild,
moderator=ctx.author,
reason=reason,
moderation_type="note",
response=await interaction.original_response(),
response=message,
)
await target.send(embed=embed)
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
interaction.guild.id,
interaction.user.id,
ctx.guild.id,
ctx.author.id,
"NOTE",
"USER",
target.id,
@ -231,58 +228,55 @@ class Aurora(commands.Cog):
"NULL",
reason,
)
await interaction.edit_original_response(
await message.edit(
content=f"{target.mention} has received a note! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
)
await log(interaction, moderation_id)
await log(ctx, moderation_id)
case = await fetch_case(moderation_id, interaction.guild.id)
await send_evidenceformat(interaction, case)
case = await fetch_case(moderation_id, ctx.guild.id)
await send_evidenceformat(ctx, case)
@app_commands.command(name="warn")
@commands.hybrid_command(name="warn")
@commands.mod_or_permissions(moderate_members=True)
@app_commands.describe(
target="Who are you warning?",
reason="Why are you warning this user?",
silent="Should the user be messaged?",
)
async def warn(
self,
interaction: discord.Interaction,
ctx: commands.Context,
target: discord.Member,
reason: str,
silent: bool = None,
):
"""Warn a user.
Parameters
-----------
target: discord.Member
Who are you warning?
reason: str
Why are you warning this user?
silent: bool
Should the user be messaged?"""
if not await check_moddable(target, interaction, ["moderate_members"]):
"""Warn a user."""
if not await check_moddable(target, ctx, ["moderate_members"]):
return
await interaction.response.send_message(
message = await ctx.send(
content=f"{target.mention} has been warned!\n**Reason** - `{reason}`"
)
if silent is None:
silent = not await config.guild(interaction.guild).dm_users()
silent = not await config.guild(ctx.guild).dm_users()
if silent is False:
try:
embed = await message_factory(
await self.bot.get_embed_color(interaction.channel),
guild=interaction.guild,
moderator=interaction.user,
await self.bot.get_embed_color(ctx.channel),
guild=ctx.guild,
moderator=ctx.author,
reason=reason,
moderation_type="warned",
response=await interaction.original_response(),
response=message,
)
await target.send(embed=embed)
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
interaction.guild.id,
interaction.user.id,
ctx.guild.id,
ctx.author.id,
"WARN",
"USER",
target.id,
@ -290,13 +284,13 @@ class Aurora(commands.Cog):
"NULL",
reason,
)
await interaction.edit_original_response(
await message.edit(
content=f"{target.mention} has been warned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
)
await log(interaction, moderation_id)
await log(ctx, moderation_id)
case = await fetch_case(moderation_id, interaction.guild.id)
await send_evidenceformat(interaction, case)
case = await fetch_case(moderation_id, ctx.guild.id)
await send_evidenceformat(ctx, case)
@app_commands.command(name="addrole")
async def addrole(
@ -407,32 +401,28 @@ class Aurora(commands.Cog):
case = await fetch_case(moderation_id, interaction.guild.id)
await send_evidenceformat(interaction, case)
@app_commands.command(name="mute")
@commands.hybrid_command(name="mute")
@commands.mod_or_permissions(moderate_members=True)
@app_commands.describe(
target="Who are you muting?",
duration="How long are you muting this user for?",
reason="Why are you muting this user?",
silent="Should the user be messaged?",
)
async def mute(
self,
interaction: discord.Interaction,
ctx: commands.Context,
target: discord.Member,
duration: str,
reason: str,
silent: bool = None,
):
"""Mute a user.
Parameters
-----------
target: discord.Member
Who are you unbanning?
duration: str
How long are you muting this user for?
reason: str
Why are you unbanning this user?
silent: bool
Should the user be messaged?"""
if not await check_moddable(target, interaction, ["moderate_members"]):
"""Mute a user."""
if not await check_moddable(target, ctx, ["moderate_members"]):
return
if target.is_timed_out() is True:
await interaction.response.send_message(
await ctx.send(
error(f"{target.mention} is already muted!"),
allowed_mentions=discord.AllowedMentions(users=False),
ephemeral=True,
@ -442,36 +432,36 @@ class Aurora(commands.Cog):
try:
parsed_time = parse(sval=duration, as_timedelta=True, raise_exception=True)
except ValueError:
await interaction.response.send_message(
await ctx.send(
error("Please provide a valid duration!"), ephemeral=True
)
return
if parsed_time.total_seconds() / 1000 > 2419200000:
await interaction.response.send_message(
await ctx.send(
error("Please provide a duration that is less than 28 days.")
)
return
await target.timeout(
parsed_time, reason=f"Muted by {interaction.user.id} for: {reason}"
parsed_time, reason=f"Muted by {ctx.author.id} for: {reason}"
)
await interaction.response.send_message(
message = await ctx.send(
content=f"{target.mention} has been muted for {humanize.precisedelta(parsed_time)}!\n**Reason** - `{reason}`"
)
if silent is None:
silent = not await config.guild(interaction.guild).dm_users()
silent = not await config.guild(ctx.guild).dm_users()
if silent is False:
try:
embed = await message_factory(
await self.bot.get_embed_color(interaction.channel),
guild=interaction.guild,
moderator=interaction.user,
await ctx.embed_color(),
guild=ctx.guild,
moderator=ctx.author,
reason=reason,
moderation_type="muted",
response=await interaction.original_response(),
response=message,
duration=parsed_time,
)
await target.send(embed=embed)
@ -479,8 +469,8 @@ class Aurora(commands.Cog):
pass
moderation_id = await mysql_log(
interaction.guild.id,
interaction.user.id,
ctx.guild.id,
ctx.author.id,
"MUTE",
"USER",
target.id,
@ -488,37 +478,34 @@ class Aurora(commands.Cog):
parsed_time,
reason,
)
await interaction.edit_original_response(
await message.edit(
content=f"{target.mention} has been muted for {humanize.precisedelta(parsed_time)}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
)
await log(interaction, moderation_id)
await log(ctx, moderation_id)
case = await fetch_case(moderation_id, interaction.guild.id)
await send_evidenceformat(interaction, case)
case = await fetch_case(moderation_id, ctx.guild.id)
await send_evidenceformat(ctx, case)
@app_commands.command(name="unmute")
@commands.hybrid_command(name="unmute")
@commands.mod_or_permissions(moderate_members=True)
@app_commands.describe(
target="Who are you unmuting?",
reason="Why are you unmuting this user?",
silent="Should the user be messaged?",
)
async def unmute(
self,
interaction: discord.Interaction,
ctx: commands.Context,
target: discord.Member,
reason: str = None,
silent: bool = None,
):
"""Unmute a user.
Parameters
-----------
target: discord.user
Who are you unmuting?
reason: str
Why are you unmuting this user?
silent: bool
Should the user be messaged?"""
if not await check_moddable(target, interaction, ["moderate_members"]):
"""Unmute a user."""
if not await check_moddable(target, ctx, ["moderate_members"]):
return
if target.is_timed_out() is False:
await interaction.response.send_message(
await ctx.send(
error(f"{target.mention} is not muted!"),
allowed_mentions=discord.AllowedMentions(users=False),
ephemeral=True,
@ -527,35 +514,35 @@ class Aurora(commands.Cog):
if reason:
await target.timeout(
None, reason=f"Unmuted by {interaction.user.id} for: {reason}"
None, reason=f"Unmuted by {ctx.author.id} for: {reason}"
)
else:
await target.timeout(None, reason=f"Unbanned by {interaction.user.id}")
await target.timeout(None, reason=f"Unmuted by {ctx.author.id}")
reason = "No reason given."
await interaction.response.send_message(
message = await ctx.send(
content=f"{target.mention} has been unmuted!\n**Reason** - `{reason}`"
)
if silent is None:
silent = not await config.guild(interaction.guild).dm_users()
silent = not await config.guild(ctx.guild).dm_users()
if silent is False:
try:
embed = await message_factory(
await self.bot.get_embed_color(interaction.channel),
guild=interaction.guild,
moderator=interaction.user,
await ctx.embed_color(),
guild=ctx.guild,
moderator=ctx.author,
reason=reason,
moderation_type="unmuted",
response=await interaction.original_response(),
response=message,
)
await target.send(embed=embed)
except discord.errors.HTTPException:
pass
moderation_id = await mysql_log(
interaction.guild.id,
interaction.user.id,
ctx.guild.id,
ctx.author.id,
"UNMUTE",
"USER",
target.id,
@ -563,13 +550,13 @@ class Aurora(commands.Cog):
"NULL",
reason,
)
await interaction.edit_original_response(
await message.edit(
content=f"{target.mention} has been unmuted! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
)
await log(interaction, moderation_id)
await log(ctx, moderation_id)
case = await fetch_case(moderation_id, interaction.guild.id)
await send_evidenceformat(interaction, case)
case = await fetch_case(moderation_id, ctx.guild.id)
await send_evidenceformat(ctx, case)
@app_commands.command(name="kick")
async def kick(

View file

@ -3,8 +3,7 @@ from datetime import datetime, timedelta
from typing import Union
import humanize
from discord import (Color, Embed, Guild, Interaction, InteractionMessage,
Member, Role, User)
from discord import Color, Embed, Guild, Member, Message, Role, User
from redbot.core import commands
from redbot.core.utils.chat_formatting import bold, box, error, warning
@ -21,7 +20,7 @@ async def message_factory(
moderation_type: str,
moderator: Union[Member, User] = None,
duration: timedelta = None,
response: InteractionMessage = None,
response: Message = None,
role: Role = None,
) -> Embed:
"""This function creates a message from set parameters, meant for contacting the moderated user.
@ -33,10 +32,9 @@ async def message_factory(
moderation_type (str): The type of moderation.
moderator (Union[Member, User], optional): The moderator who performed the moderation. Defaults to None.
duration (timedelta, optional): The duration of the moderation. Defaults to None.
response (InteractionMessage, optional): The response message. Defaults to None.
response (Message, optional): The response message. Defaults to None.
role (Role, optional): The role that was added or removed. Defaults to None.
Returns:
embed: The message embed.
"""
@ -92,7 +90,7 @@ async def message_factory(
async def log_factory(
interaction: Interaction, case_dict: dict, resolved: bool = False
ctx: commands.Context, case_dict: dict, resolved: bool = False
) -> Embed:
"""This function creates a log embed from set parameters, meant for moderation logging.
@ -103,20 +101,20 @@ async def log_factory(
"""
if resolved:
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_user = await fetch_user_dict(ctx.bot, case_dict["target_id"])
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
target_user = await fetch_channel_dict(ctx.guild, case_dict["target_id"])
if target_user["mention"]:
target_name = f"{target_user['mention']}"
else:
target_name = f"`{target_user['name']}`"
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_user = await fetch_user_dict(ctx.bot, case_dict["moderator_id"])
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
@ -125,7 +123,7 @@ async def log_factory(
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,} Resolved",
color=await interaction.client.get_embed_color(interaction.channel),
color=await ctx.client.get_embed_color(ctx.channel),
)
embed.description = f"**Type:** {str.title(case_dict['moderation_type'])}\n**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})\n**Timestamp:** <t:{case_dict['timestamp']}> | <t:{case_dict['timestamp']}:R>"
@ -152,7 +150,7 @@ async def log_factory(
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
resolved_user = await fetch_user_dict(ctx.bot, case_dict["resolved_by"])
resolved_name = (
resolved_user["name"]
if resolved_user["discriminator"] == "0"
@ -166,20 +164,20 @@ async def log_factory(
)
else:
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_user = await fetch_user_dict(ctx.bot, case_dict["target_id"])
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
target_user = await fetch_channel_dict(ctx.guild, case_dict["target_id"])
if target_user["mention"]:
target_name = target_user["mention"]
else:
target_name = f"`{target_user['name']}`"
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_user = await fetch_user_dict(ctx.bot, case_dict["moderator_id"])
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
@ -188,7 +186,7 @@ async def log_factory(
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,}",
color=await interaction.client.get_embed_color(interaction.channel),
color=await ctx.bot.get_embed_color(ctx.channel),
)
embed.description = f"**Type:** {str.title(case_dict['moderation_type'])}\n**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})\n**Timestamp:** <t:{case_dict['timestamp']}> | <t:{case_dict['timestamp']}:R>"
@ -211,28 +209,28 @@ async def log_factory(
return embed
async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
async def case_factory(ctx: commands.Context, case_dict: dict) -> Embed:
"""This function creates a case embed from set parameters.
Args:
interaction (Interaction): The interaction object.
ctx (commands.Context): The context object.
case_dict (dict): The case dictionary.
"""
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_user = await fetch_user_dict(ctx.bot, case_dict["target_id"])
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
target_user = await fetch_channel_dict(ctx.guild, case_dict["target_id"])
if target_user["mention"]:
target_name = f"{target_user['mention']}"
else:
target_name = f"`{target_user['name']}`"
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_user = await fetch_user_dict(ctx.bot, case_dict["moderator_id"])
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
@ -241,7 +239,7 @@ async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,}",
color=await interaction.client.get_embed_color(interaction.channel),
color=await ctx.bot.get_embed_color(ctx.channel),
)
embed.description = f"**Type:** {str.title(case_dict['moderation_type'])}\n**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})\n**Resolved:** {bool(case_dict['resolved'])}\n**Timestamp:** <t:{case_dict['timestamp']}> | <t:{case_dict['timestamp']}:R>"
@ -276,7 +274,7 @@ async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
if case_dict["resolved"] == 1:
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
resolved_user = await fetch_user_dict(ctx.bot, case_dict["resolved_by"])
resolved_name = (
f"`{resolved_user['name']}`"
if resolved_user["discriminator"] == "0"
@ -291,16 +289,16 @@ async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
return embed
async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
async def changes_factory(ctx: commands.Context, case_dict: dict) -> Embed:
"""This function creates a changes embed from set parameters.
Args:
interaction (Interaction): The interaction object.
ctx (commands.Context): The context object.
case_dict (dict): The case dictionary.
"""
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,} Changes",
color=await interaction.client.get_embed_color(interaction.channel),
color=await ctx.bot.get_embed_color(ctx.channel),
)
memory_dict = {}
@ -309,7 +307,7 @@ async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
for change in case_dict["changes"]:
if change["user_id"] not in memory_dict:
memory_dict[str(change["user_id"])] = await fetch_user_dict(
interaction.client, change["user_id"]
ctx.bot, change["user_id"]
)
user = memory_dict[str(change["user_id"])]
@ -348,7 +346,7 @@ async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
return embed
async def evidenceformat_factory(interaction: Interaction, case_dict: dict) -> str:
async def evidenceformat_factory(ctx: commands.Context, case_dict: dict) -> str:
"""This function creates a codeblock in evidence format from set parameters.
Args:
@ -356,7 +354,7 @@ async def evidenceformat_factory(interaction: Interaction, case_dict: dict) -> s
case_dict (dict): The case dictionary.
"""
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_user = await fetch_user_dict(ctx.bot, case_dict["target_id"])
target_name = (
target_user["name"]
if target_user["discriminator"] == "0"
@ -364,10 +362,10 @@ async def evidenceformat_factory(interaction: Interaction, case_dict: dict) -> s
)
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
target_user = await fetch_channel_dict(ctx.guild, case_dict["target_id"])
target_name = target_user["name"]
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_user = await fetch_user_dict(ctx.bot, case_dict["moderator_id"])
moderator_name = (
moderator_user["name"]
if moderator_user["discriminator"] == "0"

View file

@ -40,11 +40,11 @@ def check_permissions(
async def check_moddable(
target: Union[User, Member], interaction: Interaction, permissions: list
target: Union[User, Member], ctx: Union[commands.Context, Interaction], permissions: list
) -> bool:
"""Checks if a moderator can moderate a target."""
if check_permissions(interaction.client.user, permissions, guild=interaction.guild):
await interaction.response.send_message(
if check_permissions(ctx.bot.user, permissions, guild=ctx.guild):
await ctx.send(
error(
f"I do not have the `{permissions}` permission, required for this action."
),
@ -52,9 +52,9 @@ async def check_moddable(
)
return False
if await config.guild(interaction.guild).use_discord_permissions() is True:
if check_permissions(interaction.user, permissions, guild=interaction.guild):
await interaction.response.send_message(
if await config.guild(ctx.guild).use_discord_permissions() is True:
if check_permissions(ctx.author, permissions, guild=ctx.guild):
await ctx.send(
error(
f"You do not have the `{permissions}` permission, required for this action."
),
@ -62,21 +62,21 @@ async def check_moddable(
)
return False
if interaction.user.id == target.id:
await interaction.response.send_message(
if ctx.author.id == target.id:
await ctx.send(
content="You cannot moderate yourself!", ephemeral=True
)
return False
if target.bot:
await interaction.response.send_message(
await ctx.send(
content="You cannot moderate bots!", ephemeral=True
)
return False
if isinstance(target, Member):
if interaction.user.top_role <= target.top_role:
await interaction.response.send_message(
if ctx.author.top_role <= target.top_role:
await ctx.send(
content=error(
"You cannot moderate members with a higher role than you!"
),
@ -85,10 +85,10 @@ async def check_moddable(
return False
if (
interaction.guild.get_member(interaction.client.user.id).top_role
ctx.guild.get_member(ctx.bot.user.id).top_role
<= target.top_role
):
await interaction.response.send_message(
await ctx.send(
content=error(
"You cannot moderate members with a role higher than the bot!"
),
@ -100,7 +100,7 @@ async def check_moddable(
for role in target.roles:
if role.id in immune_roles:
await interaction.response.send_message(
await ctx.send(
content=error("You cannot moderate members with an immune role!"),
ephemeral=True,
)
@ -203,19 +203,19 @@ async def fetch_role_dict(guild: Guild, role_id: int) -> dict:
return role_dict
async def log(interaction: Interaction, moderation_id: int, resolved: bool = False) -> None:
async def log(ctx: Union[commands.Context, 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
logging_channel_id = await config.guild(interaction.guild).log_channel()
logging_channel_id = await config.guild(ctx.guild).log_channel()
if logging_channel_id != " ":
logging_channel = interaction.guild.get_channel(logging_channel_id)
logging_channel = ctx.guild.get_channel(logging_channel_id)
case = await fetch_case(moderation_id, interaction.guild.id)
case = await fetch_case(moderation_id, ctx.guild.id)
if case:
embed = await log_factory(
interaction=interaction, case_dict=case, resolved=resolved
ctx=ctx, case_dict=case, resolved=resolved
)
try:
await logging_channel.send(embed=embed)
@ -223,20 +223,20 @@ async def log(interaction: Interaction, moderation_id: int, resolved: bool = Fal
return
async def send_evidenceformat(interaction: Interaction, case_dict: dict) -> None:
async def send_evidenceformat(ctx: commands.Context, case_dict: dict) -> 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
send_evidence_bool = (
await config.user(interaction.user).auto_evidenceformat()
or await config.guild(interaction.guild).auto_evidenceformat()
await config.user(ctx.author).auto_evidenceformat()
or await config.guild(ctx.guild).auto_evidenceformat()
or False
)
if send_evidence_bool is False:
return
content = await evidenceformat_factory(interaction=interaction, case_dict=case_dict)
await interaction.followup.send(content=content, ephemeral=True)
content = await evidenceformat_factory(ctx=ctx, case_dict=case_dict)
await ctx.send(content=content, ephemeral=True)
def convert_timedelta_to_str(timedelta: td) -> str: