feat: gestion événements — historique, export ZIP, filtre galerie
🚀 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-17 14:43:05 +02:00
parent 7d60eba86d
commit d5f111d60b
10 changed files with 329 additions and 117 deletions
+53
View File
@@ -2,10 +2,14 @@
from __future__ import annotations
import io
import logging
import zipfile
from datetime import datetime
from pathlib import Path
from fastapi import APIRouter, Request
from fastapi.responses import StreamingResponse, JSONResponse
from pydantic import BaseModel
from backend.services.event_service import slugify
@@ -81,6 +85,55 @@ async def update_event(request: Request, payload: EventUpdate):
}
@router.get("/event/{slug}/export")
async def export_event_zip(request: Request, slug: str):
"""Exporte toutes les photos d'un événement dans un fichier ZIP.
Les photos sont sélectionnées par timestamp de fichier (mtime) entre
started_at et ended_at de l'événement. Pour l'événement en cours,
ended_at = maintenant.
"""
event_svc = request.app.state.event_service
cfg = request.app.state.config
ev = await event_svc.get_event_by_slug(slug)
if not ev:
return JSONResponse({"error": f"Événement '{slug}' introuvable"}, status_code=404)
started_at = ev["started_at"] or 0.0
ended_at = ev["ended_at"] or datetime.now().timestamp()
media_dir = Path(cfg.photobooth.media_dir)
if not media_dir.exists():
return JSONResponse({"error": "Dossier média introuvable"}, status_code=500)
# Sélectionner les photos dans la plage de l'événement
photos = []
for f in sorted(media_dir.iterdir()):
if f.suffix.lower() not in (".jpg", ".jpeg", ".png"):
continue
mtime = f.stat().st_mtime
if started_at <= mtime <= ended_at:
photos.append(f)
if not photos:
return JSONResponse({"error": "Aucune photo pour cet événement"}, status_code=404)
# Créer le ZIP en mémoire
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zf:
for photo in photos:
zf.write(photo, photo.name)
buf.seek(0)
filename = f"{slug}_By_LSDW_{datetime.fromtimestamp(started_at).strftime('%Y-%m-%d')}.zip"
return StreamingResponse(
buf,
media_type="application/zip",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
@router.get("/event/history")
async def get_event_history(request: Request):
"""Retourne tous les événements passés avec leurs statistiques."""