import os import json import uuid from pathlib import Path from typing import Optional, List from pydantic import BaseModel, Field AGENT_HOME = Path(os.environ.get("PROGRAMDATA", "C:/ProgramData")) / "OnEverDrive" if not AGENT_HOME.exists(): try: AGENT_HOME.mkdir(parents=True, exist_ok=True) except Exception: AGENT_HOME = Path(__file__).resolve().parent.parent / "data" AGENT_HOME.mkdir(parents=True, exist_ok=True) CONFIG_FILE = AGENT_HOME / "config.json" class LocalFolderJob(BaseModel): id: str = Field(default_factory=lambda: str(uuid.uuid4())[:8]) job_id: Optional[int] = None name: str source_path: str file_patterns: str = "*.bak,*.mdf" schedule_cron: str = "daily" schedule_interval_minutes: int = 60 min_stable_seconds: int = 60 is_active: bool = True last_backup_at: Optional[str] = None last_status: Optional[str] = "En espera" class AgentConfig(BaseModel): server_url: str = "http://127.0.0.1:8000" client_code: Optional[str] = None device_id: Optional[str] = None device_token: Optional[str] = None client_name: Optional[str] = None chunk_size: int = 4 * 1024 * 1024 # 4 MB heartbeat_interval_seconds: int = 30 min_stable_time_seconds: int = 60 log_level: str = "INFO" local_folders: List[LocalFolderJob] = [] # Notification preferences (configurable from GUI and Tray) enable_notifications: bool = True notify_on_start: bool = True notify_on_complete: bool = True notify_on_error: bool = True def load_config() -> AgentConfig: """Loads agent configuration from disk or returns default configuration.""" if CONFIG_FILE.exists(): try: with open(CONFIG_FILE, "r", encoding="utf-8") as f: data = json.load(f) return AgentConfig(**data) except Exception: pass return AgentConfig() def save_config(config: AgentConfig) -> None: """Persists agent configuration to disk.""" CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True) with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(config.model_dump(), f, indent=2)