Files
k.eaven bec06bd909 feat: Multi-guild support implementation
- Added multi-guild support with comma-separated AllowedGuildIDs config
- Per-guild embed tracking with isolated state
- Per-server action locking to prevent race conditions across guilds
- Cross-guild embed updates after power actions
- Debug logging for embed update triggers
- Fixed resource usage field formatting (brackets now properly closed)
- Updated config.ini.sample, generate_config.py for backward compatibility
- Updated README.md with multi-guild documentation
- Updated tests for multi-guild support
2026-10-30 10:37:13 +00:00

118 lines
2.6 KiB
Python

"""
Data Models Module
Pydantic models for type-safe data handling throughout the application.
Provides validation and serialization for API responses and internal data.
"""
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field
class ResourceAttributes(BaseModel):
"""Current resource usage attributes from panel API."""
current_state: str
resources: "ResourceUsage"
class ResourceUsage(BaseModel):
"""Individual resource metrics."""
cpu_absolute: float = 0.0
memory_bytes: int = 0
disk_bytes: int = 0
network_rx_bytes: int = 0
network_tx_bytes: int = 0
uptime: int = 0
class ServerAttributes(BaseModel):
"""Server attributes from panel API."""
identifier: str
name: str
description: Optional[str] = None
suspended: bool = False
limits: "ServerLimits" = Field(default_factory=lambda: ServerLimits())
class ServerLimits(BaseModel):
"""Server resource limits."""
cpu: int = 0
memory: int = 0
disk: int = 0
class ServerRelationships(BaseModel):
"""Server relationships data."""
allocations: Optional["AllocationsData"] = None
class AllocationsData(BaseModel):
"""Allocations data container."""
data: List["Allocation"] = Field(default_factory=list)
class Allocation(BaseModel):
"""Individual allocation (IP/port)."""
attributes: "AllocationAttributes"
class AllocationAttributes(BaseModel):
"""Allocation attributes."""
ip_alias: str = "Unknown"
port: int = 0
is_default: bool = False
class ServerData(BaseModel):
"""Complete server data from panel API."""
attributes: ServerAttributes
relationships: Optional[ServerRelationships] = None
class ServerResources(BaseModel):
"""Server resources response from panel API."""
attributes: ResourceAttributes
class APIResponse(BaseModel):
"""Generic API response wrapper."""
status: str = "success"
data: Any = None
message: Optional[str] = None
errors: Optional[List[Dict[str, Any]]] = None
class ServerListResponse(BaseModel):
"""Server list response from panel API."""
data: List[Dict[str, Any]] = Field(default_factory=list)
meta: Optional[Dict[str, Any]] = None
class EmbedLocation(BaseModel):
"""Embed location tracking data with guild context."""
guild_id: int
channel_id: str
message_id: str
# Composite key for storage
@property
def storage_key(self) -> str:
return f"{self.guild_id}:{self.channel_id}:{self.message_id}"
# Rebuild models to resolve forward references
ResourceAttributes.model_rebuild()
ServerAttributes.model_rebuild()