Molodetz blogrol volgens DPP-template
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
import aiofiles
|
||||
from fastapi import APIRouter, HTTPException, Request
|
||||
from fastapi.responses import StreamingResponse
|
||||
|
||||
from molodetz.attachments import format_size
|
||||
from molodetz.database import enqueue_backup, get_backup, list_backups
|
||||
from molodetz.dependencies import json_or_form
|
||||
from molodetz.models import BackupForm
|
||||
from molodetz.responses import action_result, respond
|
||||
from molodetz.routers.admin._shared import admin_seo
|
||||
from molodetz.schemas.admin import BackupsOut
|
||||
from molodetz.services.backup import backup_path
|
||||
from molodetz.utils.audit import record
|
||||
from molodetz.utils.auth import is_primary_admin, not_found, require_admin
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/backups")
|
||||
async def backups_index(request: Request):
|
||||
user = require_admin(request)
|
||||
rows = [{**row, "size_label": format_size(row.get("size_bytes"))} for row in list_backups()]
|
||||
ctx = {"backups": rows, "can_download": is_primary_admin(user), "seo": admin_seo(request, "Back-ups")}
|
||||
return respond(request, "admin/backups.html", ctx, model=BackupsOut)
|
||||
|
||||
|
||||
@router.post("/backups")
|
||||
async def backups_enqueue(request: Request):
|
||||
user = require_admin(request)
|
||||
data = await json_or_form(request, BackupForm)
|
||||
row = enqueue_backup(data.target, user["uid"])
|
||||
record(request, "backup.enqueue", payload={"target": data.target}, targets=[("backup", row["uid"])], user=user)
|
||||
return action_result(request, "/admin/backups", data={"uid": row["uid"]})
|
||||
|
||||
|
||||
@router.get("/backups/{uid}/download")
|
||||
async def backups_download(request: Request, uid: str):
|
||||
user = require_admin(request)
|
||||
if not is_primary_admin(user):
|
||||
record(request, "backup.download", result="denied", targets=[("backup", uid)], user=user)
|
||||
raise HTTPException(403, "Alleen de primaire beheerder")
|
||||
row = get_backup(uid)
|
||||
if row is None or row.get("status") != "done":
|
||||
not_found("Back-up niet gevonden")
|
||||
path = backup_path(row)
|
||||
if not path.exists():
|
||||
not_found("Archief ontbreekt")
|
||||
record(request, "backup.download", targets=[("backup", uid)], user=user)
|
||||
return StreamingResponse(
|
||||
_stream_file(path),
|
||||
media_type="application/octet-stream",
|
||||
headers={"Content-Disposition": f'attachment; filename="{row["stored_name"]}"', "Content-Length": str(path.stat().st_size)},
|
||||
)
|
||||
|
||||
|
||||
async def _stream_file(path, chunk_size=1024 * 256):
|
||||
async with aiofiles.open(path, "rb") as handle:
|
||||
while chunk := await handle.read(chunk_size):
|
||||
yield chunk
|
||||
Reference in New Issue
Block a user