import json from datetime import datetime, timedelta from typing import Literal, Optional from redbot.core.bot import Red from seautils.aurora.models.base import AuroraBaseModel from seautils.aurora.models.partials import PartialUser from seautils.aurora.utils.misc import timedelta_from_string class Change(AuroraBaseModel): type: Literal["ORIGINAL", "RESOLVE", "EDIT"] timestamp: datetime user_id: int reason: Optional[str] = "No reason provided" duration: Optional[timedelta] = None end_timestamp: Optional[datetime] = None @property def unix_timestamp(self) -> int: return int(self.timestamp.timestamp()) def __str__(self): return f"{self.type} {self.user_id} {self.reason}" async def get_user(self) -> "PartialUser": return await PartialUser.from_id(self.bot, self.user_id) @classmethod def from_dict(cls, bot: Red, data: dict) -> "Change": if isinstance(data, str): data = json.loads(data) if "duration" in data and data["duration"] and not isinstance(data["duration"], timedelta) and not data["duration"] == "NULL": duration = timedelta_from_string(data["duration"]) elif "duration" in data and isinstance(data["duration"], timedelta): duration = data["duration"] else: 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"] try: data["user_id"] = int(data["user_id"]) except ValueError: data["user_id"] = 0 data.update({ "timestamp": timestamp, "end_timestamp": end_timestamp, "duration": duration }) return cls(bot=bot, **data)