import json import os from dataclasses import dataclass, field from typing import List, Optional CONFIG_VERSION = 2 @dataclass class Profile: name: str esde_src: str = "" roms_src: str = "" esde_dst: str = "" roms_dst: str = "" selected: List[str] = field(default_factory=list) def to_dict(self) -> dict: return { "name": self.name, "esde_src": self.esde_src, "roms_src": self.roms_src, "esde_dst": self.esde_dst, "roms_dst": self.roms_dst, "selected": self.selected, } @staticmethod def from_dict(data: dict) -> "Profile": return Profile( name=data.get("name", "Default"), esde_src=data.get("esde_src", ""), roms_src=data.get("roms_src", ""), esde_dst=data.get("esde_dst", ""), roms_dst=data.get("roms_dst", ""), selected=data.get("selected", []), ) class ConfigManager: def __init__(self, config_path: str): self.config_path = config_path self.profiles: List[Profile] = [Profile(name="Default")] self.active_profile_name: str = "Default" @property def active_profile(self) -> Profile: for p in self.profiles: if p.name == self.active_profile_name: return p # Si el perfil activo no existe, devolver el primero return self.profiles[0] def profile_names(self) -> List[str]: return [p.name for p in self.profiles] def get_profile(self, name: str) -> Optional[Profile]: for p in self.profiles: if p.name == name: return p return None def add_profile(self, name: str) -> Profile: p = Profile(name=name) self.profiles.append(p) return p def rename_profile(self, old_name: str, new_name: str) -> bool: p = self.get_profile(old_name) if p is None or self.get_profile(new_name) is not None: return False p.name = new_name if self.active_profile_name == old_name: self.active_profile_name = new_name return True def delete_profile(self, name: str) -> bool: if len(self.profiles) <= 1: return False p = self.get_profile(name) if p is None: return False self.profiles.remove(p) if self.active_profile_name == name: self.active_profile_name = self.profiles[0].name return True def load(self) -> None: if not os.path.exists(self.config_path): return try: with open(self.config_path, "r", encoding="utf-8") as f: data = json.load(f) except Exception: return version = data.get("version", 1) if version == 1: self._migrate_v1(data) self.save() else: self._load_v2(data) def _migrate_v1(self, data: dict) -> None: default = Profile( name="Default", esde_src=data.get("esde_src", ""), roms_src=data.get("roms_src", ""), esde_dst=data.get("esde_dst", ""), roms_dst=data.get("roms_dst", ""), selected=data.get("selected", []), ) self.profiles = [default] self.active_profile_name = "Default" def _load_v2(self, data: dict) -> None: raw_profiles = data.get("profiles", []) if not raw_profiles: return self.profiles = [Profile.from_dict(p) for p in raw_profiles] self.active_profile_name = data.get("active_profile", self.profiles[0].name) # Asegurar que el perfil activo existe if self.get_profile(self.active_profile_name) is None: self.active_profile_name = self.profiles[0].name def save(self) -> None: data = { "version": CONFIG_VERSION, "active_profile": self.active_profile_name, "profiles": [p.to_dict() for p in self.profiles], } with open(self.config_path, "w", encoding="utf-8") as f: json.dump(data, f, indent=4, ensure_ascii=False)