Galerie booth : QR avec auto-login, event_id aleatoire, flyer imprimable

- QR code inclut le mot de passe (?p=XXXX) pour acces direct sans saisie
- Supprime le code texte visible sur l'ecran d'accueil, QR plus petit
- Bouton admin 'Imprimer flyer QR galerie' genere un 10x15 avec
  nom evenement, QR code, texte invitation, design assorti
- Auto-login ajoute cote serveur booth (booth.copydev.fr)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 20:07:52 +02:00
parent 4d2d3e7a93
commit 98c738cf79
6 changed files with 90 additions and 17 deletions

View File

@@ -819,6 +819,77 @@ async def api_qr_galerie():
return {"chemin": f"/data/exports/{chemin.name}"}
@app.post("/api/booth/imprimer-qr")
async def api_booth_imprimer_qr():
"""Genere et imprime un flyer QR pour la galerie booth."""
config = charger_config()
booth = config.get("booth", {})
event = config.get("evenement", {})
if not booth.get("actif") or not booth.get("url"):
return JSONResponse({"erreur": "Booth non configure"}, status_code=400)
info = recuperer_booth_password()
password = info.get("password", "")
event_id = booth.get("event_id", "default")
nom_event = event.get("nom", "Photobooth")
url_galerie = f"{booth['url']}/{event_id}?p={password}"
from PIL import Image, ImageDraw, ImageFont
import qrcode
W, H = 1200, 1800 # 10x15 portrait @ 300dpi
img = Image.new("RGB", (W, H), "#0a0a1a")
draw = ImageDraw.Draw(img)
try:
font_big = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 72)
font_med = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 42)
font_small = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 32)
except OSError:
font_big = ImageFont.load_default()
font_med = font_big
font_small = font_big
# Titre evenement
draw.text((W // 2, 120), "📸", font=font_big, anchor="mt", fill="#e91e63")
draw.text((W // 2, 220), nom_event, font=font_big, anchor="mt", fill="#ffffff")
# Ligne decorative
draw.line([(150, 320), (W - 150, 320)], fill="#e91e63", width=3)
# Texte d'invitation
draw.text((W // 2, 400), "Retrouvez toutes les photos", font=font_med, anchor="mt", fill="#cccccc")
draw.text((W // 2, 460), "en direct sur la galerie !", font=font_med, anchor="mt", fill="#cccccc")
# QR code
qr = qrcode.QRCode(version=None, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=12, border=3)
qr.add_data(url_galerie)
qr.make(fit=True)
qr_img = qr.make_image(fill_color="#ffffff", back_color="#0a0a1a").convert("RGB")
qr_size = 700
qr_img = qr_img.resize((qr_size, qr_size), Image.NEAREST)
img.paste(qr_img, ((W - qr_size) // 2, 540))
# Instruction
draw.text((W // 2, 1300), "Scannez ce QR code", font=font_med, anchor="mt", fill="#ffffff")
draw.text((W // 2, 1360), "avec votre téléphone", font=font_med, anchor="mt", fill="#ffffff")
# Ligne decorative bas
draw.line([(150, 1460), (W - 150, 1460)], fill="#e91e63", width=3)
draw.text((W // 2, 1520), "Les photos apparaissent en temps réel", font=font_small, anchor="mt", fill="#888888")
draw.text((W // 2, 1570), "Téléchargez-les directement !", font=font_small, anchor="mt", fill="#888888")
# Sauvegarder
chemin = DOSSIER_EXPORTS / "flyer_qr_booth.jpg"
img.save(str(chemin), "JPEG", quality=95)
# Imprimer
ok = imprimer(str(chemin), copies=1)
return {"succes": ok, "chemin": f"/data/exports/flyer_qr_booth.jpg"}
# --- API Galerie ---
@app.get("/api/galerie")