first commit
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled

This commit is contained in:
2026-07-16 00:55:29 +02:00
commit 209f81aa3d
100 changed files with 17682 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
"""API de gestion des actions photobooth-app + mapping bouton."""
import logging
from fastapi import APIRouter, Request, Body
from fastapi.responses import JSONResponse
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("/actions/photobooth")
async def get_pb_actions(request: Request):
"""Retourne les actions image de photobooth-app + le mapping bouton actuel."""
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", [])
# Enrichit avec l'index
for i, action in enumerate(actions):
action["_index"] = i
return {
"actions": actions,
"button_mapping": cfg.button_actions,
}
@router.get("/actions/assets")
async def get_assets(request: Request):
"""Liste les cadres et fonds disponibles dans userdata."""
pb = request.app.state.photobooth_service
frames = await pb.list_userdata_frames()
backgrounds = await pb.list_userdata_backgrounds()
return {"frames": frames, "backgrounds": backgrounds}
@router.put("/actions/mapping")
async def update_button_mapping(
request: Request,
mapping: dict = Body(...),
):
"""
Met à jour le mapping clics → actions.
Body: { "1": {"label": "...", "photobooth_index": 0}, ... }
"""
config_svc = request.app.state.config_service
# Validation basique
for k, v in mapping.items():
if not isinstance(v, dict) or "photobooth_index" not in v:
return JSONResponse({"error": f"Format invalide pour clic {k}"}, status_code=400)
config_svc.save_button_actions(mapping)
request.app.state.config.button_actions = mapping
# Met aussi à jour le button_service
btn = request.app.state.button_service
btn._btn_actions = mapping
logger.info("Mapping bouton mis à jour: %s", mapping)
return {"ok": True, "mapping": mapping}
@router.put("/actions/photobooth/{index}")
async def update_pb_action(
request: Request,
index: int,
updates: dict = Body(...),
):
"""
Met à jour une action image de photobooth-app (cadre, fond, countdown, etc.)
updates peut contenir: countdown_capture, img_frame_file, img_background_file,
remove_background, image_filter, name
"""
pb = request.app.state.photobooth_service
pb_config = await pb.read_pb_config()
actions = pb_config.get("actions", {}).get("image", [])
if index < 0 or index >= len(actions):
return JSONResponse({"error": f"Index {index} invalide (max: {len(actions)-1})"}, status_code=400)
action = actions[index]
# Mise à jour des champs autorisés
allowed_root = {"name"}
allowed_processing = {"remove_background", "img_frame_file", "img_background_file",
"image_filter", "fill_background_enable", "fill_background_color",
"img_background_enable", "texts_enable"}
allowed_jobcontrol = {"countdown_capture"}
for key, value in updates.items():
if key in allowed_root:
action[key] = value
elif key in allowed_processing:
action.setdefault("processing", {})[key] = value
elif key in allowed_jobcontrol:
action.setdefault("jobcontrol", {})[key] = value
pb_config["actions"]["image"][index] = action
await pb.write_pb_config(pb_config)
logger.info("Action %d mise à jour: %s", index, list(updates.keys()))
return {"ok": True, "index": index, "action": action}
@router.post("/actions/trigger/{index}")
async def trigger_action(request: Request, index: int):
"""Déclenche une action directement (test)."""
pb = request.app.state.photobooth_service
led = request.app.state.led_service
btn = request.app.state.button_service
btn.relay_off()
try:
result = await pb.trigger_image_action(index)
return {"ok": True, "index": index, "result": result}
except Exception as e:
led.play("error")
btn.relay_on()
return JSONResponse({"error": str(e)}, status_code=500)