from fastapi import APIRouter, HTTPException, Depends, BackgroundTasks
from fastapi.responses import HTMLResponse
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import os
import logging
from datetime import datetime
from typing import Optional
# Import avec gestion des erreurs pour les imports relatifs
try:
from ..services.vector_updater import VectorUpdater
except ImportError:
try:
from app.services.vector_updater import VectorUpdater
except ImportError:
# Import direct pour quand l'application est lancée depuis le répertoire racine
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from services.vector_updater import VectorUpdater
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/admin", tags=["admin"])
security = HTTPBearer()
# Instance globale du updater - créée de manière paresseuse pour éviter les erreurs d'import
vector_updater = None
def get_vector_updater():
"""Get vector updater instance (lazy initialization)"""
global vector_updater
if vector_updater is None:
vector_updater = VectorUpdater()
return vector_updater
def verify_admin_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
"""Vérification du token admin"""
admin_token = os.getenv('ADMIN_TOKEN')
if not admin_token or credentials.credentials != admin_token:
raise HTTPException(status_code=403, detail="Invalid admin token")
return credentials.credentials
@router.get("/", response_class=HTMLResponse)
async def admin_dashboard():
"""Interface web d'administration"""
html_content = """
Karl Movie Vector - Admin
🎬 Karl Movie Vector - Administration
📊 Statut du Système
🚀 Mise à jour des Vecteurs
Déclenchez manuellement la mise à jour des vecteurs de films depuis TMDB.
⏳ Mise à jour en cours...
📋 Logs de Mise à jour
Cliquez sur "Charger les Logs" pour voir les logs...
"""
return HTMLResponse(content=html_content)
@router.get("/status")
async def get_status(token: str = Depends(verify_admin_token)):
"""Obtenir le statut du système"""
return get_vector_updater().get_update_status()
@router.post("/update-vectors")
async def update_vectors(background_tasks: BackgroundTasks, token: str = Depends(verify_admin_token)):
"""Déclencher une mise à jour si nécessaire"""
vector_updater = get_vector_updater()
if vector_updater.is_updating:
return {"success": False, "message": "Une mise à jour est déjà en cours"}
# Lancer la mise à jour en arrière-plan
background_tasks.add_task(vector_updater.update_vectors_if_needed)
return {"success": True, "message": "Mise à jour programmée (vérification des conditions)"}
@router.post("/force-update-vectors")
async def force_update_vectors(background_tasks: BackgroundTasks, token: str = Depends(verify_admin_token)):
"""Forcer la mise à jour des vecteurs"""
vector_updater = get_vector_updater()
if vector_updater.is_updating:
return {"success": False, "message": "Une mise à jour est déjà en cours"}
# Lancer la mise à jour forcée en arrière-plan
background_tasks.add_task(vector_updater.force_update_vectors)
return {"success": True, "message": "Mise à jour forcée programmée"}
@router.get("/logs")
async def get_logs(token: str = Depends(verify_admin_token)):
"""Obtenir les logs de mise à jour"""
try:
logs = get_vector_updater().get_logs()
return {"logs": logs}
except Exception as e:
return {"logs": [f"Erreur de lecture des logs: {e}"]}