diff --git a/backend/api/print_api.py b/backend/api/print_api.py index fe79da4..c2af3f3 100644 --- a/backend/api/print_api.py +++ b/backend/api/print_api.py @@ -4,7 +4,7 @@ import asyncio import logging from pathlib import Path -from fastapi import APIRouter, Request, Query +from fastapi import APIRouter, Request, Query, Body from fastapi.responses import JSONResponse logger = logging.getLogger(__name__) @@ -125,6 +125,29 @@ async def set_print_mode(request: Request, mode: str = Query(...)): return {"ok": True, "mode": mode} +@router.post("/print/user-print-config") +async def set_user_print_config(request: Request, body: dict = Body(...)): + """Configure l'impression depuis la galerie utilisateur.""" + enabled = bool(body.get("user_print_enabled", False)) + quota = max(0, int(body.get("user_print_quota", 0))) + max_copies = max(1, min(10, int(body.get("user_print_max_copies", 1)))) + config_svc = request.app.state.config_service + config_svc.save_user_print_config(enabled, quota, max_copies) + logger.info("User print config: enabled=%s quota=%d max_copies=%d", enabled, quota, max_copies) + return {"ok": True, "user_print_enabled": enabled, "user_print_quota": quota, "user_print_max_copies": max_copies} + + +@router.get("/print/user-print-config") +async def get_user_print_config(request: Request): + """Retourne la config impression galerie utilisateur.""" + cfg = request.app.state.config.print + return { + "user_print_enabled": cfg.user_print_enabled, + "user_print_quota": cfg.user_print_quota, + "user_print_max_copies": cfg.user_print_max_copies, + } + + # ── Gestion avancée des imprimantes CUPS ────────────────────────────────────── @router.post("/print/printers/{printer_name}/enable") diff --git a/backend/services/config_service.py b/backend/services/config_service.py index 6400eb7..fd75717 100644 --- a/backend/services/config_service.py +++ b/backend/services/config_service.py @@ -83,6 +83,10 @@ class PrintConfig: script_path: str = "/home/pi/photobooth-data/script/script_print.sh" default_copies: int = 1 printers: list = field(default_factory=list) + # Impression depuis la galerie utilisateur + user_print_enabled: bool = False + user_print_quota: int = 0 # 0 = illimité + user_print_max_copies: int = 1 # copies max par demande @dataclass @@ -209,6 +213,21 @@ class ConfigService: self._config.event.slug = slug self._config.event.started_at = started_at + def save_user_print_config(self, enabled: bool, quota: int, max_copies: int): + with open(self.path, encoding="utf-8") as f: + raw = yaml.safe_load(f) or {} + raw.setdefault("print", {}).update({ + "user_print_enabled": enabled, + "user_print_quota": quota, + "user_print_max_copies": max_copies, + }) + with open(self.path, "w", encoding="utf-8") as f: + yaml.dump(raw, f, allow_unicode=True, default_flow_style=False) + if self._config: + self._config.print.user_print_enabled = enabled + self._config.print.user_print_quota = quota + self._config.print.user_print_max_copies = max_copies + def save_print_mode(self, mode: str): with open(self.path, encoding="utf-8") as f: raw = yaml.safe_load(f) or {} diff --git a/frontend/templates/admin/print.html b/frontend/templates/admin/print.html index 4bbe5c1..539a25b 100644 --- a/frontend/templates/admin/print.html +++ b/frontend/templates/admin/print.html @@ -256,6 +256,51 @@ + +
+
👥 Impression galerie utilisateur
+
+

+ Autorise (ou non) les visiteurs de la galerie publique à demander l'impression d'une photo, + avec un quota et un nombre de copies maximum par demande. +

+
+ + + +
+
+ +
+ + 0 = illimité +
+
+ +
+ + +
+
+ +
+ +
+
+
@@ -486,6 +531,19 @@ async function cancelPrint(id) { } catch(err) { showToast('Erreur', 'error'); } } +// ── Config impression utilisateur ───────────────────────────────────────────── +async function saveUserPrintConfig() { + const payload = { + user_print_enabled: document.getElementById('uprint-enabled').checked, + user_print_quota: parseInt(document.getElementById('uprint-quota').value) || 0, + user_print_max_copies: parseInt(document.getElementById('uprint-max-copies').value) || 1, + }; + try { + await api('POST', '/api/print/user-print-config', payload); + showToast('✅ Configuration sauvegardée', 'success'); + } catch(e) { showToast('❌ Erreur : ' + e.message, 'error'); } +} + // ── WebSocket + auto-refresh ─────────────────────────────────────────────────── function onWsMessage(msg) { if (['print_request','print_result','print_cancelled'].includes(msg.type)) {