Bulletproof: messages novices, kiosk port auto, reset compteur, sync booth event_id
- Messages erreur camera/impression: texte novice ("Oups!", "Reessayez") au lieu de jargon technique
- kiosk-session.sh: lit le port depuis config.json (plus de http://localhost en dur), healthcheck /api/config, supprime git pull auto au boot
- Activer evenement: reset automatique du compteur photos
- Activer evenement: sync booth.event_id quand galerie live active
- Port par defaut backend: 80 → 8080
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -125,6 +125,10 @@ def activer_evenement(event_id: str) -> dict | None:
|
||||
event = obtenir_evenement(event_id)
|
||||
if not event:
|
||||
return None
|
||||
config = charger_config()
|
||||
booth = config.get("booth", {})
|
||||
if booth.get("actif"):
|
||||
booth["event_id"] = event_id
|
||||
mettre_a_jour_config({
|
||||
"evenement": {
|
||||
"event_id": event_id,
|
||||
@@ -134,7 +138,8 @@ def activer_evenement(event_id: str) -> dict | None:
|
||||
"couleur_secondaire": event.get("couleur_secondaire", "#ffffff"),
|
||||
"media_accueil": event.get("media_accueil"),
|
||||
"formats_actifs": event.get("formats_actifs", ["10x15", "15x20", "strip"]),
|
||||
}
|
||||
},
|
||||
"booth": booth,
|
||||
})
|
||||
log.info(f"Evenement active : {event['nom']} ({event_id})")
|
||||
return event
|
||||
|
||||
@@ -1736,6 +1736,8 @@ async def api_activer_evenement(event_id: str):
|
||||
event = activer_evenement(event_id)
|
||||
if not event:
|
||||
return JSONResponse({"erreur": "Evenement introuvable"}, status_code=404)
|
||||
reset_compteur()
|
||||
log.info(f"Compteur photos remis a zero (activation evenement {event_id})")
|
||||
await diffuser_ws({"type": "config_maj", "config": charger_config()})
|
||||
return event
|
||||
|
||||
@@ -2587,6 +2589,6 @@ if __name__ == "__main__":
|
||||
uvicorn.run(
|
||||
app,
|
||||
host=conf_srv.get("host", "0.0.0.0"),
|
||||
port=conf_srv.get("port", 80),
|
||||
port=conf_srv.get("port", 8080),
|
||||
log_level="info",
|
||||
)
|
||||
|
||||
@@ -50,8 +50,8 @@ function afficherErreurPreview(visible) {
|
||||
const el = document.getElementById('preview-erreur-camera');
|
||||
if (!el) return;
|
||||
if (visible) {
|
||||
el.querySelector('p').textContent = 'Appareil photo deconnecte';
|
||||
el.querySelector('span').textContent = 'Reconnexion en cours...';
|
||||
el.querySelector('p').textContent = 'Un instant...';
|
||||
el.querySelector('span').textContent = 'L\'appareil photo se reconnecte';
|
||||
el.classList.remove('cache');
|
||||
} else {
|
||||
el.classList.add('cache');
|
||||
@@ -194,7 +194,7 @@ wsOnMessage('camera_erreur', () => {
|
||||
if (!captureEnCours) {
|
||||
captureAbortee = true;
|
||||
if (ecranActuel === 'capture') {
|
||||
afficherErreurCapture('Appareil photo déconnecté', 'Reconnexion en cours...');
|
||||
afficherErreurCapture('Un instant...', 'L\'appareil photo se prepare');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -253,7 +253,7 @@ async function lancerCapture() {
|
||||
try {
|
||||
let statut = await apiGet('/api/camera/statut');
|
||||
if ((!statut.connectee || statut.mode === 'erreur') && statut.reveil_en_cours) {
|
||||
afficherStatut('Appareil photo en preparation...', 'succes');
|
||||
afficherStatut('L\'appareil photo se prepare, un instant...', 'succes');
|
||||
for (let att = 0; att < 30; att++) {
|
||||
await pause(2000);
|
||||
statut = await apiGet('/api/camera/statut');
|
||||
@@ -263,12 +263,12 @@ async function lancerCapture() {
|
||||
}
|
||||
if (!statut.connectee || statut.mode === 'erreur') {
|
||||
captureEnCours = false;
|
||||
afficherErreurCapture('Appareil photo non disponible', 'Verifiez la connexion USB du DSLR');
|
||||
afficherErreurCapture('Appareil photo indisponible', 'Reessayez dans quelques instants');
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
captureEnCours = false;
|
||||
afficherErreurCapture('Impossible de joindre le serveur', 'Verifiez que le photobooth est bien demarre');
|
||||
afficherErreurCapture('Le photobooth demarre', 'Reessayez dans quelques instants');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ async function lancerCapture() {
|
||||
flash.classList.add('cache');
|
||||
document.getElementById('capture-en-cours').classList.add('cache');
|
||||
captureEnCours = false;
|
||||
afficherErreurCapture('Erreur reseau', 'Le serveur ne repond pas — redemarrez le photobooth');
|
||||
afficherErreurCapture('Oups !', 'La photo n\'a pas pu etre prise, reessayez');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ async function lancerCapture() {
|
||||
document.getElementById('capture-en-cours').classList.add('cache');
|
||||
captureEnCours = false;
|
||||
const msg = resultat.erreur;
|
||||
afficherErreurCapture('Echec de la capture', msg.includes('Echec') ? 'Verifiez le DSLR et reessayez' : msg);
|
||||
afficherErreurCapture('Oups !', 'La photo n\'a pas pu etre prise, reessayez');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ let formatImpression = null; // Format CUPS à utiliser (ex: "10x15-2up")
|
||||
|
||||
async function traiterCapture() {
|
||||
if (photosSession.length === 0) {
|
||||
afficherErreurCapture('Aucune photo capturee', 'Une erreur inattendue s\'est produite');
|
||||
afficherErreurCapture('Oups !', 'La photo n\'a pas pu etre prise, reessayez');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -461,7 +461,7 @@ async function traiterCapture() {
|
||||
if (mode === 'strip') {
|
||||
resultat = await apiPost('/api/strip', { photos: photosSession });
|
||||
if (resultat.erreur) {
|
||||
afficherErreurCapture('Erreur creation de la planche', resultat.erreur);
|
||||
afficherErreurCapture('Oups !', 'La planche n\'a pas pu etre creee, reessayez');
|
||||
return;
|
||||
}
|
||||
if (resultat.impression) photoImpression = resultat.impression;
|
||||
@@ -469,12 +469,12 @@ async function traiterCapture() {
|
||||
} else {
|
||||
resultat = await apiPost('/api/collage', { photos: photosSession });
|
||||
if (resultat.erreur) {
|
||||
afficherErreurCapture('Erreur creation du collage', resultat.erreur);
|
||||
afficherErreurCapture('Oups !', 'Le collage n\'a pas pu etre cree, reessayez');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!resultat.nom) {
|
||||
afficherErreurCapture('Erreur traitement des photos', 'Le fichier final n\'a pas ete genere');
|
||||
afficherErreurCapture('Oups !', 'Un probleme est survenu, reessayez');
|
||||
return;
|
||||
}
|
||||
photoFinale = resultat.nom;
|
||||
|
||||
@@ -125,9 +125,9 @@ async function lancerImpression() {
|
||||
} else if (resultat.succes) {
|
||||
afficherStatut(`${nbExemplaires} exemplaire(s) envoye(s) a l'imprimante !`, 'succes');
|
||||
} else if (resultat.erreur === 'evenement_termine') {
|
||||
afficherStatut('Evenement termine — impression indisponible', 'erreur');
|
||||
afficherStatut('L\'impression n\'est plus disponible pour cet evenement', 'erreur');
|
||||
} else {
|
||||
afficherStatut('Erreur d\'impression', 'erreur');
|
||||
afficherStatut('L\'impression a rencontre un probleme, reessayez', 'erreur');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ async function envoyerEmail() {
|
||||
} else if (resultat.succes) {
|
||||
afficherStatut('Email envoyé !', 'succes');
|
||||
} else {
|
||||
afficherStatut('Erreur d\'envoi email', 'erreur');
|
||||
afficherStatut('L\'email n\'a pas pu etre envoye, reessayez', 'erreur');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,18 @@
|
||||
exec 9>/tmp/photobooth-kiosk.lock
|
||||
flock -n 9 || { echo "[kiosk] Déjà en cours, abandon."; exit 0; }
|
||||
|
||||
PHOTOBOOTH_DIR=/home/jules/photobooth
|
||||
|
||||
# Port du backend (lu depuis config.json, fallback 8080)
|
||||
BACKEND_PORT=$(python3 -c "
|
||||
import json, sys
|
||||
try:
|
||||
d = json.load(open('$PHOTOBOOTH_DIR/data/config.json'))
|
||||
print(d.get('serveur', {}).get('port', 8080))
|
||||
except: print(8080)
|
||||
" 2>/dev/null)
|
||||
BACKEND_URL="http://localhost:${BACKEND_PORT}"
|
||||
|
||||
# Tuer tout backend orphelin d'une session precedente
|
||||
pkill -f 'python.*backend.main' 2>/dev/null || true
|
||||
sleep 1
|
||||
@@ -23,8 +35,7 @@ pkill -f gvfs-gphoto2-volume-monitor 2>/dev/null || true
|
||||
_backend_loop() {
|
||||
while true; do
|
||||
while [ -f /tmp/photobooth-maintenance ]; do sleep 2; done
|
||||
cd /home/jules/photobooth
|
||||
git pull --ff-only 2>&1 | logger -t photobooth-git
|
||||
cd "$PHOTOBOOTH_DIR"
|
||||
source .venv/bin/activate
|
||||
authbind --deep python -m backend.main 2>&1 | tee -a /tmp/photobooth-backend.log
|
||||
echo "[kiosk] backend terminé, redémarrage dans 3s..."
|
||||
@@ -37,9 +48,9 @@ BACKEND_LOOP_PID=$!
|
||||
# Nettoyer le backend si le kiosk est tue
|
||||
trap "kill $BACKEND_LOOP_PID 2>/dev/null; pkill -f 'python.*backend.main' 2>/dev/null" EXIT
|
||||
|
||||
# Attendre que le backend soit pret (max 15s)
|
||||
for i in $(seq 1 15); do
|
||||
curl -sf http://localhost/ > /dev/null 2>&1 && break
|
||||
# Attendre que le backend soit pret (max 30s)
|
||||
for i in $(seq 1 30); do
|
||||
curl -sf "${BACKEND_URL}/api/config" > /dev/null 2>&1 && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
@@ -64,7 +75,7 @@ while true; do
|
||||
--password-store=basic \
|
||||
--lang=fr \
|
||||
--remote-debugging-port=9222 \
|
||||
http://localhost
|
||||
"${BACKEND_URL}"
|
||||
echo "[kiosk] Chromium terminé, redémarrage dans 2s..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user