WIP: Moderation type registry #26
2 changed files with 86 additions and 93 deletions
146
aurora/aurora.py
146
aurora/aurora.py
|
@ -27,13 +27,13 @@ from aurora.menus.addrole import Addrole
|
||||||
from aurora.menus.guild import Guild
|
from aurora.menus.guild import Guild
|
||||||
from aurora.menus.immune import Immune
|
from aurora.menus.immune import Immune
|
||||||
from aurora.menus.overrides import Overrides
|
from aurora.menus.overrides import Overrides
|
||||||
from aurora.models import Moderation
|
from aurora.models import Change, Moderation
|
||||||
from aurora.utilities.config import config, register_config
|
from aurora.utilities.config import config, register_config
|
||||||
from aurora.utilities.database import connect, create_guild_table, fetch_case, mysql_log
|
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.factory import addrole_embed, case_factory, changes_factory, evidenceformat_factory, guild_embed, immune_embed, message_factory, overrides_embed
|
||||||
from aurora.utilities.json import dump, dumps
|
from aurora.utilities.json import dump, dumps
|
||||||
from aurora.utilities.logger import logger
|
from aurora.utilities.logger import logger
|
||||||
from aurora.utilities.utils import check_moddable, check_permissions, convert_timedelta_to_str, fetch_channel_dict, fetch_user_dict, generate_dict, get_footer_image, log, send_evidenceformat, timedelta_from_relativedelta
|
from aurora.utilities.utils import check_moddable, check_permissions, fetch_channel_dict, fetch_user_dict, generate_dict, get_footer_image, log, send_evidenceformat, timedelta_from_relativedelta
|
||||||
|
|
||||||
|
|
||||||
class Aurora(commands.Cog):
|
class Aurora(commands.Cog):
|
||||||
|
@ -1490,107 +1490,77 @@ class Aurora(commands.Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
if case != 0:
|
if case != 0:
|
||||||
parsed_time = None
|
moderation = Moderation.from_sql(interaction.client, case, interaction.guild.id)
|
||||||
case_dict = await fetch_case(case, interaction.guild.id)
|
old_moderation = moderation
|
||||||
if case_dict:
|
if moderation:
|
||||||
if duration:
|
if len(moderation.changes) > 25:
|
||||||
parsed_time = parse_timedelta(duration)
|
return await interaction.response.send_message(
|
||||||
if parsed_time is None:
|
|
||||||
await interaction.response.send_message(
|
|
||||||
error("Please provide a valid duration!"), ephemeral=True
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
end_timestamp = case_dict["timestamp"] + parsed_time.total_seconds()
|
|
||||||
|
|
||||||
if case_dict["moderation_type"] == "MUTE":
|
|
||||||
if (
|
|
||||||
time.time() - case_dict["timestamp"]
|
|
||||||
) + parsed_time.total_seconds() > 2419200:
|
|
||||||
await interaction.response.send_message(
|
|
||||||
error(
|
|
||||||
"Please provide a duration that is less than 28 days from the initial moderation."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
member = await interaction.guild.fetch_member(
|
|
||||||
case_dict["target_id"]
|
|
||||||
)
|
|
||||||
|
|
||||||
await member.timeout(
|
|
||||||
parsed_time,
|
|
||||||
reason=f"Case #{case:,} edited by {interaction.user.id}",
|
|
||||||
)
|
|
||||||
except discord.NotFound:
|
|
||||||
pass
|
|
||||||
|
|
||||||
changes: list = case_dict["changes"]
|
|
||||||
if len(changes) > 25:
|
|
||||||
await interaction.response.send_message(
|
|
||||||
content=error(
|
content=error(
|
||||||
"Due to limitations with Discord's embed system, you cannot edit a case more than 25 times."
|
"Due to limitations with Discord's embed system, you cannot edit a case more than 25 times."
|
||||||
),
|
),
|
||||||
ephemeral=True,
|
ephemeral=True,
|
||||||
)
|
)
|
||||||
return
|
if duration:
|
||||||
if not changes:
|
moderation.duration = parse_timedelta(duration)
|
||||||
changes.append(
|
if moderation.duration is None:
|
||||||
{
|
return await interaction.response.send_message(
|
||||||
|
error("Please provide a valid duration!"), ephemeral=True
|
||||||
|
)
|
||||||
|
|
||||||
|
moderation.end_timestamp = moderation.timestamp + moderation.duration.total_seconds()
|
||||||
|
|
||||||
|
if moderation.type == "MUTE":
|
||||||
|
if (
|
||||||
|
time.time() - moderation.unix_timestamp
|
||||||
|
) + moderation.duration.total_seconds() > 2419200:
|
||||||
|
return await interaction.response.send_message(
|
||||||
|
error(
|
||||||
|
"Please provide a duration that is less than 28 days from the initial moderation."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
member = await interaction.guild.fetch_member(
|
||||||
|
moderation.target_id
|
||||||
|
)
|
||||||
|
|
||||||
|
await member.timeout(
|
||||||
|
moderation.duration,
|
||||||
|
reason=f"Case #{case:,} edited by {interaction.user.id}",
|
||||||
|
)
|
||||||
|
except discord.NotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not moderation.changes:
|
||||||
|
moderation.changes.append(Change.from_dict(interaction.client, {
|
||||||
"type": "ORIGINAL",
|
"type": "ORIGINAL",
|
||||||
"timestamp": case_dict["timestamp"],
|
"timestamp": old_moderation.timestamp,
|
||||||
"reason": case_dict["reason"],
|
"reason": old_moderation.reason,
|
||||||
"user_id": case_dict["moderator_id"],
|
"user_id": old_moderation.moderator_id,
|
||||||
"duration": case_dict["duration"],
|
"duration": old_moderation.duration,
|
||||||
"end_timestamp": case_dict["end_timestamp"],
|
"end_timestamp": old_moderation.end_timestamp,
|
||||||
}
|
}))
|
||||||
)
|
if duration:
|
||||||
if parsed_time:
|
moderation.changes.append(Change.from_dict(interaction.client, {
|
||||||
changes.append(
|
|
||||||
{
|
|
||||||
"type": "EDIT",
|
"type": "EDIT",
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
"reason": reason,
|
"reason": reason,
|
||||||
"user_id": interaction.user.id,
|
"user_id": interaction.user.id,
|
||||||
"duration": convert_timedelta_to_str(parsed_time),
|
"duration": moderation.duration,
|
||||||
"end_timestamp": end_timestamp,
|
"end_timestamp": moderation.end_timestamp,
|
||||||
}
|
}))
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
changes.append(
|
moderation.changes.append(Change.from_dict(interaction.client, {
|
||||||
{
|
|
||||||
"type": "EDIT",
|
"type": "EDIT",
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
"reason": reason,
|
"reason": reason,
|
||||||
"user_id": interaction.user.id,
|
"user_id": interaction.user.id,
|
||||||
"duration": case_dict["duration"],
|
"duration": moderation.duration,
|
||||||
"end_timestamp": case_dict["end_timestamp"],
|
"end_timestamp": moderation.end_timestamp,
|
||||||
}
|
}))
|
||||||
)
|
|
||||||
|
|
||||||
database = connect()
|
moderation.update()
|
||||||
cursor = database.cursor()
|
embed = await case_factory(interaction=interaction, moderation=moderation)
|
||||||
|
|
||||||
if parsed_time:
|
|
||||||
update_query = f"UPDATE `moderation_{interaction.guild.id}` SET changes = ?, reason = ?, duration = ?, end_timestamp = ? WHERE moderation_id = ?"
|
|
||||||
cursor.execute(
|
|
||||||
update_query,
|
|
||||||
(
|
|
||||||
dumps(changes),
|
|
||||||
reason,
|
|
||||||
convert_timedelta_to_str(parsed_time),
|
|
||||||
end_timestamp,
|
|
||||||
case,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
update_query = f"UPDATE `moderation_{interaction.guild.id}` SET changes = ?, reason = ? WHERE moderation_id = ?"
|
|
||||||
cursor.execute(update_query, (dumps(changes), reason, case))
|
|
||||||
database.commit()
|
|
||||||
|
|
||||||
new_case = await fetch_case(case, interaction.guild.id)
|
|
||||||
embed = await case_factory(interaction=interaction, case_dict=new_case)
|
|
||||||
|
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
content=f"✅ Moderation #{case:,} edited!",
|
content=f"✅ Moderation #{case:,} edited!",
|
||||||
|
@ -1599,8 +1569,6 @@ class Aurora(commands.Cog):
|
||||||
)
|
)
|
||||||
await log(interaction, case)
|
await log(interaction, case)
|
||||||
|
|
||||||
cursor.close()
|
|
||||||
database.close()
|
|
||||||
return
|
return
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
content=error(f"No case with case number `{case}` found."), ephemeral=True
|
content=error(f"No case with case number `{case}` found."), ephemeral=True
|
||||||
|
|
|
@ -77,6 +77,16 @@ class Moderation(AuroraGuildModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.moderation_type} {self.target_type} {self.target_id} {self.reason}"
|
return f"{self.moderation_type} {self.target_type} {self.target_id} {self.reason}"
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
from aurora.utilities.database import connect
|
||||||
|
query = f"UPDATE moderation_{self.guild_id} SET timestamp = ?, moderation_type = ?, target_type = ?, moderator_id = ?, role_id = ?, duration = ?, end_timestamp = ?, reason = ?, resolved = ?, resolved_by = ?, resolve_reason = ?, expired = ?, changes = ?, metadata = ? WHERE moderation_id = ?;"
|
||||||
|
changes = [change.to_json() for change in self.changes]
|
||||||
|
|
||||||
|
with connect() as database:
|
||||||
|
cursor = database.cursor()
|
||||||
|
cursor.execute(query, (self.timestamp, self.moderation_type, self.target_type, self.moderator_id, self.role_id, self.duration, self.end_timestamp, self.reason, self.resolved, self.resolved_by, self.resolve_reason, self.expired, changes, self.metadata, self.moderation_id))
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_sql(cls, bot: Red, moderation_id: int, guild_id: int) -> Optional["Moderation"]:
|
def from_sql(cls, bot: Red, moderation_id: int, guild_id: int) -> Optional["Moderation"]:
|
||||||
from aurora.utilities.database import connect
|
from aurora.utilities.database import connect
|
||||||
|
@ -118,14 +128,29 @@ class Change(AuroraBaseModel):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, bot: Red, data: dict) -> "Change":
|
def from_dict(cls, bot: Red, data: dict) -> "Change":
|
||||||
if "duration" in data and data["duration"] is not None:
|
if "duration" in data and data["duration"] and not isinstance(data["duration"], timedelta):
|
||||||
hours, minutes, seconds = map(int, data["duration"].split(':'))
|
hours, minutes, seconds = map(int, data["duration"].split(':'))
|
||||||
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
||||||
|
elif duration in data and isinstance(data["duration"], timedelta):
|
||||||
|
duration = data["duration"]
|
||||||
else:
|
else:
|
||||||
duration = None
|
duration = None
|
||||||
|
|
||||||
|
if "end_timestamp" in data and data["end_timestamp"] and not isinstance(data["end_timestamp"], datetime):
|
||||||
|
end_timestamp = datetime.fromtimestamp(data["end_timestamp"])
|
||||||
|
elif "end_timestamp" in data and isinstance(data["end_timestamp"], datetime):
|
||||||
|
end_timestamp = data["end_timestamp"]
|
||||||
|
else:
|
||||||
|
end_timestamp = None
|
||||||
|
|
||||||
|
if not isinstance(data["timestamp"], datetime):
|
||||||
|
timestamp = datetime.fromtimestamp(data["timestamp"])
|
||||||
|
else:
|
||||||
|
timestamp = data["timestamp"]
|
||||||
|
|
||||||
data.update({
|
data.update({
|
||||||
"timestamp": datetime.fromtimestamp(data["timestamp"]),
|
"timestamp": timestamp,
|
||||||
"end_timestamp": datetime.fromtimestamp(data["end_timestamp"]) if "end_timestamp" in data and data["end_timestamp"] else None,
|
"end_timestamp": end_timestamp,
|
||||||
"duration": duration
|
"duration": duration
|
||||||
})
|
})
|
||||||
return cls(bot=bot, **data)
|
return cls(bot=bot, **data)
|
||||||
|
|
Loading…
Reference in a new issue