SXXXXXXX_GitUtility/profile_handler.py
2025-04-14 09:02:34 +02:00

194 lines
7.5 KiB
Python

# profile_handler.py
import logging
# Assuming ConfigManager handles its own constants now
from config_manager import ConfigManager, DEFAULT_PROFILE, DEFAULT_BACKUP_DIR
class ProfileHandler:
"""Handles loading, saving, adding, removing profiles via ConfigManager."""
def __init__(self, logger, config_manager: ConfigManager):
"""
Initializes the ProfileHandler.
Args:
logger (logging.Logger): Logger instance.
config_manager (ConfigManager): Instance to interact with config file.
"""
self.logger = logger
self.config_manager = config_manager
def get_profile_list(self):
"""Returns the list of available profile names."""
return self.config_manager.get_profile_sections()
def load_profile_data(self, profile_name):
"""
Loads all relevant data for a given profile name.
Args:
profile_name (str): The name of the profile to load.
Returns:
dict or None: A dictionary containing all profile settings,
or None if the profile doesn't exist.
"""
self.logger.info(f"Loading data for profile: '{profile_name}'")
if profile_name not in self.get_profile_list():
self.logger.error(f"Cannot load: Profile '{profile_name}' not found.")
return None
# Use ConfigManager's internal knowledge of keys and defaults
keys_with_defaults = self.config_manager._get_expected_keys_with_defaults()
profile_data = {}
# Load each option using ConfigManager
for key, default_value in keys_with_defaults.items():
# Pass the actual default value from the dictionary
profile_data[key] = self.config_manager.get_profile_option(
profile_name, key, fallback=default_value
)
# Convert loaded string values back to appropriate types if needed
# Example: Booleans
profile_data["autocommit"] = (
str(profile_data.get("autocommit", "False")).lower() == "true"
)
profile_data["autobackup"] = (
str(profile_data.get("autobackup", "False")).lower() == "true"
)
self.logger.debug(f"Loaded data for '{profile_name}': {profile_data}")
return profile_data
def save_profile_data(self, profile_name, profile_data):
"""
Saves the provided data dictionary to the specified profile name.
Args:
profile_name (str): The name of the profile to save.
profile_data (dict): Dictionary containing the settings to save.
Keys should match config options.
Returns:
bool: True on success, False on failure.
"""
if not profile_name:
self.logger.warning("Cannot save: No profile name provided.")
return False
if not isinstance(profile_data, dict):
self.logger.error("Cannot save: Invalid profile data format (not a dict).")
return False
self.logger.info(f"Saving data for profile: '{profile_name}'")
try:
# Iterate through data and save using ConfigManager
for key, value in profile_data.items():
# Convert specific types back to string for storage
if isinstance(value, bool):
value_to_save = str(value)
# Add other type conversions if necessary
else:
# Assume other types can be directly converted to string
value_to_save = str(value) if value is not None else ""
self.config_manager.set_profile_option(profile_name, key, value_to_save)
# Persist changes to the configuration file
self.config_manager.save_config()
self.logger.info(f"Profile '{profile_name}' saved successfully.")
return True
except Exception as e:
self.logger.error(
f"Error saving profile '{profile_name}': {e}", exc_info=True
)
# Let the caller (main app) show the error message
return False
def add_new_profile(self, profile_name):
"""
Adds a new profile with default settings.
Args:
profile_name (str): The name for the new profile.
Returns:
bool: True if added successfully, False otherwise.
"""
self.logger.info(f"Attempting to add new profile: '{profile_name}'")
# Basic validation
if not profile_name:
self.logger.warning("Add profile failed: Name cannot be empty.")
return False
if profile_name in self.get_profile_list():
self.logger.warning(f"Add profile failed: '{profile_name}' already exists.")
return False
try:
# Get defaults and customize for a new profile
defaults = self.config_manager._get_expected_keys_with_defaults()
defaults["bundle_name"] = f"{profile_name}_repo.bundle"
defaults["bundle_name_updated"] = f"{profile_name}_update.bundle"
defaults["svn_working_copy_path"] = "" # Start empty
defaults["usb_drive_path"] = "" # Start empty
# Set all options for the new profile section
# ConfigManager.set_profile_option creates the section if needed
for key, value in defaults.items():
self.config_manager.set_profile_option(profile_name, key, value)
# Save the configuration file
self.config_manager.save_config()
self.logger.info(f"Profile '{profile_name}' added successfully.")
return True
except Exception as e:
# Log unexpected errors during profile addition
self.logger.error(
f"Error adding profile '{profile_name}': {e}", exc_info=True
)
return False
def remove_existing_profile(self, profile_name):
"""
Removes an existing profile (cannot remove the default profile).
Args:
profile_name (str): The name of the profile to remove.
Returns:
bool: True if removed successfully, False otherwise.
"""
self.logger.info(f"Attempting to remove profile: '{profile_name}'")
# Validation checks
if not profile_name:
self.logger.warning("Remove profile failed: No name provided.")
return False
if profile_name == DEFAULT_PROFILE:
self.logger.warning("Remove profile failed: Cannot remove default.")
return False
if profile_name not in self.get_profile_list():
self.logger.warning(f"Remove profile failed: '{profile_name}' not found.")
return False
try:
# Attempt removal using ConfigManager
success = self.config_manager.remove_profile_section(profile_name)
if success:
# Save config only if removal was successful
self.config_manager.save_config()
self.logger.info(f"Profile '{profile_name}' removed.")
return True
else:
# ConfigManager should log the reason for failure
self.logger.error(
f"ConfigManager reported failure removing '{profile_name}'."
)
return False
except Exception as e:
# Log unexpected errors during removal
self.logger.error(
f"Error removing profile '{profile_name}': {e}", exc_info=True
)
return False