/
Flipper
/
Marginal
Обзор
Документация
Войти
/
Flipper
/
Marginal
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
1
CI/CD
Аналитика
Безопасность
master
src/ConfigManager.py
224 строки
8 KB
Alex
Marginal v1.0.0 RELEASE
11 янв 2026, 18:02
11 янв 2026, 18:02
5e1eff8
Код
Авторство
О чём код?
import json import os from src.utils import generateFullPath from utils import getBasePath, getBakedPath class ConfigManager(): """ Manages application configuration, including loading, saving, validating, and providing access to configuration data with compatibility checking. """ def __init__(self, backbone, limitInit: bool = False): """ Initialize ConfigManager with application backbone. Args: backbone (Backbone): Central application controller. limitInit (bool): If True, skips user configuration validation. """ self.backbone = backbone self.logger = self.backbone.logger self.limitInit = limitInit self.localDataPath = os.path.join(getBakedPath(), r"local") self.configPath = os.path.join(getBasePath(), r"config\config.json") self.minSaveVer = str() self.defaultConfig = dict() self.config = dict() self.appMetadata = dict() self.loadConfig() if not limitInit: self.checkUserConfig() def loadConfig(self): """ Load application metadata, default configuration, and user configuration. Performs compatibility checks and falls back to default if user config is invalid. Returns: None """ # Load application metadata (contains compatibility information) with open(os.path.join(self.localDataPath, "app_metadata.json"), "r") as metadata: self.appMetadata = json.load(metadata) self.minSaveVer = self.appMetadata["compatibility"]["min_save"] # Load default configuration with open(os.path.join(self.localDataPath, "app_defaultConfig.json"), "r") as defaultConfig: self.defaultConfig = json.load(defaultConfig) # Load user configuration if it exists if os.path.isfile(self.configPath): with open(self.configPath, "r") as configFile: userConfig = json.load(configFile) try: # Check version compatibility before using user config if self.backbone.validator.checkCompatibility( userConfig["version"], self.minSaveVer ): self.config = userConfig else: # Incompatible version - fall back to default if self.logger: self.logger.log( "ConfigManager", "Failed to load user config\n-> using default configuration." ) self.config = self.defaultConfig except Exception as e: # Any error during loading - fall back to default if self.logger: self.logger.log( "ConfigManager", "Unexpected error during config loading\n-> using default configuration." ) self.config = self.defaultConfig else: # No user config file exists - use default and save it self.config = self.defaultConfig # Ensure config file exists (creates it if missing) if not os.path.isfile(self.configPath) and not self.limitInit: self.saveConfig() def getConfig(self, key=None): """ Retrieve configuration value(s) by key or entire configuration. Args: key (str, optional): Specific configuration key to retrieve. Returns: dict | any -> Requested configuration value(s). Returns empty dict if key not found. """ if key is not None and key in self.config.keys(): return self.config[key] elif key and key not in self.config.keys(): return dict() else: return self.config def updateConfig(self, changes: dict): """ Update configuration with provided changes and save to disk. Args: changes (dict): Key-value pairs to update in configuration. Returns: None """ self.config.update(changes) self.saveConfig() def saveConfig(self, refresh: bool = True): """ Save current configuration to disk. Args: refresh (bool): Whether to trigger application config refresh. Returns: None """ with open(self.configPath, 'w') as cnfg: json.dump(self.config, cnfg, indent=2) if refresh and not self.limitInit: self.backbone.refreshConfigs() def getMeta(self, key=None): """ Retrieve application metadata value(s) by key or entire metadata. Args: key (str, optional): Specific metadata key to retrieve. Returns: dict | any -> Requested metadata value(s). Returns empty dict if key not found. """ if key is not None and key in self.appMetadata.keys(): return self.appMetadata[key] elif key and key not in self.appMetadata.keys(): return dict() else: return self.appMetadata def getDefault(self, key=None): """ Retrieve default configuration value(s) by key or entire default config. Args: key (str, optional): Specific default config key to retrieve. Returns: dict | any -> Requested default configuration value(s). Returns empty dict if key not found. """ if key is not None and key in self.defaultConfig.keys(): return self.defaultConfig[key] elif key and key not in self.defaultConfig.keys(): return dict() else: return self.defaultConfig def checkUserConfig(self): """ Validate paths in user configuration and replace invalid ones with defaults. Called during initialization unless limitInit is True. Returns: None """ exportConf = self.getConfig("exportOptions") dirs = [ exportConf["exportPath"], exportConf["exportSearchPath"], exportConf["inputDataSearchFolder"], exportConf["profileSearchFolder"] ] self.backbone.checkDirs(dirs, False, self.replaceInvalidPaths) def replaceInvalidPaths(self, path: str): """ Replace invalid paths in configuration with default values. Args: path (str): The invalid path that needs to be replaced. Returns: None """ keysToPaths = [ "exportPath", "exportSearchPath", "inputDataSearchFolder", "profileSearchFolder" ] # Find which configuration key contains the invalid path for key in keysToPaths: if ( key in self.config["exportOptions"].keys() and generateFullPath(getBasePath(), self.config["exportOptions"][key]) == path ): # Replace with default value self.config["exportOptions"][key] = self.defaultConfig["exportOptions"][key] if self.logger: self.logger.log( "ConfigManager", "Invalid path ({path}) were replaced with default values. " "Replaced path: \n{defPath}", path=path, defPath=self.config["exportOptions"][key] ) break