from __future__ import annotations from dataclasses import dataclass, field from enum import Enum class TicketStatus(str, Enum): OPEN = "open" CLOSED = "closed" @dataclass class TicketCategory: id: str name: str emoji: str = "" description: str = "" staff_role_id: int | None = None discord_category_id: int | None = None def to_dict(self) -> dict: return { "id": self.id, "name": self.name, "emoji": self.emoji, "description": self.description, "staff_role_id": self.staff_role_id, "discord_category_id": self.discord_category_id, } @classmethod def from_dict(cls, data: dict) -> TicketCategory: return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__}) @dataclass class TicketMessage: author_id: int author_name: str content: str timestamp: str attachments: list[str] = field(default_factory=list) is_staff: bool = False @dataclass class TicketData: channel_id: int guild_id: int user_id: int category_id: str status: TicketStatus = TicketStatus.OPEN created_at: str = "" closed_at: str | None = None closed_by: int | None = None messages: list[TicketMessage] = field(default_factory=list) reason: str = "" def to_dict(self) -> dict: return { "channel_id": self.channel_id, "guild_id": self.guild_id, "user_id": self.user_id, "category_id": self.category_id, "status": self.status.value, "created_at": self.created_at, "closed_at": self.closed_at, "closed_by": self.closed_by, "messages": [ { "author_id": m.author_id, "author_name": m.author_name, "content": m.content, "timestamp": m.timestamp, "attachments": m.attachments, "is_staff": m.is_staff, } for m in self.messages ], "reason": self.reason, } @classmethod def from_dict(cls, data: dict) -> TicketData: messages = [TicketMessage(**m) for m in data.pop("messages", [])] data["status"] = TicketStatus(data.get("status", "open")) data.pop("transcript_path", None) data.pop("rating", None) data.pop("feedback", None) return cls(messages=messages, **{k: v for k, v in data.items() if k in cls.__dataclass_fields__}) @dataclass class GuildTicketConfig: guild_id: int enabled: bool = False categories: list[TicketCategory] = field(default_factory=list) staff_role_id: int | None = None log_channel_id: int | None = None panel_channel_id: int | None = None panel_message_id: int | None = None transcript_enabled: bool = True def to_dict(self) -> dict: return { "guild_id": self.guild_id, "enabled": self.enabled, "categories": [c.to_dict() for c in self.categories], "staff_role_id": self.staff_role_id, "log_channel_id": self.log_channel_id, "panel_channel_id": self.panel_channel_id, "panel_message_id": self.panel_message_id, "transcript_enabled": self.transcript_enabled, } @classmethod def from_dict(cls, data: dict) -> GuildTicketConfig: categories = [TicketCategory.from_dict(c) for c in data.pop("categories", [])] return cls(categories=categories, **{k: v for k, v in data.items() if k in cls.__dataclass_fields__})