Files
photobooth/backend/destinations.py
Jules d9de999d74 Backoffice complet : materiel, compteur, destinations, cadres, animations
- Onglet Materiel : choix appareil photo + imprimante
- Compteur avec limite configurable (399/400) affiche sur l'accueil
- Destinations multiples : memoire interne, cle USB, FTP, site web, email
- Choix sauvegarder toutes les photos ou seulement les imprimees
- Gestion des cadres : activation/desactivation + import
- 7 animations de compte a rebours : classique, explosion, rebond,
  rotation 3D, fondu, emoji fun, tremblement
- Preview des animations dans le backoffice
- Module destinations.py (copie USB, envoi FTP, compteur)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 23:03:30 +01:00

115 lines
3.6 KiB
Python

import ftplib
import logging
import shutil
from pathlib import Path
from backend.config import charger_config, mettre_a_jour_config
log = logging.getLogger("photobooth.destinations")
def distribuer_photo(chemin_photo: Path, imprimee: bool = False):
"""Copie la photo vers toutes les destinations activees."""
config = charger_config()
dest = config.get("destinations", {})
# Verifier si on sauvegarde tout ou seulement les imprimees
if not dest.get("sauvegarder_tout", True) and not imprimee:
log.info(f"Photo non imprimee, pas de distribution : {chemin_photo.name}")
return
# Cle USB
if dest.get("cle_usb", False):
copier_usb(chemin_photo, dest.get("chemin_usb", "/media/usb"))
# FTP
if dest.get("ftp", False):
envoyer_ftp(chemin_photo, dest)
# Incrementer le compteur
compteur = config.get("compteur", {})
if compteur.get("actif", False):
compteur["photos_prises"] = compteur.get("photos_prises", 0) + 1
mettre_a_jour_config({"compteur": compteur})
def copier_usb(chemin_photo: Path, chemin_usb: str):
"""Copie une photo sur la cle USB."""
dossier_usb = Path(chemin_usb)
if not dossier_usb.exists():
log.warning(f"Cle USB non trouvee : {chemin_usb}")
return False
dossier_dest = dossier_usb / "photobooth"
dossier_dest.mkdir(exist_ok=True)
try:
shutil.copy2(chemin_photo, dossier_dest / chemin_photo.name)
log.info(f"Photo copiee sur USB : {chemin_photo.name}")
return True
except OSError as e:
log.error(f"Erreur copie USB : {e}")
return False
def envoyer_ftp(chemin_photo: Path, config_dest: dict):
"""Envoie une photo par FTP."""
host = config_dest.get("ftp_host", "")
port = config_dest.get("ftp_port", 21)
user = config_dest.get("ftp_user", "")
password = config_dest.get("ftp_password", "")
chemin_distant = config_dest.get("ftp_chemin", "/photobooth")
if not host:
log.warning("FTP non configure")
return False
try:
with ftplib.FTP() as ftp:
ftp.connect(host, port, timeout=10)
ftp.login(user, password)
# Creer le dossier si necessaire
try:
ftp.mkd(chemin_distant)
except ftplib.error_perm:
pass
ftp.cwd(chemin_distant)
with open(chemin_photo, "rb") as f:
ftp.storbinary(f"STOR {chemin_photo.name}", f)
log.info(f"Photo envoyee par FTP : {chemin_photo.name}")
return True
except (ftplib.all_errors, OSError) as e:
log.error(f"Erreur FTP : {e}")
return False
def detecter_usb() -> list[str]:
"""Detecte les cles USB montees."""
chemins_possibles = [Path("/media"), Path("/mnt")]
usb_trouvees = []
for racine in chemins_possibles:
if racine.exists():
for sous_dossier in racine.iterdir():
if sous_dossier.is_mount() or (sous_dossier.is_dir() and any(sous_dossier.iterdir())):
usb_trouvees.append(str(sous_dossier))
return usb_trouvees
def compteur_restant() -> dict:
"""Retourne l'etat du compteur."""
config = charger_config()
compteur = config.get("compteur", {})
limite = compteur.get("limite", 400)
prises = compteur.get("photos_prises", 0)
return {
"actif": compteur.get("actif", False),
"limite": limite,
"photos_prises": prises,
"restantes": max(0, limite - prises),
}
def reset_compteur():
"""Remet le compteur a zero."""
mettre_a_jour_config({"compteur": {"photos_prises": 0}})