Animations custom (video/GIF) + selection aleatoire
- Upload de GIF/MP4/WebM comme animations de compte a rebours - Checkboxes pour activer/desactiver chaque animation (CSS + custom) - Si plusieurs actives, tirage aleatoire a chaque photo - Preview dans le backoffice avec tirage aleatoire - Suppression des animations custom importees - Les animations custom se jouent en plein ecran avant la capture Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ DOSSIER_PHOTOS = RACINE / "data" / "photos"
|
||||
DOSSIER_EXPORTS = RACINE / "data" / "exports"
|
||||
DOSSIER_OVERLAYS = RACINE / "frontend" / "assets" / "overlays"
|
||||
DOSSIER_FONDS = RACINE / "frontend" / "assets" / "backgrounds"
|
||||
DOSSIER_ANIMATIONS = RACINE / "frontend" / "assets" / "animations"
|
||||
|
||||
|
||||
def charger_config() -> dict:
|
||||
@@ -48,5 +49,5 @@ def _merge_profond(base: dict, modifications: dict):
|
||||
|
||||
|
||||
# Initialisation des dossiers au chargement du module
|
||||
for dossier in [DOSSIER_PHOTOS, DOSSIER_EXPORTS, DOSSIER_OVERLAYS, DOSSIER_FONDS]:
|
||||
for dossier in [DOSSIER_PHOTOS, DOSSIER_EXPORTS, DOSSIER_OVERLAYS, DOSSIER_FONDS, DOSSIER_ANIMATIONS]:
|
||||
dossier.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -10,7 +10,7 @@ from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from backend.config import (
|
||||
RACINE, DOSSIER_PHOTOS, DOSSIER_EXPORTS, DOSSIER_OVERLAYS, DOSSIER_FONDS,
|
||||
RACINE, DOSSIER_PHOTOS, DOSSIER_EXPORTS, DOSSIER_OVERLAYS, DOSSIER_FONDS, DOSSIER_ANIMATIONS,
|
||||
charger_config, sauvegarder_config, mettre_a_jour_config,
|
||||
)
|
||||
from backend.camera import camera
|
||||
@@ -348,6 +348,44 @@ async def api_animations():
|
||||
return ANIMATIONS_CAR
|
||||
|
||||
|
||||
@app.get("/api/animations/custom")
|
||||
async def api_animations_custom():
|
||||
"""Liste les animations personnalisees (GIF/video)."""
|
||||
extensions = {".gif", ".mp4", ".webm"}
|
||||
fichiers = []
|
||||
if DOSSIER_ANIMATIONS.exists():
|
||||
for f in sorted(DOSSIER_ANIMATIONS.iterdir()):
|
||||
if f.suffix.lower() in extensions:
|
||||
fichiers.append(f.name)
|
||||
config = charger_config()
|
||||
actives = config.get("animations_custom", {}).get("actives", [])
|
||||
return {"tous": fichiers, "actives": actives}
|
||||
|
||||
|
||||
@app.post("/api/animations/custom")
|
||||
async def api_animations_custom_update(donnees: dict):
|
||||
actives = donnees.get("actives", [])
|
||||
mettre_a_jour_config({"animations_custom": {"actives": actives}})
|
||||
return {"actives": actives}
|
||||
|
||||
|
||||
@app.post("/api/upload/animation")
|
||||
async def api_upload_animation(fichier: UploadFile = File(...)):
|
||||
chemin = DOSSIER_ANIMATIONS / fichier.filename
|
||||
with open(chemin, "wb") as f:
|
||||
f.write(await fichier.read())
|
||||
return {"nom": fichier.filename}
|
||||
|
||||
|
||||
@app.delete("/api/animations/custom/{nom}")
|
||||
async def api_supprimer_animation(nom: str):
|
||||
chemin = DOSSIER_ANIMATIONS / nom
|
||||
if chemin.exists() and chemin.parent == DOSSIER_ANIMATIONS:
|
||||
chemin.unlink()
|
||||
return {"succes": True}
|
||||
return JSONResponse({"erreur": "Fichier introuvable"}, status_code=404)
|
||||
|
||||
|
||||
# --- API Systeme ---
|
||||
|
||||
@app.post("/api/systeme/redemarrer")
|
||||
|
||||
Reference in New Issue
Block a user