58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
from fastapi import APIRouter, Depends, UploadFile, File, HTTPException
|
|
from fastapi.responses import FileResponse
|
|
from sqlalchemy.orm import Session
|
|
import uuid
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
from app.db import get_db
|
|
from app.auth.dependencies import get_current_user
|
|
from app.config import settings
|
|
|
|
router = APIRouter(prefix="/documents", tags=["Assets"])
|
|
|
|
def get_asset_path(document_id: str, ref: str) -> Path:
|
|
# Ensure directory exists
|
|
dir_path = settings.PDF_STORAGE_PATH / "assets" / document_id
|
|
dir_path.mkdir(parents=True, exist_ok=True)
|
|
return dir_path / ref
|
|
|
|
@router.post("/{id}/assets")
|
|
async def upload_asset(
|
|
id: str,
|
|
file: UploadFile = File(...),
|
|
user_id: int = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Upload a binary asset (like an image or signature) for a document."""
|
|
# In a real app we'd verify the user owns the document here
|
|
# For this single-user app, we trust the ID
|
|
|
|
if not file.content_type or not file.content_type.startswith("image/"):
|
|
raise HTTPException(status_code=400, detail="Only image assets are supported")
|
|
|
|
ref = str(uuid.uuid4())
|
|
filepath = get_asset_path(id, ref)
|
|
|
|
try:
|
|
with open(filepath, "wb") as f:
|
|
shutil.copyfileobj(file.file, f)
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to save asset: {e}")
|
|
|
|
return {
|
|
"ref": ref,
|
|
"url": f"/api/v1/documents/{id}/assets/{ref}"
|
|
}
|
|
|
|
@router.get("/{id}/assets/{ref}")
|
|
async def get_asset(
|
|
id: str,
|
|
ref: str,
|
|
):
|
|
"""Serve a binary asset."""
|
|
filepath = get_asset_path(id, ref)
|
|
if not filepath.exists() or not filepath.is_file():
|
|
raise HTTPException(status_code=404, detail="Asset not found")
|
|
|
|
return FileResponse(filepath)
|