Files
disknext/models/download.py
于小丘 5835b4c626 Add HTTP exception helpers and update models
Introduced utils/http/http_exceptions.py with common HTTP exception helpers for FastAPI. Updated main.py to use a global exception handler that logs and hides internal errors. Refined models/README.md to document new models and relationships, including PhysicalFile and UploadSession, and updated DTO and enum documentation. Simplified ThemeResponse in models/color.py. Improved models/download.py with type annotations, index changes, and import optimizations. Fixed a parameter type in clean.py.

Co-Authored-By: 砂糖橘 <54745033+Foxerine@users.noreply.github.com>
2025-12-25 15:48:21 +08:00

196 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from enum import StrEnum
from typing import TYPE_CHECKING, Annotated
from uuid import UUID
from sqlmodel import Field, Relationship, UniqueConstraint, Index
from .base import SQLModelBase
from .mixin import UUIDTableBaseMixin, TableBaseMixin
if TYPE_CHECKING:
from .user import User
from .task import Task
from .node import Node
class DownloadStatus(StrEnum):
"""下载状态枚举"""
RUNNING = "running"
"""进行中"""
COMPLETED = "completed"
"""已完成"""
ERROR = "error"
"""错误"""
class DownloadType(StrEnum):
"""下载类型枚举"""
# [TODO] 补充具体下载类型
pass
# ==================== Aria2 信息模型 ====================
class DownloadAria2InfoBase(SQLModelBase):
"""Aria2下载信息基础模型"""
info_hash: Annotated[str | None, Field(max_length=40)] = None
"""InfoHashBT种子"""
piece_length: int = 0
"""分片大小"""
num_pieces: int = 0
"""分片数量"""
num_seeders: int = 0
"""做种人数"""
connections: int = 0
"""连接数"""
upload_speed: int = 0
"""上传速度bytes/s"""
upload_length: int = 0
"""已上传大小(字节)"""
error_code: str | None = None
"""错误代码"""
error_message: str | None = None
"""错误信息"""
class DownloadAria2Info(DownloadAria2InfoBase, SQLModelBase, table=True):
"""Aria2下载信息模型与Download一对一关联"""
download_id: UUID = Field(
foreign_key="download.id",
primary_key=True,
ondelete="CASCADE"
)
"""关联的下载任务UUID"""
# 反向关系
download: "Download" = Relationship(back_populates="aria2_info")
"""关联的下载任务"""
class DownloadAria2File(SQLModelBase, TableBaseMixin):
"""Aria2下载文件列表与Download一对多关联"""
download_id: UUID = Field(
foreign_key="download.id",
index=True,
ondelete="CASCADE"
)
"""关联的下载任务UUID"""
file_index: int = Field(ge=1)
"""文件索引从1开始"""
path: str
"""文件路径"""
length: int = 0
"""文件大小(字节)"""
completed_length: int = 0
"""已完成大小(字节)"""
is_selected: bool = True
"""是否选中下载"""
# 反向关系
download: "Download" = Relationship(back_populates="aria2_files")
"""关联的下载任务"""
# ==================== 主模型 ====================
class DownloadBase(SQLModelBase):
pass
class Download(DownloadBase, UUIDTableBaseMixin):
"""离线下载任务模型"""
__table_args__ = (
UniqueConstraint("node_id", "g_id", name="uq_download_node_gid"),
Index("ix_download_user_status", "user_id", "status"),
)
status: DownloadStatus = Field(default=DownloadStatus.RUNNING, sa_column_kwargs={"server_default": "'running'"}, index=True)
"""下载状态"""
type: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
"""任务类型 [TODO] 待定义枚举"""
source: str
"""来源URL或标识"""
total_size: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
"""总大小(字节)"""
downloaded_size: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
"""已下载大小(字节)"""
g_id: str | None = Field(default=None, index=True)
"""Aria2 GID"""
speed: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
"""下载速度bytes/s"""
parent: str | None = Field(default=None, max_length=255)
"""父任务标识"""
error: str | None = Field(default=None)
"""错误信息"""
dst: str
"""目标存储路径"""
# 外键
user_id: UUID = Field(
foreign_key="user.id",
index=True,
ondelete="CASCADE"
)
"""所属用户UUID"""
task_id: int | None = Field(
default=None,
foreign_key="task.id",
index=True,
ondelete="SET NULL"
)
"""关联的任务ID"""
node_id: int = Field(
foreign_key="node.id",
index=True,
ondelete="RESTRICT"
)
"""执行下载的节点ID"""
# 关系
aria2_info: DownloadAria2Info | None = Relationship(
back_populates="download",
sa_relationship_kwargs={"uselist": False, "cascade": "all, delete-orphan"},
)
"""Aria2下载信息"""
aria2_files: list[DownloadAria2File] = Relationship(
back_populates="download",
sa_relationship_kwargs={"cascade": "all, delete-orphan"}
)
"""Aria2文件列表"""
user: "User" = Relationship(back_populates="downloads")
"""所属用户"""
task: "Task" = Relationship(back_populates="downloads")
"""关联的任务"""
node: "Node" = Relationship(back_populates="downloads")
"""执行下载的节点"""