64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
"""Archive location and preflight API (US06-01).
|
|
|
|
Registering a location writes a marker onto the medium; preflight is a command
|
|
rather than a read, because it probes the destination, hashes the scope, and issues
|
|
the token a later archive plan must present (US06-02). Neither endpoint moves or
|
|
removes a single library file.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import BaseModel
|
|
|
|
from photo_pipeline.services.archives import ArchiveError, ArchiveService
|
|
|
|
router = APIRouter(tags=["archives"])
|
|
|
|
# Which failures are the caller's request (422) and which are a missing thing (404).
|
|
NOT_FOUND_CODES = {"unknown_location"}
|
|
|
|
|
|
class RegisterLocationRequest(BaseModel):
|
|
name: str
|
|
root: str
|
|
|
|
|
|
class PreflightRequest(BaseModel):
|
|
location_id: str
|
|
# ``None`` means every album; an explicit list scopes the check.
|
|
albums: list[str] | None = None
|
|
|
|
|
|
def _service(request: Request) -> ArchiveService:
|
|
return ArchiveService(request.app.state.session_factory, config=request.app.state.config)
|
|
|
|
|
|
def _error(error: ArchiveError) -> JSONResponse:
|
|
status = 404 if error.code in NOT_FOUND_CODES else 422
|
|
return JSONResponse(
|
|
status_code=status, content={"error": {"code": error.code, "message": str(error)}}
|
|
)
|
|
|
|
|
|
@router.post("/archive-locations", status_code=201)
|
|
def register_location(body: RegisterLocationRequest, request: Request):
|
|
try:
|
|
return _service(request).register(body.name, body.root)
|
|
except ArchiveError as error:
|
|
return _error(error)
|
|
|
|
|
|
@router.get("/archive-locations")
|
|
def list_locations(request: Request) -> dict:
|
|
return {"locations": _service(request).locations()}
|
|
|
|
|
|
@router.post("/archive-preflight")
|
|
def preflight(body: PreflightRequest, request: Request):
|
|
try:
|
|
return _service(request).preflight(body.location_id, body.albums)
|
|
except ArchiveError as error:
|
|
return _error(error)
|