"""Data models for the web application.""" from dataclasses import dataclass from datetime import datetime, timezone from typing import Optional @dataclass class SearchResult: """Represents a YouTube search result.""" id: str title: str url: str thumbnail: str author: str length: str view_count: Optional[int] = None is_short: bool = False is_playlist: bool = False description: str = "" published: str = "" @dataclass class QueueItem: """Represents a download queue item.""" id: str video_id: str title: str url: str thumbnail: str = "" status: str = "pending" # pending, downloading, completed, failed, cancelled progress: float = 0.0 category: str = "" network_folder: Optional[str] = None added_at: str = "" completed_at: Optional[str] = None error_message: Optional[str] = None download_path: Optional[str] = None file_size: Optional[str] = None speed: Optional[str] = None eta: Optional[str] = None item_type: str = "video" # video or playlist quality: Optional[str] = None # e.g. "360", "480", "720", "1080", "best" def __post_init__(self): if not self.added_at: self.added_at = datetime.now(timezone.utc).isoformat() def to_dict(self) -> dict: return { "id": self.id, "videoId": self.video_id, "title": self.title, "url": self.url, "thumbnail": self.thumbnail, "status": self.status, "progress": self.progress, "category": self.category, "network_folder": self.network_folder, "addedAt": self.added_at, "completedAt": self.completed_at, "errorMessage": self.error_message, "downloadPath": self.download_path, "fileSize": self.file_size, "speed": self.speed, "eta": self.eta, "type": self.item_type, "quality": self.quality, } @dataclass class ArchiveItem: """Represents a downloaded video in the archive.""" video_id: str title: str url: str description: str = "" thumbnail: str = "" channel: str = "" views: int = 0 duration: str = "" category: str = "" download_path: str = "" network_share_path: Optional[str] = None file_size: Optional[int] = None download_date: str = "" item_type: str = "video" # video or playlist def __post_init__(self): if not self.download_date: self.download_date = datetime.now(timezone.utc).isoformat() def to_dict(self) -> dict: return { "videoId": self.video_id, "title": self.title, "url": self.url, "description": self.description, "thumbnail": self.thumbnail, "channel": self.channel, "views": self.views, "duration": self.duration, "category": self.category, "downloadPath": self.download_path, "networkSharePath": self.network_share_path, "fileSize": self.file_size, "downloadDate": self.download_date, "type": self.item_type, } @dataclass class SearchRecent: """Represents a recent search query.""" query: str searched_at: str = "" def __post_init__(self): if not self.searched_at: self.searched_at = datetime.now(timezone.utc).isoformat()