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])