import json from datetime import datetime, timedelta from typing import Literal, Optional from redbot.core.bot import Red from ..utilities.logger import logger from ..utilities.utils import timedelta_from_string from .base import AuroraBaseModel from .partials import PartialUser class Change(AuroraBaseModel): type: Literal["ORIGINAL", "RESOLVE", "EDIT"] timestamp: datetime user_id: int reason: Optional[str] = None duration: Optional[timedelta] = None end_timestamp: Optional[datetime] = None @property def unix_timestamp(self) -> int: return int(self.timestamp.timestamp()) @property def unix_end_timestamp(self) -> Optional[int]: if self.end_timestamp: return int(self.end_timestamp.timestamp()) return None 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 data.get('duration'): logger.debug(f"Duration: {data['duration']}") 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)