Dashboard: boutons restart services, JH-Photomaton et reboot Pi
🚀 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-18 10:35:43 +02:00
parent 3522d2d996
commit fb35533b37
3 changed files with 148 additions and 4 deletions
+61 -3
View File
@@ -79,7 +79,6 @@ async def set_delete_button(request: Request, visible: bool):
Écrit userdata/private.css puis redémarre photobooth-app pour que le CSS
soit pris en compte.
"""
import asyncio, subprocess
pb = request.app.state.photobooth_service
config_svc = request.app.state.config_service
@@ -93,7 +92,6 @@ async def set_delete_button(request: Request, visible: bool):
async def _restart_photobooth():
import asyncio
await asyncio.sleep(0.5)
proc = await asyncio.create_subprocess_exec(
"sudo", "systemctl", "restart", "photobooth-app.service",
@@ -107,11 +105,71 @@ async def _restart_photobooth():
@router.post("/system/restart-photobooth")
async def restart_photobooth(request: Request):
"""Redémarre photobooth-app.service pour recharger la config (actions, etc.)."""
import asyncio
asyncio.create_task(_restart_photobooth())
return {"ok": True, "message": "Redémarrage de photobooth-app en cours…"}
# ── Gestion services & système ────────────────────────────────────────────────
@router.get("/system/ping")
async def ping():
"""Endpoint de health-check — utilisé par le polling de reconnexion côté client."""
return {"ok": True}
@router.post("/system/service/{name}/restart")
async def restart_service(name: str):
"""Redémarre un service systemd autorisé."""
if name not in _ALLOWED_SERVICES:
return JSONResponse({"ok": False, "error": f"Service '{name}' non autorisé"}, status_code=403)
asyncio.create_task(_run_systemctl_restart(name))
return {"ok": True, "message": f"Redémarrage de {name} en cours…"}
async def _run_systemctl_restart(name: str):
proc = await asyncio.create_subprocess_exec(
"sudo", "systemctl", "restart", f"{name}.service",
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL,
)
await proc.wait()
logger.info("%s redémarré (exit %d)", name, proc.returncode)
@router.post("/system/restart-self")
async def restart_self():
"""Redémarre le service jh-photomaton lui-même (avec délai pour que la réponse parte d'abord)."""
asyncio.create_task(_restart_self_delayed())
return {"ok": True, "message": "Redémarrage de JH-Photomaton en cours…"}
async def _restart_self_delayed():
await asyncio.sleep(1.5)
proc = await asyncio.create_subprocess_exec(
"sudo", "systemctl", "restart", "jh-photomaton.service",
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL,
)
await proc.wait()
@router.post("/system/reboot")
async def reboot_pi():
"""Redémarre le Raspberry Pi (avec délai pour que la réponse parte d'abord)."""
asyncio.create_task(_reboot_delayed())
return {"ok": True, "message": "Redémarrage du Pi en cours…"}
async def _reboot_delayed():
await asyncio.sleep(2)
proc = await asyncio.create_subprocess_exec(
"sudo", "reboot",
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL,
)
await proc.wait()
@router.post("/system/screen/refresh")
async def screen_refresh(request: Request):
"""Envoie F5 à l'écran HDMI connecté (Chromium kiosque Wayland/X11)."""