import json from datetime import datetime, timedelta from typing import Literal, Optional from redbot.core.bot import Red 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}" def __repr__(self) -> str: attrs = [ ('type', self.type), ('timestamp', self.timestamp), ('user_id', self.user_id), ('reason', self.reason), ('duration', self.duration), ('end_timestamp', self.end_timestamp), ] joined = ' '.join('%s=%r' % t for t in attrs) return f"<{self.__class__.__name__} {joined}>" 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') and not isinstance(data["duration"], timedelta) and not data["duration"] == "NULL": duration = timedelta_from_string(data["duration"]) elif data.get('duration') and isinstance(data["duration"], timedelta): duration = data["duration"] else: duration = None if data.get('end_timestamp') and not isinstance(data["end_timestamp"], datetime): end_timestamp = datetime.fromtimestamp(data["end_timestamp"]) elif data.get('end_timestamp') 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 }) if "bot" in data: del data["bot"] return cls(bot=bot, **data)