Initial commit — Serveur Lucas SmartEye

API réception alertes chute (SmartEye/YOLO), analyse IA (Gemini 2.5 Flash),
gestion alertes avec escalade (watchdog), notifications Firebase,
dashboard web, documentation MkDocs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-03-14 21:26:06 +01:00
commit 24dbc7cd6a
64 changed files with 9677 additions and 0 deletions

138
repair_missing_analyses.py Executable file
View File

@@ -0,0 +1,138 @@
#!/usr/bin/env python3
"""
Script de réparation pour analyser les images historiques
qui n'ont pas de fichier JSON sidecar
"""
import os
import sys
import json
import glob
from datetime import datetime
# Import du module d'analyse
sys.path.insert(0, '/var/www/lucas')
from analyze import analyze_image
def find_images_without_json(client_folder):
"""Trouve toutes les images sans fichier JSON"""
images = glob.glob(f"{client_folder}/*.jpg")
missing = []
for img in images:
json_file = img + ".json"
if not os.path.exists(json_file):
missing.append(img)
return sorted(missing, key=lambda x: os.path.getmtime(x), reverse=True)
def repair_image_analysis(image_path):
"""Analyse une image et crée son fichier JSON sidecar"""
print(f"\n📸 Analyse: {os.path.basename(image_path)}")
try:
# Analyser l'image
result = analyze_image(image_path)
# Créer le fichier JSON sidecar
history_data = {
"urgence": result.get("urgence", False),
"message": result.get("message", "Analyse rétrospective"),
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"retrospective": True # Marqueur pour indiquer que c'est une analyse a posteriori
}
json_file = image_path + ".json"
with open(json_file, 'w') as f:
json.dump(history_data, f, indent=2)
status = "🚨 URGENCE" if result.get("urgence") else "✅ SÉCURISÉ"
print(f" {status} - {result.get('message', '')[:60]}")
return True
except Exception as e:
print(f" ❌ ERREUR: {type(e).__name__}: {str(e)}")
# Créer quand même un JSON avec l'erreur
history_data = {
"urgence": None, # null = inconnu
"message": f"Erreur d'analyse rétrospective: {type(e).__name__}",
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"retrospective": True,
"error": True
}
json_file = image_path + ".json"
with open(json_file, 'w') as f:
json.dump(history_data, f, indent=2)
return False
def main():
print("="*70)
print("RÉPARATION DES ANALYSES MANQUANTES")
print("="*70)
client_folder = "/var/www/lucas/clients/Demo_01"
if not os.path.exists(client_folder):
print(f"❌ Dossier introuvable: {client_folder}")
return 1
# Trouver les images sans JSON
print(f"\n🔍 Recherche des images sans analyse...")
missing_images = find_images_without_json(client_folder)
if not missing_images:
print("✅ Toutes les images ont déjà une analyse JSON!")
return 0
print(f"\n📊 Trouvé: {len(missing_images)} images sans analyse")
# Demander confirmation si beaucoup d'images
if len(missing_images) > 50:
print(f"\n⚠️ ATTENTION: {len(missing_images)} images à analyser")
print(f" Cela peut prendre ~{len(missing_images) * 5} secondes")
response = input(" Continuer ? (o/n): ")
if response.lower() != 'o':
print("Annulé.")
return 0
# Analyser les images
print(f"\n🚀 Démarrage de l'analyse...")
print("-"*70)
success_count = 0
error_count = 0
for i, img in enumerate(missing_images, 1):
print(f"\n[{i}/{len(missing_images)}]", end=" ")
if repair_image_analysis(img):
success_count += 1
else:
error_count += 1
# Résumé
print("\n" + "="*70)
print("RÉSUMÉ")
print("="*70)
print(f"Images analysées: {len(missing_images)}")
print(f"✅ Succès: {success_count}")
print(f"❌ Erreurs: {error_count}")
print("\n✓ Réparation terminée!")
print("="*70)
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except KeyboardInterrupt:
print("\n\n⚠️ Interruption par l'utilisateur")
sys.exit(1)
except Exception as e:
print(f"\n❌ Erreur fatale: {type(e).__name__}: {e}")
import traceback
traceback.print_exc()
sys.exit(1)