""" Linux BenchTools - YAML Configuration Loader Load and manage YAML configuration files """ import os import yaml from typing import Dict, Any, List, Optional from pathlib import Path class YAMLConfigLoader: """YAML configuration file loader""" def __init__(self, config_dir: str = "./config"): """ Initialize YAML loader Args: config_dir: Directory containing YAML config files """ self.config_dir = config_dir self._cache = {} def load_config(self, filename: str, force_reload: bool = False) -> Dict[str, Any]: """ Load a YAML configuration file Args: filename: YAML filename (without path) force_reload: Force reload even if cached Returns: Parsed YAML data as dictionary """ if not force_reload and filename in self._cache: return self._cache[filename] filepath = os.path.join(self.config_dir, filename) if not os.path.exists(filepath): return {} with open(filepath, 'r', encoding='utf-8') as f: data = yaml.safe_load(f) or {} self._cache[filename] = data return data def save_config(self, filename: str, data: Dict[str, Any]) -> bool: """ Save a YAML configuration file Args: filename: YAML filename (without path) data: Dictionary to save Returns: True if successful """ filepath = os.path.join(self.config_dir, filename) # Ensure directory exists os.makedirs(self.config_dir, exist_ok=True) try: with open(filepath, 'w', encoding='utf-8') as f: yaml.safe_dump(data, f, allow_unicode=True, sort_keys=False, indent=2) # Update cache self._cache[filename] = data return True except Exception as e: print(f"Error saving YAML config: {e}") return False def get_peripheral_types(self) -> List[Dict[str, Any]]: """ Get peripheral types configuration Returns: List of peripheral type definitions """ config = self.load_config("peripheral_types.yaml") return config.get("peripheral_types", []) def get_peripheral_type(self, type_id: str) -> Optional[Dict[str, Any]]: """ Get specific peripheral type configuration Args: type_id: Peripheral type ID Returns: Peripheral type definition or None """ types = self.get_peripheral_types() for ptype in types: if ptype.get("id") == type_id: return ptype return None def add_peripheral_type(self, type_data: Dict[str, Any]) -> bool: """ Add a new peripheral type Args: type_data: Peripheral type definition Returns: True if successful """ config = self.load_config("peripheral_types.yaml", force_reload=True) if "peripheral_types" not in config: config["peripheral_types"] = [] # Check if type already exists existing_ids = [t.get("id") for t in config["peripheral_types"]] if type_data.get("id") in existing_ids: return False config["peripheral_types"].append(type_data) return self.save_config("peripheral_types.yaml", config) def update_peripheral_type(self, type_id: str, type_data: Dict[str, Any]) -> bool: """ Update an existing peripheral type Args: type_id: Peripheral type ID to update type_data: New peripheral type definition Returns: True if successful """ config = self.load_config("peripheral_types.yaml", force_reload=True) if "peripheral_types" not in config: return False # Find and update for i, ptype in enumerate(config["peripheral_types"]): if ptype.get("id") == type_id: config["peripheral_types"][i] = type_data return self.save_config("peripheral_types.yaml", config) return False def delete_peripheral_type(self, type_id: str) -> bool: """ Delete a peripheral type Args: type_id: Peripheral type ID to delete Returns: True if successful """ config = self.load_config("peripheral_types.yaml", force_reload=True) if "peripheral_types" not in config: return False # Filter out the type original_count = len(config["peripheral_types"]) config["peripheral_types"] = [ t for t in config["peripheral_types"] if t.get("id") != type_id ] if len(config["peripheral_types"]) < original_count: return self.save_config("peripheral_types.yaml", config) return False def get_location_types(self) -> List[Dict[str, Any]]: """ Get location types configuration Returns: List of location type definitions """ config = self.load_config("locations.yaml") return config.get("location_types", []) def get_stockage_locations(self) -> List[str]: """ Get storage locations list (for non-used peripherals) Returns: List of storage location names """ config = self.load_config("locations.yaml") locations = config.get("stockage_locations", []) return [l for l in locations if isinstance(l, str)] def get_image_processing_config(self) -> Dict[str, Any]: """ Get image processing configuration Returns: Image processing settings """ config = self.load_config("image_processing.yaml") return config.get("image_processing", {}) def get_notification_config(self) -> Dict[str, Any]: """ Get notification configuration Returns: Notification settings """ config = self.load_config("notifications.yaml") return config.get("notifications", {}) def get_boutiques(self) -> List[str]: """ Get boutique list configuration Returns: List of boutique names """ config = self.load_config("boutique.yaml") boutiques = config.get("boutiques", []) return [b for b in boutiques if isinstance(b, str)] def get_hosts(self) -> List[Dict[str, str]]: """ Get hosts list configuration Returns: List of hosts with name and location """ config = self.load_config("host.yaml") hosts = config.get("hosts", []) result = [] for host in hosts: if not isinstance(host, dict): continue name = host.get("nom") location = host.get("localisation", "") if isinstance(name, str) and name: result.append({"nom": name, "localisation": location}) return result def get_loan_reminder_days(self) -> int: """ Get number of days before loan return to send reminder Returns: Number of days """ config = self.get_notification_config() return config.get("loan_reminder_days", 7) def clear_cache(self): """Clear the configuration cache""" self._cache = {} # Global instance yaml_loader = YAMLConfigLoader()