AutoBackups/src/models/config_model.py

166 lines
5.9 KiB
Python

"""
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()