from datetime import datetime from typing import List, Optional from pydantic import BaseModel, Field from .db_models import ThemeType, DownloadStatus # ============== AnimeThemes Search ============== class AnimeSearchResult(BaseModel): """Single anime search result from AnimeThemes.""" animethemes_slug: str title_english: Optional[str] = None year: Optional[int] = None poster_url: Optional[str] = None class Config: from_attributes = True class SearchResponse(BaseModel): """Response for anime search.""" results: List[AnimeSearchResult] total: int # ============== Anime Themes ============== class ThemeInfo(BaseModel): """Information about a single anime theme (OP/ED).""" id: int theme_type: ThemeType sequence: int full_name: str # "OP1", "ED2" song_title: Optional[str] = None artist: Optional[str] = None video_url: Optional[str] = None is_downloaded: bool download_status: Optional[DownloadStatus] = None file_size_bytes: Optional[int] = None class Config: from_attributes = True class AnimeDetailResponse(BaseModel): """Detailed anime info with themes.""" id: int animethemes_slug: str title_english: Optional[str] = None year: Optional[int] = None poster_url: Optional[str] = None themes: List[ThemeInfo] class Config: from_attributes = True # ============== Download Queue ============== class AddToQueueRequest(BaseModel): """Request to add specific themes to download queue.""" theme_ids: List[int] = Field(..., min_length=1) class AddAllThemesRequest(BaseModel): """Request to add all themes from an anime.""" anime_id: int class QueueTaskResponse(BaseModel): """Single task in the download queue.""" id: int theme_id: int anime_title: str theme_name: str # "OP1", "ED2" song_title: Optional[str] = None status: DownloadStatus progress_percent: int error_message: Optional[str] = None estimated_size_bytes: int created_at: datetime started_at: Optional[datetime] = None completed_at: Optional[datetime] = None class Config: from_attributes = True class QueueStatusResponse(BaseModel): """Current status of the download queue.""" tasks: List[QueueTaskResponse] total_queued: int total_downloading: int total_done: int total_failed: int estimated_queue_size_bytes: int worker_running: bool = False # Indicates if download worker is currently active # ============== Storage Stats ============== class StorageStatsResponse(BaseModel): """S3 storage usage statistics.""" used_bytes: int limit_bytes: int used_percent: float available_bytes: int can_download: bool # False if limit exceeded openings_count: int