Newer
Older
bugtrail / server / app / routers / uploads.py
import uuid

from fastapi import APIRouter, Depends, HTTPException, UploadFile, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from ..db import get_session
from ..deps import require_user
from ..models import File
from ..schemas import UploadOut
from ..storage import safe_filename, store_upload

router = APIRouter(prefix="/uploads", tags=["uploads"])


@router.post("", response_model=UploadOut, status_code=status.HTTP_201_CREATED)
async def upload_file(
    file: UploadFile,
    user=Depends(require_user),
    db: AsyncSession = Depends(get_session),
) -> UploadOut:
    sha, rel_path, size, mime = await store_upload(file)
    result = await db.execute(select(File).where(File.sha256 == sha))
    existing = result.scalar_one_or_none()
    if existing is not None:
        return UploadOut(file_id=existing.id, mime=existing.mime, size=existing.size, filename=safe_filename(file.filename or "file"))
    record = File(sha256=sha, path=rel_path, mime=mime, size=size)
    db.add(record)
    await db.commit()
    await db.refresh(record)
    return UploadOut(file_id=record.id, mime=mime, size=size, filename=safe_filename(file.filename or "file"))


@router.get("/{file_id}")
async def file_meta(file_id: uuid.UUID, db: AsyncSession = Depends(get_session)):
    record = await db.get(File, file_id)
    if record is None:
        raise HTTPException(status.HTTP_404_NOT_FOUND, "File not found")
    return UploadOut(file_id=record.id, mime=record.mime, size=record.size, filename=record.path.rsplit("/", 1)[-1])