"""API gestion de la file d'attente d'impression.""" import logging from pathlib import Path from fastapi import APIRouter, Request, Query from fastapi.responses import JSONResponse logger = logging.getLogger(__name__) router = APIRouter() @router.get("/print/request") async def print_request( request: Request, filename: str = Query(..., description="Chemin absolu du fichier à imprimer"), copies: int = Query(default=1, ge=1, le=3), ): """ Reçoit la demande d'impression depuis photobooth-app (appelé par le share_command 'Demande d'impression'). """ printer_svc = request.app.state.printer_service pb = request.app.state.photobooth_service led = request.app.state.led_service ws = request.app.state.ws_manager # Construit l'URL de miniature depuis le filename stem = Path(filename).stem thumb_url = pb.thumbnail_url(stem) entry = await printer_svc.add_request(filename, thumb_url, copies) await ws.broadcast({"type": "print_request", "entry": entry}) # Feedback LED si impression directe if request.app.state.config.print.mode == "direct": led.play("printing") logger.info("Demande impression reçue: %s", filename) return {"ok": True, "id": entry["id"], "mode": request.app.state.config.print.mode} @router.get("/print/queue") async def get_queue( request: Request, status: str | None = Query(default=None), ): """Retourne la file d'attente d'impression.""" printer_svc = request.app.state.printer_service queue = await printer_svc.get_queue(status) printers = await printer_svc.get_printers_status() return {"queue": queue, "printers": printers} @router.post("/print/execute/{entry_id}") async def execute_print( request: Request, entry_id: str, copies: int = Query(default=1, ge=1, le=3), ): """Lance l'impression d'une entrée en attente (validation admin).""" printer_svc = request.app.state.printer_service led = request.app.state.led_service ws = request.app.state.ws_manager led.play("printing") result = await printer_svc.execute_print(entry_id, copies) await ws.broadcast({"type": "print_result", "entry_id": entry_id, "result": result}) if result["success"]: led.play("finished") else: led.play("error") return result @router.post("/print/cancel/{entry_id}") async def cancel_print(request: Request, entry_id: str): """Annule une demande en attente.""" printer_svc = request.app.state.printer_service ws = request.app.state.ws_manager ok = await printer_svc.cancel(entry_id) if ok: await ws.broadcast({"type": "print_cancelled", "entry_id": entry_id}) return {"ok": ok} @router.post("/print/cups/cancel/{printer_name}") async def cancel_cups_jobs(request: Request, printer_name: str): """Annule tous les jobs CUPS d'une imprimante.""" printer_svc = request.app.state.printer_service ok = await printer_svc.cancel_cups_jobs(printer_name) return {"ok": ok, "printer": printer_name} @router.get("/print/printers") async def get_printers(request: Request): """Statut des imprimantes CUPS.""" printer_svc = request.app.state.printer_service return await printer_svc.get_printers_status() @router.post("/print/mode") async def set_print_mode(request: Request, mode: str = Query(...)): """Change le mode d'impression (direct | validation | gallery).""" if mode not in ("direct", "validation", "gallery"): return JSONResponse({"error": "Mode invalide"}, status_code=400) config_svc = request.app.state.config_service config_svc.save_print_mode(mode) request.app.state.config.print.mode = mode return {"ok": True, "mode": mode}