You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.7 KiB
Python
72 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends, Query, Request
|
|
from fastapi.responses import StreamingResponse
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from iti.auth import require_user
|
|
from iti.db import get_db
|
|
from iti.exceptions import BizError
|
|
from iti.responses import ok
|
|
from iti.storage import StorageManager
|
|
|
|
from iti_system.models import SysFile
|
|
from iti_system.services import dump_file, get_or_404
|
|
|
|
|
|
router = APIRouter(prefix="/file", tags=["common.file"])
|
|
|
|
|
|
@router.get("/share/{share_code}")
|
|
def share_file(share_code: str, password: str | None = Query(default=None), db: Session = Depends(get_db)):
|
|
item = db.scalar(select(SysFile).where(SysFile.share_code == share_code))
|
|
if item is None:
|
|
raise BizError("分享不存在", code=404)
|
|
if item.share_password and item.share_password != password:
|
|
raise BizError("分享密码错误", code=403)
|
|
item.share_count += 1
|
|
db.commit()
|
|
return ok(dump_file(item))
|
|
|
|
|
|
@router.get("/share/{share_code}/download")
|
|
def share_download(share_code: str, password: str | None = Query(default=None), db: Session = Depends(get_db)):
|
|
item = db.scalar(select(SysFile).where(SysFile.share_code == share_code))
|
|
if item is None:
|
|
raise BizError("分享不存在", code=404)
|
|
if item.share_password and item.share_password != password:
|
|
raise BizError("分享密码错误", code=403)
|
|
item.share_count += 1
|
|
db.commit()
|
|
return ok(dump_file(item))
|
|
|
|
|
|
@router.get("/{file_id}/download", dependencies=[Depends(require_user)])
|
|
def download_file(file_id: str, request: Request, db: Session = Depends(get_db)):
|
|
item = get_or_404(db, SysFile, file_id, "文件不存在")
|
|
storage = StorageManager.get_storage(
|
|
item.storage_type,
|
|
config=request.app.state.config.file_storage,
|
|
base_dir=request.app.state.config.base_dir,
|
|
)
|
|
stream = storage.download(item.file_key)
|
|
return StreamingResponse(
|
|
stream,
|
|
media_type=item.mime_type or "application/octet-stream",
|
|
headers={"Content-Disposition": f'attachment; filename="{item.filename}"'},
|
|
)
|
|
|
|
|
|
@router.get("/{file_id}/preview", dependencies=[Depends(require_user)])
|
|
def preview_file(file_id: str, db: Session = Depends(get_db)):
|
|
return ok(dump_file(get_or_404(db, SysFile, file_id, "文件不存在")))
|
|
|
|
|
|
@router.get("/{file_id}/thumbnail", dependencies=[Depends(require_user)])
|
|
def thumbnail_file(file_id: str, w: int = 200, h: int = 200, mode: str = "fit", db: Session = Depends(get_db)):
|
|
item = get_or_404(db, SysFile, file_id, "文件不存在")
|
|
data = dump_file(item)
|
|
data.update({"width": w, "height": h, "mode": mode})
|
|
return ok(data)
|