""" Configuration Model Manejo de la configuración global del sistema """ import json from typing import Dict, List, Any from pathlib import Path class Config: """Clase para manejar la configuración global del sistema""" def __init__(self, config_path: str = None): if config_path is None: # Buscar config.json en el directorio del proyecto current_dir = Path(__file__).parent.parent.parent config_path = current_dir / "config.json" self.config_path = Path(config_path) self._config = {} self.load_config() def load_config(self) -> None: """Cargar configuración desde archivo JSON""" try: if self.config_path.exists(): with open(self.config_path, "r", encoding="utf-8") as f: self._config = json.load(f) else: # Crear configuración por defecto si no existe self._create_default_config() self.save_config() except Exception as e: raise Exception(f"Error cargando configuración: {e}") def save_config(self) -> None: """Guardar configuración actual al archivo JSON""" try: with open(self.config_path, "w", encoding="utf-8") as f: json.dump(self._config, f, indent=2, ensure_ascii=False) except Exception as e: raise Exception(f"Error guardando configuración: {e}") def _create_default_config(self) -> None: """Crear configuración por defecto""" self._config = { "observation_directories": [], "backup_destination": "D:\\Backups\\AutoBackups", "global_settings": { "default_schedule": "daily", "default_schedule_time": "02:00", "retry_delay_hours": 1, "backup_timeout_minutes": 0, "min_free_space_mb": 100, "scan_interval_minutes": 60, "min_backup_interval_minutes": 10, }, "everything_api": { "dll_path": "Everything-SDK\\dll\\Everything64.dll", "enabled": True, "search_depth": -1, "skip_last_level_for_s7p": True, }, "web_interface": {"host": "127.0.0.1", "port": 5000, "debug": False}, "logging": {"level": "INFO", "max_log_files": 30, "log_rotation_days": 30}, "backup_options": { "compression_level": 6, "include_subdirectories": True, "preserve_directory_structure": True, "hash_algorithm": "md5", "hash_includes": ["timestamp", "size"], "backup_type": "complete", "process_priority": "low", "sequential_execution": True, "filename_format": "HH-MM-SS_projects.zip", "date_format": "YYYY-MM-DD", }, } # Getters para las secciones principales @property def observation_directories(self) -> List[Dict[str, Any]]: return self._config.get("observation_directories", []) @property def backup_destination(self) -> str: return self._config.get("backup_destination", "") @property def global_settings(self) -> Dict[str, Any]: return self._config.get("global_settings", {}) @property def everything_api(self) -> Dict[str, Any]: return self._config.get("everything_api", {}) @property def web_interface(self) -> Dict[str, Any]: return self._config.get("web_interface", {}) @property def logging_config(self) -> Dict[str, Any]: return self._config.get("logging", {}) @property def backup_options(self) -> Dict[str, Any]: return self._config.get("backup_options", {}) # Métodos de utilidad def get_dll_path(self) -> str: """Obtener la ruta completa de la DLL de Everything""" dll_relative_path = self.everything_api.get("dll_path", "") if dll_relative_path: # Convertir ruta relativa a absoluta current_dir = Path(__file__).parent.parent.parent.parent return str(current_dir / dll_relative_path) return "" def get_min_free_space_mb(self) -> int: """Obtener el espacio mínimo libre requerido en MB""" return self.global_settings.get("min_free_space_mb", 100) def get_scan_interval_minutes(self) -> int: """Obtener el intervalo de escaneo en minutos""" return self.global_settings.get("scan_interval_minutes", 60) def get_min_backup_interval_minutes(self) -> int: """Obtener el intervalo mínimo de backup en minutos""" return self.global_settings.get("min_backup_interval_minutes", 10) def add_observation_directory( self, path: str, dir_type: str, description: str = "" ) -> None: """Agregar un nuevo directorio de observación""" new_dir = { "path": path, "type": dir_type, "enabled": True, "description": description, } if "observation_directories" not in self._config: self._config["observation_directories"] = [] self._config["observation_directories"].append(new_dir) self.save_config() def update_config_value(self, key_path: str, value: Any) -> None: """Actualizar un valor específico en la configuración usando dot notation""" keys = key_path.split(".") current = self._config # Navegar hasta el penúltimo nivel for key in keys[:-1]: if key not in current: current[key] = {} current = current[key] # Establecer el valor final current[keys[-1]] = value self.save_config() def get_full_config(self) -> Dict[str, Any]: """Obtener toda la configuración actual""" return self._config.copy()