AutoBackups/autobackups/src/models/config_model.py

168 lines
5.9 KiB
Python

"""
Configuration Model
Manejo de la configuración global del sistema
"""
import json
import os
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()