Files
photoBooth/backend/api/admin_api.py
T
admin c32b3ba345
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled
feat: badges imprimé ( copies) dans galeries admin+public; fix: timestamp_to_date dans print.html
2026-07-17 16:48:48 +02:00

157 lines
4.6 KiB
Python

"""Routes du dashboard admin -- authentification requise."""
import logging
from datetime import datetime
from pathlib import Path
from fastapi import APIRouter, Request, Form
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
logger = logging.getLogger(__name__)
router = APIRouter()
_templates = Jinja2Templates(
directory=Path(__file__).parent.parent.parent / "frontend" / "templates"
)
def _is_auth(request: Request) -> bool:
return request.session.get("authenticated") is True
def _require_auth(request: Request):
if not _is_auth(request):
return RedirectResponse(url="/admin/login", status_code=302)
return None
# -- Auth ----------------------------------------------------------------------
@router.get("/admin/login", response_class=HTMLResponse)
async def login_page(request: Request):
if _is_auth(request):
return RedirectResponse(url="/admin", status_code=302)
return _templates.TemplateResponse(request, "admin/login.html", {"error": None})
@router.post("/admin/login")
async def login(request: Request, password: str = Form(...)):
cfg = request.app.state.config
if password == cfg.app.admin_password:
request.session["authenticated"] = True
return RedirectResponse(url="/admin", status_code=302)
return _templates.TemplateResponse(
request,
"admin/login.html",
{"error": "Mot de passe incorrect"},
)
@router.get("/admin/logout")
async def logout(request: Request):
request.session.clear()
return RedirectResponse(url="/admin/login", status_code=302)
# -- Pages admin ---------------------------------------------------------------
@router.get("/admin", response_class=HTMLResponse)
async def admin_dashboard(request: Request):
redirect = _require_auth(request)
if redirect:
return redirect
sys_svc = request.app.state.system_service
cfg = request.app.state.config
led = request.app.state.led_service
btn = request.app.state.button_service
stats = sys_svc.get_stats()
services = sys_svc.get_services_status()
return _templates.TemplateResponse(request, "admin/dashboard.html", {
"config": cfg,
"stats": stats,
"services": services,
"led_effect": led.current_effect,
"relay_state": btn.relay_state if btn else True,
"print_mode": cfg.print.mode,
})
@router.get("/admin/gallery", response_class=HTMLResponse)
async def admin_gallery(request: Request):
redirect = _require_auth(request)
if redirect:
return redirect
cfg = request.app.state.config
return _templates.TemplateResponse(request, "admin/gallery.html", {
"config": cfg,
})
@router.get("/admin/actions", response_class=HTMLResponse)
async def admin_actions(request: Request):
redirect = _require_auth(request)
if redirect:
return redirect
pb = request.app.state.photobooth_service
cfg = request.app.state.config
pb_config = await pb.read_pb_config()
actions = pb_config.get("actions", {}).get("image", [])
return _templates.TemplateResponse(request, "admin/actions.html", {
"config": cfg,
"pb_actions": actions,
"button_mapping": cfg.button_actions,
})
@router.get("/admin/settings", response_class=HTMLResponse)
async def admin_settings(request: Request):
redirect = _require_auth(request)
if redirect:
return redirect
cfg = request.app.state.config
return _templates.TemplateResponse(request, "admin/settings.html", {
"config": cfg,
"button": cfg.button,
})
@router.get("/admin/events", response_class=HTMLResponse)
async def admin_events(request: Request):
redirect = _require_auth(request)
if redirect:
return redirect
cfg = request.app.state.config
return _templates.TemplateResponse(request, "admin/events.html", {"config": cfg})
@router.get("/admin/print", response_class=HTMLResponse)
async def admin_print(request: Request):
redirect = _require_auth(request)
if redirect:
return redirect
printer_svc = request.app.state.printer_service
cfg = request.app.state.config
queue = await printer_svc.get_queue()
printers = await printer_svc.get_printers_status()
# Formate les dates pour le template Jinja2
for q in queue:
ts = q.get("requested_at")
q["requested_at_str"] = (
datetime.fromtimestamp(ts).strftime("%d/%m %H:%M") if ts else "—"
)
return _templates.TemplateResponse(request, "admin/print.html", {
"config": cfg,
"queue": queue,
"printers": printers,
})