from typing import Optional, List, Any from pydantic import BaseModel, Field class AddMagnetRequest(BaseModel): magnet: str = Field(..., description="마그넷 링크 (magnet:?xt=urn:btih:...) 또는 토렌트 URL") download_dir: Optional[str] = Field(None, description="저장 경로 (비워둘 시 Transmission 기본값 사용)") paused: bool = Field(False, description="추가 후 일시정지 상태로 둘지 여부") class TorrentItem(BaseModel): id: int name: str status: int status_label: str = "" percent_done: float rate_download: int rate_upload: int total_size: int eta: Optional[int] = None download_dir: Optional[str] = None error_string: Optional[str] = None is_finished: bool = False class ApiResponse(BaseModel): success: bool message: str data: Optional[Any] = None class StatusResponse(BaseModel): connected: bool rpc_url: str version: Optional[str] = None torrents_count: int = 0 class ExtractArchiveRequest(BaseModel): path: str = Field(..., description="압축 파일 상대 경로") password: Optional[str] = Field(None, description="압축 해제 암호 (비밀번호)") create_subfolder: bool = Field(True, description="하위 폴더를 생성하여 압축 풀기 여부") custom_dest: Optional[str] = Field(None, description="커스텀 해제 폴더명") delete_archive: bool = Field(False, description="해제 후 원본 압축파일 삭제 여부") class BatchDownloadRequest(BaseModel): paths: List[str] = Field(..., description="다운로드할 파일 및 폴더 상대 경로 목록") zip_name: Optional[str] = Field("bundle.zip", description="다운로드될 압축 파일명")