ge-tool/backend/common/models.py

144 lines
3.6 KiB
Python
Raw Permalink Normal View History

2025-12-10 06:41:43 +00:00
"""
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]