SXXXXXXX_RepoSync/reposync/config/profile_manager.py

115 lines
4.0 KiB
Python

# RepoSync/config/profile_manager.py
"""
Manages loading and saving of server connection profiles and application
settings from a JSON file.
"""
import json
import logging
import os
from pathlib import Path
from typing import Dict, List, Optional, Any
logger = logging.getLogger(__name__)
def get_config_path() -> Path:
"""
Gets the path to the configuration file inside a 'config' subdirectory
relative to the application's current working directory.
"""
base_path = Path.cwd()
config_dir = base_path / "config"
config_dir.mkdir(exist_ok=True)
return config_dir / "profiles.json"
class ProfileManager:
"""Handles CRUD for server profiles and app settings."""
def __init__(self):
self.profiles_path = get_config_path()
self.profiles: Dict[str, Dict] = {}
self.settings: Dict[str, Any] = {}
self.load_data()
def load_data(self):
"""Loads both profiles and settings from the JSON file."""
logger.info(f"Loading data from: {self.profiles_path}")
if not self.profiles_path.exists():
self.profiles = {}
self.settings = {
"bundle_path": str(Path.home() / "RepoSyncBundles"),
"git_timeout": 600 # Default: 10 minutes
}
logger.warning("Profiles file not found. Using default settings.")
return
try:
with open(self.profiles_path, "r", encoding="utf-8") as f:
data = json.load(f)
self.profiles = data.get("profiles", {})
self.settings = data.get("settings", {})
# Ensure defaults are set if they are missing from the file
if "bundle_path" not in self.settings:
self.settings["bundle_path"] = str(Path.home() / "RepoSyncBundles")
if "git_timeout" not in self.settings:
self.settings["git_timeout"] = 600
logger.info(f"Loaded {len(self.profiles)} profiles and app settings.")
except (json.JSONDecodeError, IOError) as e:
logger.error(f"Failed to load or parse profiles file: {e}. Starting fresh.")
self.profiles = {}
self.settings = {
"bundle_path": str(Path.home() / "RepoSyncBundles"),
"git_timeout": 600
}
def save_data(self):
"""Saves both profiles and settings to the JSON file."""
logger.info(f"Saving data to: {self.profiles_path}")
data_to_save = {
"profiles": self.profiles,
"settings": self.settings
}
try:
with open(self.profiles_path, "w", encoding="utf-8") as f:
json.dump(data_to_save, f, indent=4)
except IOError as e:
logger.error(f"Failed to save profiles file: {e}")
def get_profile(self, name: str) -> Optional[Dict]:
"""Retrieves a single profile by name."""
return self.profiles.get(name)
def get_all_profiles(self) -> Dict[str, Dict]:
"""Returns all loaded profiles."""
return self.profiles
def get_profile_names(self) -> List[str]:
"""Returns a list of all profile names."""
return list(self.profiles.keys())
def add_or_update_profile(self, name: str, data: Dict):
"""Adds a new profile or updates an existing one."""
if not name.strip(): raise ValueError("Profile name cannot be empty.")
self.profiles[name] = data
self.save_data()
def delete_profile(self, name: str):
"""Deletes a profile by name."""
if name in self.profiles:
del self.profiles[name]
self.save_data()
def get_setting(self, key: str, default: Any = None) -> Any:
"""Gets a specific application setting."""
return self.settings.get(key, default)
def set_setting(self, key: str, value: Any):
"""Sets an application setting and saves it."""
logger.info(f"Updating setting '{key}' to '{value}'")
self.settings[key] = value
self.save_data()