Compare commits
2 commits
2c336ff70c
...
e7e8d60f3b
Author | SHA1 | Date | |
---|---|---|---|
e7e8d60f3b | |||
eea66607d9 |
3 changed files with 99 additions and 71 deletions
|
@ -1,5 +1,5 @@
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Literal, Optional, Union
|
||||||
|
|
||||||
from discord import Forbidden, HTTPException, InvalidData, NotFound
|
from discord import Forbidden, HTTPException, InvalidData, NotFound
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
@ -10,6 +10,11 @@ from aurora.utilities.utils import generate_dict
|
||||||
|
|
||||||
class AuroraBaseModel(BaseModel):
|
class AuroraBaseModel(BaseModel):
|
||||||
"""Base class for all models in Aurora."""
|
"""Base class for all models in Aurora."""
|
||||||
|
|
||||||
|
def to_json(self, indent: int = None, file: Any = None, **kwargs):
|
||||||
|
from aurora.utilities.json import dump, dumps
|
||||||
|
return dump(self.model_dump(), file, indent=indent, **kwargs) if file else dumps(self.model_dump(), indent=indent, **kwargs)
|
||||||
|
|
||||||
class Moderation(AuroraBaseModel):
|
class Moderation(AuroraBaseModel):
|
||||||
bot: ClassVar[Red]
|
bot: ClassVar[Red]
|
||||||
moderation_id: int
|
moderation_id: int
|
||||||
|
@ -52,6 +57,11 @@ class Moderation(AuroraBaseModel):
|
||||||
return await PartialUser.from_id(self.bot, self.resolved_by)
|
return await PartialUser.from_id(self.bot, self.resolved_by)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def get_role(self) -> Optional["PartialRole"]:
|
||||||
|
if self.role_id:
|
||||||
|
return await PartialRole.from_id(self.bot, self.guild_id, self.role_id)
|
||||||
|
return None
|
||||||
|
|
||||||
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}"
|
||||||
|
|
||||||
|
@ -76,11 +86,26 @@ class Moderation(AuroraBaseModel):
|
||||||
def from_dict(cls, bot: Red, data: dict) -> "Moderation":
|
def from_dict(cls, bot: Red, data: dict) -> "Moderation":
|
||||||
return cls(bot=bot, **data)
|
return cls(bot=bot, **data)
|
||||||
|
|
||||||
def to_json(self, indent: int = None, file: Any = None):
|
def to_json(self, indent: int = None, file: Any = None, **kwargs):
|
||||||
from aurora.utilities.json import dump, dumps
|
from aurora.utilities.json import dump, dumps
|
||||||
return dump(self.model_dump(exclude={"bot", "guild_id"}), file, indent=indent) if file else dumps(self.model_dump(exclude={"bot", "guild_id"}), indent=indent)
|
return dump(self.model_dump(exclude={"bot", "guild_id"}), file, indent=indent, **kwargs) if file else dumps(self.model_dump(exclude={"bot", "guild_id"}), indent=indent, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class Change(AuroraBaseModel):
|
||||||
|
type: Literal["ORIGINAL", "RESOLVE", "EDIT"]
|
||||||
|
timestamp: datetime
|
||||||
|
reason: str
|
||||||
|
user_id: int
|
||||||
|
duration: Optional[timedelta]
|
||||||
|
end_timestamp: Optional[datetime]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.type} {self.user_id} {self.reason}"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: dict) -> "Change":
|
||||||
|
return cls(**data)
|
||||||
|
|
||||||
class PartialUser(AuroraBaseModel):
|
class PartialUser(AuroraBaseModel):
|
||||||
id: int
|
id: int
|
||||||
username: str
|
username: str
|
||||||
|
@ -103,6 +128,7 @@ class PartialUser(AuroraBaseModel):
|
||||||
except NotFound:
|
except NotFound:
|
||||||
return cls(id=user_id, username="Deleted User", discriminator=0)
|
return cls(id=user_id, username="Deleted User", discriminator=0)
|
||||||
|
|
||||||
|
|
||||||
class PartialChannel(AuroraBaseModel):
|
class PartialChannel(AuroraBaseModel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
@ -127,3 +153,26 @@ class PartialChannel(AuroraBaseModel):
|
||||||
if e == Forbidden:
|
if e == Forbidden:
|
||||||
return cls(id=channel_id, name="Forbidden Channel")
|
return cls(id=channel_id, name="Forbidden Channel")
|
||||||
return cls(id=channel_id, name="Deleted Channel")
|
return cls(id=channel_id, name="Deleted Channel")
|
||||||
|
|
||||||
|
class PartialRole(AuroraBaseModel):
|
||||||
|
id: int
|
||||||
|
guild_id: int
|
||||||
|
name: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mention(self):
|
||||||
|
return f"<@&{self.id}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.mention
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_id(cls, bot: Red, guild_id: int, role_id: int) -> "PartialRole":
|
||||||
|
try:
|
||||||
|
guild = await bot.fetch_guild(guild_id, with_counts=False)
|
||||||
|
except (Forbidden, HTTPException):
|
||||||
|
return cls(id=role_id, guild_id=guild_id, name="Forbidden Role")
|
||||||
|
role = guild.get_role(role_id)
|
||||||
|
if not role:
|
||||||
|
return cls(id=role_id, guild_id=guild_id, name="Deleted Role")
|
||||||
|
return cls(id=role.id, guild_id=guild_id, name=role.name)
|
||||||
|
|
|
@ -2,17 +2,13 @@
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from discord import (Color, Embed, Guild, Interaction, InteractionMessage,
|
from discord import Color, Embed, Guild, Interaction, InteractionMessage, Member, Role, User
|
||||||
Member, Role, User)
|
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.utils.chat_formatting import (bold, box, error,
|
from redbot.core.utils.chat_formatting import bold, box, error, humanize_timedelta, warning
|
||||||
humanize_timedelta, warning)
|
|
||||||
|
|
||||||
from aurora.models import Moderation
|
from aurora.models import Moderation
|
||||||
from aurora.utilities.config import config
|
from aurora.utilities.config import config
|
||||||
from aurora.utilities.utils import (fetch_channel_dict, fetch_user_dict,
|
from aurora.utilities.utils import fetch_channel_dict, fetch_user_dict, get_bool_emoji, get_next_case_number, get_pagesize_str
|
||||||
get_bool_emoji, get_next_case_number,
|
|
||||||
get_pagesize_str)
|
|
||||||
|
|
||||||
|
|
||||||
async def message_factory(
|
async def message_factory(
|
||||||
|
@ -155,105 +151,79 @@ async def log_factory(
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
|
async def case_factory(interaction: Interaction, moderation: Moderation) -> Embed:
|
||||||
"""This function creates a case embed from set parameters.
|
"""This function creates a case embed from set parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
interaction (Interaction): The interaction object.
|
interaction (discord.Interaction): The interaction object.
|
||||||
case_dict (dict): The case dictionary.
|
moderation (aurora.models.Moderation): The moderation object.
|
||||||
"""
|
"""
|
||||||
if case_dict["target_type"] == "USER":
|
target = await moderation.get_target()
|
||||||
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
|
moderator = await moderation.get_moderator()
|
||||||
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"])
|
|
||||||
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_name = (
|
|
||||||
f"`{moderator_user['name']}`"
|
|
||||||
if moderator_user["discriminator"] == "0"
|
|
||||||
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
|
|
||||||
embed = Embed(
|
embed = Embed(
|
||||||
title=f"📕 Case #{case_dict['moderation_id']:,}",
|
title=f"📕 Case #{moderation.id:,}",
|
||||||
color=await interaction.client.get_embed_color(interaction.channel),
|
color=await interaction.client.get_embed_color(interaction.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>"
|
embed.description = f"**Type:** {str.title(moderation.type)}\n**Target:** {target.name} ({target.id})\n**Moderator:** {moderator.name} ({moderator.id})\n**Resolved:** {moderation.resolved}\n**Timestamp:** <t:{moderation.timestamp}> | <t:{moderation.timestamp}:R>"
|
||||||
|
|
||||||
if case_dict["duration"] != "NULL":
|
if moderation.duration:
|
||||||
td = timedelta(
|
|
||||||
**{
|
|
||||||
unit: int(val)
|
|
||||||
for unit, val in zip(
|
|
||||||
["hours", "minutes", "seconds"], case_dict["duration"].split(":")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
duration_embed = (
|
duration_embed = (
|
||||||
f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
|
f"{humanize_timedelta(timedelta=moderation.duration)} | <t:{moderation.timestamp}:R>"
|
||||||
if bool(case_dict["expired"]) is False
|
if moderation.expired is False
|
||||||
else str(humanize_timedelta(timedelta=td))
|
else str(humanize_timedelta(timedelta=moderation.duration))
|
||||||
)
|
)
|
||||||
embed.description += f"\n**Duration:** {duration_embed}\n**Expired:** {bool(case_dict['expired'])}"
|
embed.description += f"\n**Duration:** {duration_embed}\n**Expired:** {moderation.expired}"
|
||||||
|
|
||||||
embed.description += (
|
embed.description += (
|
||||||
f"\n**Changes:** {len(case_dict['changes']) - 1}"
|
f"\n**Changes:** {len(moderation.changes) - 1}"
|
||||||
if case_dict["changes"]
|
if moderation.changes
|
||||||
else "\n**Changes:** 0"
|
else "\n**Changes:** 0"
|
||||||
)
|
)
|
||||||
|
|
||||||
if case_dict["role_id"]:
|
if moderation.role_id:
|
||||||
embed.description += f"\n**Role:** <@&{case_dict['role_id']}>"
|
role = await moderation.get_role()
|
||||||
|
embed.description += f"\n**Role:** {role.name}"
|
||||||
|
|
||||||
if case_dict["metadata"]:
|
if moderation.metadata:
|
||||||
if case_dict["metadata"]["imported_from"]:
|
if moderation.metadata["imported_from"]:
|
||||||
embed.description += (
|
embed.description += (
|
||||||
f"\n**Imported From:** {case_dict['metadata']['imported_from']}"
|
f"\n**Imported From:** {moderation.metadata['imported_from']}"
|
||||||
|
)
|
||||||
|
if moderation.metadata["imported_timestamp"]:
|
||||||
|
embed.description += (
|
||||||
|
f"\n**Imported Timestamp:** <t:{moderation.metadata['imported_timestamp']}> | <t:{moderation.metadata['imported_timestamp']}:R>"
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
|
embed.add_field(name="Reason", value=box(moderation.reason), inline=False)
|
||||||
|
|
||||||
if case_dict["resolved"] == 1:
|
if moderation.resolved:
|
||||||
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
|
resolved_user = await moderation.get_resolved_by()
|
||||||
resolved_name = (
|
|
||||||
f"`{resolved_user['name']}`"
|
|
||||||
if resolved_user["discriminator"] == "0"
|
|
||||||
else f"`{resolved_user['name']}#{resolved_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Resolve Reason",
|
name="Resolve Reason",
|
||||||
value=f"Resolved by {resolved_name} ({resolved_user['id']}) for:\n{box(case_dict['resolve_reason'])}",
|
value=f"Resolved by {resolved_user.name} ({resolved_user.id}) for:\n{box(moderation.resolve_reason)}",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
|
async def changes_factory(interaction: Interaction, moderation: Moderation) -> Embed:
|
||||||
"""This function creates a changes embed from set parameters.
|
"""This function creates a changes embed from set parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
interaction (Interaction): The interaction object.
|
interaction (discord.Interaction): The interaction object.
|
||||||
case_dict (dict): The case dictionary.
|
moderation (aurora.models.Moderation): The moderation object.
|
||||||
"""
|
"""
|
||||||
embed = Embed(
|
embed = Embed(
|
||||||
title=f"📕 Case #{case_dict['moderation_id']:,} Changes",
|
title=f"📕 Case #{moderation.id:,} Changes",
|
||||||
color=await interaction.client.get_embed_color(interaction.channel),
|
color=await interaction.client.get_embed_color(interaction.channel),
|
||||||
)
|
)
|
||||||
|
|
||||||
memory_dict = {}
|
memory_dict = {}
|
||||||
|
|
||||||
if case_dict["changes"]:
|
if moderation.changes:
|
||||||
for change in case_dict["changes"]:
|
for change in moderation.changes:
|
||||||
if change["user_id"] not in memory_dict:
|
if change["user_id"] not in memory_dict:
|
||||||
memory_dict[str(change["user_id"])] = await fetch_user_dict(
|
memory_dict[str(change["user_id"])] = await fetch_user_dict(
|
||||||
interaction.client, change["user_id"]
|
interaction.client, change["user_id"]
|
||||||
|
|
|
@ -9,9 +9,11 @@ from discord.errors import Forbidden, NotFound
|
||||||
from redbot.core import commands, data_manager
|
from redbot.core import commands, data_manager
|
||||||
from redbot.core.utils.chat_formatting import error
|
from redbot.core.utils.chat_formatting import error
|
||||||
|
|
||||||
|
from aurora.models import Change
|
||||||
from aurora.utilities.config import config
|
from aurora.utilities.config import config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def check_permissions(
|
def check_permissions(
|
||||||
user: User,
|
user: User,
|
||||||
permissions: list,
|
permissions: list,
|
||||||
|
@ -130,6 +132,13 @@ def generate_dict(result: dict, guild_id: int) -> dict:
|
||||||
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
||||||
else:
|
else:
|
||||||
duration = None
|
duration = None
|
||||||
|
|
||||||
|
if result[14] is not None:
|
||||||
|
changes = json.loads(result[14].strip('"').replace('\\"', '"'))
|
||||||
|
change_obj_list = []
|
||||||
|
for change in changes:
|
||||||
|
change_obj_list.append(Change(**change))
|
||||||
|
|
||||||
case = {
|
case = {
|
||||||
"moderation_id": int(result[0]),
|
"moderation_id": int(result[0]),
|
||||||
"guild_id": int(guild_id),
|
"guild_id": int(guild_id),
|
||||||
|
@ -146,7 +155,7 @@ def generate_dict(result: dict, guild_id: int) -> dict:
|
||||||
"resolved_by": result[11],
|
"resolved_by": result[11],
|
||||||
"resolve_reason": result[12],
|
"resolve_reason": result[12],
|
||||||
"expired": bool(result[13]),
|
"expired": bool(result[13]),
|
||||||
"changes": json.loads(result[14].strip('"').replace('\\"', '"')) if result[14] else [],
|
"changes": change_obj_list if result[14] else [],
|
||||||
"metadata": json.loads(result[15].strip('"').replace('\\"', '"')) if result[15] else {},
|
"metadata": json.loads(result[15].strip('"').replace('\\"', '"')) if result[15] else {},
|
||||||
}
|
}
|
||||||
return case
|
return case
|
||||||
|
|
Loading…
Add table
Reference in a new issue