144 lines
3.6 KiB
Python
Executable File
144 lines
3.6 KiB
Python
Executable File
"""
|
|
Data models for file-centric download system.
|
|
Each download record represents ONE file, not a batch.
|
|
"""
|
|
|
|
from pydantic import BaseModel
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
|
|
class FileDownload(BaseModel):
|
|
"""Represents a single file download record in the database."""
|
|
id: int
|
|
batch_id: str
|
|
|
|
# File info
|
|
ge_id: str
|
|
lang: str
|
|
file_name: str
|
|
file_path: str # Relative path in source
|
|
|
|
# Mode & status
|
|
mode: str # 'api' or 'sharing'
|
|
status: str # 'pending', 'downloading', 'completed', 'failed', 'cancelled'
|
|
|
|
# Paths
|
|
destination_path: Optional[str] = None
|
|
|
|
# Progress
|
|
file_size: Optional[int] = None
|
|
downloaded_size: int = 0
|
|
progress_percent: Decimal = Decimal('0.00')
|
|
|
|
# Timestamps
|
|
created_at: datetime
|
|
started_at: Optional[datetime] = None
|
|
completed_at: Optional[datetime] = None
|
|
|
|
# Error handling
|
|
error_message: Optional[str] = None
|
|
retry_count: int = 0
|
|
|
|
# Metadata
|
|
sharing_id: Optional[str] = None
|
|
mongodb_path: Optional[str] = None
|
|
|
|
class Config:
|
|
from_attributes = True # For Pydantic v2 (orm_mode in v1)
|
|
|
|
|
|
# ==================== REQUEST MODELS ====================
|
|
|
|
class FileInfo(BaseModel):
|
|
"""Single file information for batch download requests."""
|
|
name: str
|
|
path: str # Relative path in source
|
|
isdir: bool = False # For API mode
|
|
is_folder: Optional[bool] = None # For Sharing mode (alias)
|
|
|
|
|
|
class CreateDownloadBatchRequest(BaseModel):
|
|
"""
|
|
Request to create a batch of file downloads (API mode).
|
|
Each file will become a separate download record.
|
|
"""
|
|
files: list[FileInfo]
|
|
ge_id: str
|
|
lang: str
|
|
|
|
|
|
class CreateSharingDownloadBatchRequest(BaseModel):
|
|
"""
|
|
Request to create batch downloads from sharing link.
|
|
"""
|
|
sharing_id: str
|
|
files: list[FileInfo]
|
|
ge_id: Optional[str] = None
|
|
lang: Optional[str] = None
|
|
|
|
|
|
class UpdateDownloadRequest(BaseModel):
|
|
"""Request to update a single download (cancel/retry)."""
|
|
action: str # 'retry' or 'cancel'
|
|
|
|
|
|
# ==================== RESPONSE MODELS ====================
|
|
|
|
class DownloadBatchResponse(BaseModel):
|
|
"""Response after creating a batch of downloads."""
|
|
success: bool
|
|
batch_id: str
|
|
file_count: int
|
|
download_ids: list[int] # List of created download IDs
|
|
message: str
|
|
|
|
|
|
class DownloadResponse(BaseModel):
|
|
"""Response for single download operation."""
|
|
success: bool
|
|
download: Optional[FileDownload] = None
|
|
message: str
|
|
|
|
|
|
class DownloadListResponse(BaseModel):
|
|
"""Response for listing downloads."""
|
|
success: bool
|
|
downloads: list[FileDownload]
|
|
count: int
|
|
|
|
|
|
# ==================== BATCH GROUPING ====================
|
|
|
|
class DownloadBatch(BaseModel):
|
|
"""
|
|
Grouped view of downloads for UI display.
|
|
Groups files by batch_id for better UX.
|
|
"""
|
|
batch_id: str
|
|
ge_id: str
|
|
lang: str
|
|
mode: str
|
|
|
|
# Batch-level stats
|
|
total_files: int
|
|
completed_files: int
|
|
failed_files: int
|
|
total_size: int
|
|
downloaded_size: int
|
|
|
|
# Batch status (derived from files)
|
|
status: str # 'downloading', 'completed', 'partial_failed', 'failed'
|
|
|
|
# Timestamps (min/max from files)
|
|
created_at: datetime
|
|
started_at: Optional[datetime] = None
|
|
completed_at: Optional[datetime] = None
|
|
|
|
# Duration (if completed)
|
|
duration_seconds: Optional[float] = None
|
|
|
|
# Individual files in this batch
|
|
files: list[FileDownload]
|