Files
ad/molodetz/routers/admin/gallery.py
T
retoor 9fb4d65787 Member invites, gallery resync, content and operator docs
- Invite flow: admin issue/revoke on join requests, public single-use
  claim links (hash-only tokens, 7-day expiry, no state reveal), claim
  creates the Member account and marks the request accepted
- Gallery: admin status page plus resync endpoint; sync refreshes
  thumbnails whose content changed; tools/gallery contract and checker
- Docs: public content page, admin-only operator runbook, api.md
  invite/gallery sections, all routes in the live API docs, docs
  reachability gate test
- Screenshots cover the new pages; version 1.0.18
2026-10-06 02:56:08 +02:00

39 lines
1.1 KiB
Python

# retoor <retoor@molodetz.nl>
from fastapi import APIRouter, Request
from molodetz.database import count_media
from molodetz.gallery import missing_sources, sync_gallery
from molodetz.responses import action_result, respond
from molodetz.routers.admin._shared import admin_seo
from molodetz.schemas.admin import GalleryStatusOut
from molodetz.utils.audit import record
from molodetz.utils.auth import require_admin
router = APIRouter()
def _status():
return {
"flyers": count_media("flyer"),
"memes": count_media("meme"),
"missing": missing_sources(),
}
@router.get("/gallery")
async def gallery_status(request: Request):
require_admin(request)
ctx = dict(_status())
ctx["seo"] = admin_seo(request, "Gallery")
return respond(request, "admin/gallery.html", ctx, model=GalleryStatusOut)
@router.post("/gallery/resync")
async def gallery_resync(request: Request):
user = require_admin(request)
synced = sync_gallery()
data = dict(_status())
data["synced"] = synced
record(request, "gallery.resync", payload=data, user=user)
return action_result(request, "/admin/gallery", data=data)