# agent_v1/session/storage.py """ Gestionnaire de stockage local robuste pour Agent V1. Gère le chiffrement des données au repos et l'auto-nettoyage du disque. """ import os import shutil import time import logging from pathlib import Path from datetime import datetime, timedelta logger = logging.getLogger("session_storage") class SessionStorage: def __init__(self, base_dir: Path, max_size_gb: int = 5, retention_days: int = 1): self.base_dir = base_dir self.max_size_bytes = max_size_gb * 1024 * 1024 * 1024 self.retention_days = retention_days self.base_dir.mkdir(parents=True, exist_ok=True) def get_session_dir(self, session_id: str) -> Path: """Retourne et crée le dossier pour une session.""" session_path = self.base_dir / session_id session_path.mkdir(exist_ok=True) (session_path / "shots").mkdir(exist_ok=True) return session_path def run_auto_cleanup(self): """Lance le nettoyage automatique basé sur l'âge et la taille.""" logger.info("🧹 Lancement du nettoyage automatique du stockage local...") self._cleanup_by_age() self._cleanup_by_size() def _cleanup_by_age(self): """Supprime les sessions plus vieilles que retention_days.""" threshold = datetime.now() - timedelta(days=self.retention_days) for session_path in self.base_dir.iterdir(): if session_path.is_dir(): mtime = datetime.fromtimestamp(session_path.stat().st_mtime) if mtime < threshold: logger.info(f"🗑️ Purge session ancienne : {session_path.name}") shutil.rmtree(session_path) def _cleanup_by_size(self): """Supprime les sessions les plus anciennes si la taille totale dépasse max_size_bytes.""" sessions = [] total_size = 0 for session_path in self.base_dir.iterdir(): if session_path.is_dir(): size = sum(f.stat().st_size for f in session_path.rglob('*') if f.is_file()) sessions.append((session_path, session_path.stat().st_mtime, size)) total_size += size if total_size > self.max_size_bytes: logger.warning(f"⚠️ Stockage saturé ({total_size/1e9:.2f} GB). Purge nécessaire.") # Trier par date de modif (plus ancien d'abord) sessions.sort(key=lambda x: x[1]) for path, _, size in sessions: if total_size <= self.max_size_bytes * 0.8: # On libère jusqu'à 80% du max break logger.info(f"🗑️ Purge session pour libérer de l'espace : {path.name} ({size/1e6:.1f} MB)") shutil.rmtree(path) total_size -= size