Commit Graph

177 Commits

Author SHA1 Message Date
a79762197d Fix impression pellicule : strip genere en paysage au lieu du portrait attendu
creer_strip() produisait une bande paysage (1800x595) alors que printer.py
('10x15-2up' -> PageSize ...-div2) et tous les cadres existants (assets/cadres/strip/*.png)
attendent une bande portrait fixe 600x1800 (5x15cm), dupliquee et coupee
automatiquement par l'imprimante. Le mismatch faisait pivoter/etirer
l'image a l'impression (StpiShrinkOutput=Crop sur un ratio incompatible),
d'ou le rendu deforme coupe en 2 mauvais morceaux au lieu de 2 pellicules
identiques.

- creer_strip() : bande 600x1800 portrait, photos empilees verticalement,
  perforations sur les cotes (au lieu de haut/bas)
- Cadre de visee live (camera.js) : formule de ratio mise a jour en
  consequence pour rester fidele au resultat final
2026-06-21 23:00:48 +02:00
0df68da41a Cadre de visee live correspondant au recadrage final pellicule/collage
L'apercu live montrait le plein cadre camera (ratio ~3:2) alors que le
recadrage final de chaque case (creer_strip/creer_collage) est plus carre
(~1.11:1 pour 3 photos en pellicule) : le cadrage visualise pendant le
compte a rebours ne correspondait pas au resultat imprime.

Ajoute un cadre pointille superpose au live preview, dimensionne en
reproduisant cote JS la meme formule de recadrage que backend/collage.py,
visible uniquement en mode multi-shot (strip ou collage).
2026-06-21 22:52:05 +02:00
b8f3bef852 DSLR : empecher la mise en veille (autopoweroff Canon + udev no-autosuspend)
Le boitier se mettait en veille apres quelques minutes d'inactivite et
apparaissait deconnecte. Deux causes possibles traitees :
- autopoweroff Canon desactive a la connexion (cote firmware)
- USB autosuspend du host desactive pour les peripheriques Canon (cote noyau)
2026-06-21 22:15:56 +02:00
66847dccf8 Ecran partage : photo miniature flexible pour toujours rentrer dans l'ecran
Le bloc partage (photo + boutons + form impression) pouvait depasser la
hauteur de l'ecran quand le choix du nombre d'exemplaires s'affichait.
La miniature absorbe maintenant l'espace restant (flex + min-height:0)
au lieu d'une hauteur fixe en vh, les autres elements gardent leur taille.
2026-06-21 22:13:26 +02:00
fe0a559c85 Flash Canon configurable, choix de cadre a l'impression, fixes capture/reconnexion DSLR
- Flash integre Canon activable/desactivable depuis l'admin (configurer_flash)
- Popup de choix de cadre juste avant impression, layout sans defilement (flex nowrap + aspect-ratio)
- Capture : ignore camera_erreur pendant une capture en cours (laisse l'API trancher)
- surveiller_dslr : grace period preview augmentee a 2s, reapplique la config camera apres reconnexion
- start.sh simplifie (Chromium gere par kiosk-session.sh), remote debugging port 9222 active
2026-06-21 21:59:36 +02:00
c7225cc9f6 surveiller_dslr : retirer le reset USB automatique (contre-productif)
Les resets USB ioctl répétés en boucle aggravent l'état des appareils Canon
au lieu de les débloquer. La fonction _usb_reset_canon est conservée pour
usage manuel mais n'est plus appelée automatiquement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 14:33:14 +02:00
f66f08da4e surveiller_dslr : pause 12s après reset USB Canon pour ré-énumération
Le reset USB ioctl prend ~10s sur le Canon EOS 6D pour que l'appareil
se ré-énumère sur le bus. Avec 3s on retombait en boucle de resets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 14:04:23 +02:00
e4e5ee05d4 surveiller_dslr : reset USB automatique après 3 échecs de connexion Canon
Quand gphoto2 détecte le DSLR mais que camera.init() timeout répétitivement
(USB stall après kill -9 ou déconnexion brutale), on tente un reset USB ioctl
(USBDEVFS_RESET sur /dev/bus/usb/<bus>/<dev>) toutes les 3 tentatives (~15s).
Évite de rester bloqué indéfiniment sur "Timeout reading from or writing to the port".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 14:02:29 +02:00
4f12f77106 Capture : viewfinder=0 avant prise (AF phase-détection), timeout 20s, spinner UI
- camera.py : désactiver LiveView avant capture (viewfinder=0) → miroir abaissé →
  AF phase-détection Canon actif. Remplace _declencher_af_liveview (autofocusdrive=1
  pouvait bloquer sur certains corps Canon). activer_viewfinder() après la prise.
- main.py : fix bug global _preview_actif dans api_capturer (était variable locale,
  le global restait True). Timeout asyncio 20s sur run_in_executor pour éviter freeze
  permanent si capture bloque. Logs INFO avant/après capture.
- camera.js + index.html + style.css : spinner "Capture en cours..." entre le flash
  et l'affichage du résultat. Cacher le spinner dans afficherErreurCapture aussi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 13:51:51 +02:00
d02cc90fee Bullet-proof caméra : reconnexion auto + fix crash capture + AF LiveView
backend:
- surveiller_dslr : fix condition qui court-circuitait le check santé
  quand mode==gphoto2 — watchdog surveille maintenant via preview_dslr_ok
  et reconnecte automatiquement après 15s d'échec (3x5s)
- _pusher_preview : ne pas envoyer camera_erreur pendant capture_en_cours
  (race condition HTTP/WS : le POST /capturer peut arriver avant preview_stop)
- api_capturer : force _preview_actif=False dès le début de la capture
- _capture_gphoto2 : déclenche autofocusdrive avant la prise en LiveView

frontend:
- websocket.js : support multi-callbacks par type (wsOnMessage ne remplace
  plus le callback précédent, tous s'exécutent)
- app.js : camera_erreur affiche bannière + reload dernier recours à 2min
  (plus 10s), camera_ok cache la bannière automatiquement
- camera.js : camera_erreur abort capture + arreterPreview(); camera_ok
  reset captureAbortee

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 12:11:33 +02:00
7e239ea0f9 Camera déconnectée : retour accueil automatique + abort capture
- camera_erreur pendant la capture : abort immédiat + afficherErreurCapture()
  → retour accueil en 4s (au lieu de rester bloqué sur "Reconnexion en cours...")
- camera_ok : cache l'erreur et reset le flag captureAbortee
- captureAbortee flag : permet à lancerCapture() de sortir proprement
  sans déclencher de capture fantôme après une déconnexion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 11:53:30 +02:00
a51d235faf Fix preview live : position:absolute sur img (height:100% cassé dans flex avec align-items:center)
La balise <img> avec height:100% ne se propage pas quand le parent est un
flex item positionné avec align-self:center au lieu de stretch. Le fix :
position:absolute top:0 left:0 width/height 100% sur .preview-live img.

Retiré aussi --remote-debugging-port=9222 (diagnostic temporaire).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 11:16:19 +02:00
831c64f4f7 Debug: active remote debugging port 9222 sur Chromium 2026-06-10 10:48:24 +02:00
652d0424e3 Retirer le .deb du repo, ajouter .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 09:57:02 +02:00
f977189a93 Kiosk : git pull auto + diagnostic caméra dans admin
- kiosk-session.sh : git pull à chaque démarrage du backend
  (les correctifs Gitea sont maintenant déployés automatiquement)
- Log backend dans /tmp/photobooth-backend.log (lisible via admin)
- Admin > Infos : bouton "Diagnostic camera" → appelle /api/camera/debug
  et affiche mode, connectee, erreur capture_preview, widgets gphoto2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 09:56:55 +02:00
d3a71a9866 Fix caméra : gvfsd-gphoto2, race condition viewfinder, exif_transpose
- kiosk-session.sh : tue gvfsd-gphoto2 au démarrage (démon GNOME qui
  monopolisait le DSLR sur USB et bloquait gphoto2)
- camera.py : viewfinder activé AVANT mode="gphoto2" → le thread preview
  ne peut plus appeler capture_preview() avant que LiveView soit prêt
- _activer_viewfinder_init() sans lock pour l'init (thread pas encore actif)
- exif_transpose sur les captures DSLR → corrige l'orientation et les
  bandes blanches dues aux photos mal orientées

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 17:33:31 +02:00
0b4c5f9430 Fix strip (K60 coupe auto), diagnostic preview, nettoyage
Strip 10x15 :
- Envoie la strip simple avec format 10x15-2up (w288h432-div2)
  le K60 duplique et coupe automatiquement → plus de papier non coupé
- Supprime creer_impression_strip et le 2-up manuel avec marges blanches
- api/imprimer accepte format_papier depuis le frontend
- Frontend stocke formatImpression et le passe à l'impression

Diagnostic preview :
- GET /api/camera/debug : teste capture_preview(), liste les widgets
  config gphoto2, état du thread → permet de voir l'erreur exacte

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 16:52:13 +02:00
1364b62297 Fix preview + miroir : thread continu, grace period, lock gphoto2
- _thread_preview tourne TOUJOURS quand DSLR connecté (plus de condition
  _preview_actif) → capture_preview() appelé en continu → miroir reste levé
- Grace period 15 frames (~500ms) avant de signaler camera_erreur : évite
  la race condition qui tuait le preview avant la 1ère frame
- _preview_gphoto2 protégé par _gp_lock (accès concurrent safe)
- surveiller_dslr ne tourne plus quand le DSLR est en mode gphoto2 connecté

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 23:01:25 +02:00
0a918666b3 Camera : viewfinder permanent + preview live pendant compte à rebours
- activer_viewfinder() à la connexion DSLR (miroir levé dès le démarrage)
- activer_viewfinder() après chaque capture (certains Canon le désactivent)
- Suppression desactiver_viewfinder() — miroir ne redescend plus jamais
- lancerPreview() au début du compte à rebours, arreterPreview() juste avant la capture
- Preview live fonctionnel : l'utilisateur se voit pendant tout le compte à rebours

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 22:32:46 +02:00
0477831679 Imprimante : bouton Couper papier (micro-job blanc déclenche le cutter K60)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 21:19:27 +02:00
843762b6d7 Imprimante : bandeau erreur tous écrans + reset USB + statut détaillé
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 21:17:27 +02:00
2b204ddb5e Admin : statut détaillé imprimante + message erreur CUPS traduit
- GET /api/imprimante/statut-detail : statut + dernière erreur log
- Bouton évacuer retourne le vrai message (format papier, bourrage...)
- Bloc d'erreur affiché dans l'onglet Matériel si problème détecté

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:38:48 +02:00
3cd5525981 detecter_usb : 2 niveaux /media/<user>/<label> + filtre fstype 2026-06-04 13:53:05 +02:00
c013c9e69e Ajout udiskie automount USB dans kiosk-session 2026-06-04 13:48:28 +02:00
4de88877c7 Fix clignotement : verrou instance unique kiosk + meta notranslate HTML
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 13:06:12 +02:00
a85cc100f2 Fix translate bar (--lang=fr + prefs FR) + popup photostation popup-overlay
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:58:09 +02:00
0c00011de0 Fix popup photostation (hors ecran-accueil) + z-index boutons + profil Chromium sans translate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:50:41 +02:00
8db27bf77d Fix : clic btn-photostation ne déclenche plus la navigation vers mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:42:26 +02:00
d66a9c2fa9 Fix : bit exécutable scripts kiosk-session.sh et install-photostation.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:37:13 +02:00
babd89425c Intégration station d'impression photo (photostation)
- Icône discrète coin bas-gauche, visible seulement si photostation installée
- Popup PIN (4 chiffres) avant lancement
- Backend : /api/photostation/disponible + /api/photostation/lancer
- kiosk-session.sh : Chromium attend le flag /tmp/photostation_running avant redémarrage
- Script install-photostation.sh pour déploiement sur la Surface

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 09:20:48 +02:00
fe71921d1a Cadres choix : zoom 2.5x + fond photo simulé, bordures bien visibles
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 09:14:40 +02:00
ba2b119e1f Kiosk : boucle infinie backend + Chromium, plus d'écran login
Si Chromium ou le backend plantent, ils redémarrent automatiquement.
La session LightDM ne se termine jamais → plus d'écran de login intempestif.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 21:40:23 +02:00
6af9d7c073 Fix : desactiver Translate dans Chromium kiosk
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 21:39:18 +02:00
e3d1d9cc07 Impression Mitsubishi K60 + cadres + interface admin distante
- Intégration selphy_print (backend CUPS dyesub Mitsubishi CP-K60DW-S)
- Formats impression : 15x20, 10x15, 10x15 2-strips avec cadre et orientation portrait/paysage
- Cadres d'impression par format (strip/10x15/15x20) : upload, sélection, aperçu live
- Cadres démo générés : pellicule noir/vintage/couleurs + bordures classique/doré/rose gold
- Écran de choix de cadre avant capture (clic direct, aperçu grand format)
- Filtres réduits à 3 (Couleur, N&B, Sépia) et appliqués sur tous les strips
- Port 80 via authbind, route /admin avec redirection auto depuis poste distant
- Autologin LightDM corrigé (pam-autologin-service)
- Bouton évacuer bourrage papier dans admin
- Fix : _gp_lock manquant dans Camera.__init__

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 21:38:31 +02:00
6451f5774c Mise a jour theme GRUB + logo copydev + test pygame
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 22:43:21 +02:00
1120513309 Switch trigger_capture() : eosremoterelease ne genere FILE_ADDED qu'une fois
eosremoterelease='Immediate' envoyait GP_EVENT_FILE_ADDED uniquement
pour la 1ere pose (bug Canon/gphoto2 connu). trigger_capture() genere
l'evenement pour CHAQUE pose. En liveview actif (miroir deja leve),
trigger_capture() ne bouge pas le miroir — uniquement l'obturateur.
Timeout reduit 15s -> 12s, poll 500ms -> 200ms (reaction plus rapide).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:06:30 +02:00
46752bf29b Fix capture multi-pose : supp eosviewfinder (cause principale timeout)
- Retire eosviewfinder=1 avant/apres chaque prise : relancait le liveview
  (4-6s de blocage) → timeout 15s → ch=None → photos=[] → S_ACCUEIL
- Le miroir est deja leve par capture_preview() continu, l'obturateur
  seul se declenche via eosremoterelease=Immediate
- Logs detailles : chaque etape imprime son resultat pour debug
- Apres capture echouee : _prev_thumbs.append(None) pour garder index cohérent
- S_PREV 2.5s → 1.5s (plus reactif entre les poses)
- Apres capture : revient en S_PREV 0.6s pour montrer la vignette
- Print "Séquence terminée N/M photos" pour suivi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:22:30 +02:00
eb0634fab4 Fix captures 2/3 perdues + miroir + stabilite camera post-prise
- post_capture_grace=10 : ignore les erreurs -52 transitoires juste
  apres une prise (Canon EOS a besoin ~1s pour stabiliser le capteur)
- Threshold abandon capture : 3 -> 8 erreurs consecutives
- Threshold reconnexion : 5 -> 10 erreurs consecutives
- Avant chaque prise : eosviewfinder=1 pour garantir miroir leve
- Apres prise : viewfinder relance + sleep 1s + drain 8 evenements
- Sim auto-detect : pas de USB reset (evite boucle -52), verification
  fonctionnelle avec un capture_preview() avant de valider la camera
- Sim poll : 15s au lieu de 10s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:02:51 +02:00
529cb41581 Fix saccades LV + distorsion pellicule + draw_capture plein ecran
- Supprime sleep(0.3) apres chaque capture_preview() reussi
  (limitait le live view a ~3fps, cause principale des saccades)
- Fixe crash silencieux thread camera : _nb_retry non initialise
  pour errs 1-4 (NameError) -> restructure en for/else propre
- Pellicule live view : _pfit() au lieu de transform.scale() -> plus de distorsion
- draw_capture() : mode pellicule affiché au lieu de fullscreen black

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 11:15:46 +02:00
9c57c8f5f2 Bouton Quitter admin + boucle reconnexion caméra améliorée
- Admin onglet Système : bouton Quitter (gris) pour fermer l'appli
- Reconnexion caméra : max 10 tentatives (~30s) puis bascule en mode
  simulation ; le loop sim reprend la détection automatique toutes les 10s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:14:51 +02:00
d4ad1dec17 Fix déformation photos + miroir Canon EOS
- _pfit() : helper scale+crop centré pygame sans déformer
- ImageOps.fit() partout : vignettes, galerie, composite (recadrage centré
  au lieu de resize qui écrase)
- eosremoterelease 'Immediate' : déclenche l'obturateur Canon en restant
  en LV, évite la levée/baisse de miroir à chaque prise

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:49:46 +02:00
32e83250d2 USB reset aussi dans le loop de reconnexion automatique 2026-04-11 17:44:17 +02:00
5fc2f11bd4 Pellicule galerie + délai S_PREV + USB unbind/bind
- draw_galerie() : rendu pellicule (bande film avec perforations) quand le
  mode est actif
- _load_gal() : charge les surfs à la taille des cadres pellicule si actif
- S_PREV : 1.5s → 2.5s pour laisser le DSLR revenir en live view
- _usb_reset_done() : utilise unbind/bind sysfs au lieu de usbreset
  (unbind/bind = seule méthode qui libère réellement le claim USB)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:43:10 +02:00
0a90ae1de6 Auto-détection DSLR + reset USB au démarrage et toutes les 10s
- _usb_reset_done() : reset USB via usbreset pour libérer tout claim
  obsolète avant d'initialiser libgphoto2 (fix erreur -53)
- Appelé au démarrage et dans _cam_loop() toutes les 10s en simulation
- _cam_loop() : log les erreurs d'auto-detect pour diagnostic

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:40:10 +02:00
59370a4965 Fix pellicule compte à rebours + auto-détection DSLR
- draw_compte() pellicule : suppression de l'overlay global qui masquait la
  bande film pendant le compte à rebours
- _cam_loop() : ne quitte plus en mode simulation, tente une reconnexion
  automatique toutes les 8s si le DSLR est branché après démarrage
- _reconnect_cam() : fonctionne aussi depuis le mode simulation (bouton admin)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:34:05 +02:00
99ae7c785c Fix toggle pellicule_mode : premier clic activait en sens inverse
Le handler utilisait True comme défaut pour tous les toggles, ce qui faisait
que not f.get("pellicule_mode", True) = False au premier clic (toggle semblait
bloqué). Ajout d'un ensemble _false_defs pour les features à défaut False.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:24:49 +02:00
34f66bde1c Mode pellicule : bande style film 35mm activable dans l'admin
- Nouveau toggle "Mode pellicule" dans l'onglet Fonctions de l'admin
- _draw_pellicule() : bande noire cinéma avec perforations haut/bas,
  cadres numérotés (01A, 02A...) ; le live view est rendu dans le cadre
  courant, les photos prises occupent leur case, les futures sont en gris
- draw_preview() / draw_compte() : utilisent _draw_pellicule() quand activé
- _make_composite() : génère une bande simple (non doublée) en mode pellicule
- Thumbnails chargés à _PELL_FH (748px) pour la qualité native en pellicule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:17:43 +02:00
1c1f0323cc Multipose: composite upload + strip preview layout
- _make_composite(): crée une image bande (2 rangées) ou grille 2x2 à partir
  des photos prises, sauvée en /tmp/photobooth_composite.jpg
- _upload_booth(): upload le composite unique en mode multi au lieu des photos
  individuelles
- _draw_multi_strip(): overlay bas avec les cases numérotées — thumbnails pour
  les prises faites, cadre pulsant pour la case courante, placeholder gris pour
  les suivantes
- draw_preview() / draw_compte(): utilisent _draw_multi_strip() en mode multi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:08:17 +02:00
8ae42e1bc6 Backend: galerie session /s/{code} + upload API
Ajoute deux routes FastAPI :
- GET /s/{code} → galerie HTML mobile avec auto-refresh 15s
- POST /api/sessions/{code}/upload → stockage photo dans session_{code}/

Corrige layout admin : titre sm au lieu de lg, compteur sans chevauchement.
Wizard step 2 : code affiché en lg (96px) au lieu de xxl (300px).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 14:33:35 +02:00
a1a0ce0503 Scripts test liveview : pygame, pyqt6, opencv, tkinter - mesure FPS et premiere image 2026-04-09 12:42:50 +02:00