64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
|
|
"""v1 vault sync-assist API — vault files are the source of truth."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
|
||
|
|
from fastapi.responses import Response
|
||
|
|
|
||
|
|
from ..auth import get_current_user
|
||
|
|
from .. import vault_store
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/manifest")
|
||
|
|
async def get_manifest(user_id: str = Depends(get_current_user)) -> dict:
|
||
|
|
"""List all files in the user's vault with size/mtime/sha256."""
|
||
|
|
return vault_store.build_manifest(user_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/files/{file_path:path}")
|
||
|
|
async def download_file(
|
||
|
|
file_path: str,
|
||
|
|
user_id: str = Depends(get_current_user),
|
||
|
|
) -> Response:
|
||
|
|
try:
|
||
|
|
data = vault_store.read_file(user_id, file_path)
|
||
|
|
except ValueError as exc:
|
||
|
|
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||
|
|
except FileNotFoundError:
|
||
|
|
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="file not found")
|
||
|
|
return Response(
|
||
|
|
content=data,
|
||
|
|
media_type="application/octet-stream",
|
||
|
|
headers={"X-Vault-Path": file_path},
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@router.put("/files/{file_path:path}")
|
||
|
|
async def upload_file(
|
||
|
|
file_path: str,
|
||
|
|
upload: UploadFile = File(...),
|
||
|
|
user_id: str = Depends(get_current_user),
|
||
|
|
) -> dict:
|
||
|
|
try:
|
||
|
|
data = await upload.read()
|
||
|
|
entry = vault_store.write_file(user_id, file_path, data)
|
||
|
|
except ValueError as exc:
|
||
|
|
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||
|
|
return entry.to_dict()
|
||
|
|
|
||
|
|
|
||
|
|
@router.delete("/files/{file_path:path}")
|
||
|
|
async def remove_file(
|
||
|
|
file_path: str,
|
||
|
|
user_id: str = Depends(get_current_user),
|
||
|
|
) -> dict:
|
||
|
|
try:
|
||
|
|
vault_store.delete_file(user_id, file_path, tombstone=True)
|
||
|
|
except ValueError as exc:
|
||
|
|
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||
|
|
except FileNotFoundError:
|
||
|
|
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="file not found")
|
||
|
|
return {"deleted": file_path, "tombstone": True}
|