120 lines
3.6 KiB
Python
120 lines
3.6 KiB
Python
|
|
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__})
|