from typing import Annotated, Sequence from fastapi import APIRouter, File, HTTPException, UploadFile from fastapi.params import Depends from sqlmodel import Session, select from nyahome.config import config_manager from nyahome.database import ModelUploadFile, ModelUser, get_session from nyahome.service.file_service import UPLOAD_DIR, s_get_safe_filename, s_save_upload_file from .auth import verify_token file_router = APIRouter(tags=["File"], prefix="/file") @file_router.get("/", name="获取文件列表") async def get_files( user: Annotated[ModelUser, Depends(verify_token)], session: Annotated[Session, Depends(get_session)], ) -> Sequence[ModelUploadFile]: """ 获取用户上传的文件列表。 Returns: ModelUploadFile 列表。 """ files: Sequence[ModelUploadFile] = session.exec( select(ModelUploadFile).where(ModelUploadFile.uploader_id == user.id) ).all() return files @file_router.post("/upload/", name="上传文件") async def file_upload( file: Annotated[UploadFile, File()], user: Annotated[ModelUser, Depends(verify_token)], session: Annotated[Session, Depends(get_session)], ) -> ModelUploadFile: """ 仅允许单文件上传。 文件存储在 `.nyahome/contents` 目录下,由 uuid4 重命名,保留原拓展名。 允许上传的文件拓展名由 NyaHome 设置 `allow_upload_file_extensions` 约束。 对于不允许上传的文件类型,将抛出 400 错误。 Args: file: 文件对象 user: 经验证的用户 session: 数据库连接对象 Raises: HTTPException: 400 表示上传的文件类型不允许。文件类型仅由拓展名判断,不检查 MIME。 Returns: ModelUploadFile """ try: safe_name = s_get_safe_filename(file.filename) # type: ignore[arg-type] dest_path = UPLOAD_DIR / safe_name except TypeError as e: raise HTTPException(status_code=400, detail=str(e)) from e try: await s_save_upload_file(dest_path, file) except TypeError as e: raise HTTPException(status_code=500, detail=str(e)) from e download_url = f"{config_manager.get('site_url', 'http://localhost:9000')}/download/{safe_name}" upload_file = ModelUploadFile( original_name=file.filename, safe_name=safe_name, download_url=download_url, uploader_id=user.id, ) session.add(upload_file) session.commit() session.refresh(upload_file) return upload_file