import json from datetime import datetime, timedelta from typing import Literal, Optional from redbot.core.bot import Red from ..models.base import AuroraBaseModel from ..models.partials import PartialUser from ..utilities.logger import logger class Change(AuroraBaseModel): type: Literal["ORIGINAL", "RESOLVE", "EDIT"] timestamp: datetime reason: str user_id: int 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": logger.trace("Creating Change from dict (%s): %s", type(data), data) if isinstance(data, str): data = json.loads(data) logger.trace("Change data was a string, converted to dict: %s", data) if "duration" in data and data["duration"] and not isinstance(data["duration"], timedelta): hours, minutes, seconds = map(int, data["duration"].split(':')) duration = timedelta(hours=hours, minutes=minutes, seconds=seconds) 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"] data.update({ "timestamp": timestamp, "end_timestamp": end_timestamp, "duration": duration, "user_id": int(data["user_id"]) }) return cls(bot=bot, **data)