#-*- coding: utf-8 -*- import configparser import os import glob import copy from lodel.settings.utils import * ##@brief Merges and loads configuration files class SettingsLoader(object): ## To avoid the DEFAULT section whose values are found in all sections, we # have to give it an unsual name DEFAULT_SECTION = 'lodel2_default_passaway_tip' ##@brief Constructor # @param conf_path str : conf.d path def __init__(self,conf_path): self.__conf_path=conf_path self.__conf_sv=dict() self.__conf=self.__merge() ##@brief Lists and merges files in settings_loader.conf_path # @return dict() def __merge(self): conf = dict() l_dir = glob.glob(self.__conf_path+'/*.ini') for f_ini in l_dir: config = configparser.ConfigParser(default_section = self.DEFAULT_SECTION ,interpolation=None) config.read(f_ini) for section in [ s for s in config if s != self.DEFAULT_SECTION ]: if section not in conf: conf[section] = dict() for param in config[section]: if param not in conf[section]: conf[section][param]=dict() conf[section][param]['value'] = config[section][param] conf[section][param]['file'] = f_ini self.__conf_sv[section + ':' + param]=f_ini else: raise SettingsError("Error redeclaration of key %s in section %s. Found in %s and %s" % ( section, param, f_ini, conf[section][param]['file'])) return conf ##@brief Returns option if exists default_value else and validates # @param section str : name of the section # @param keyname str # @param validator callable : takes one argument value and raises validation fail # @param default_value * # @param mandatory bool # @return the option def getoption(self,section,keyname,validator,default_value=None,mandatory=False): conf=self.__conf if section in conf: sec=conf[section] if keyname in sec: optionstr=sec[keyname]['value'] option= validator(sec[keyname]['value']) try: del self.__conf_sv[section + ':' + keyname] except KeyError: #allready fetched pass return option elif default_value is None and mandatory: raise SettingsError("Default value mandatory for option %s" % keyname) sec[keyname]=dict() sec[keyname]['value'] = default_value sec[keyname]['file'] = 'default_value' return default_value else: conf[section]=dict() conf[section][keyname]=dict() conf[section][keyname]['value'] = default_value conf[section][keyname]['file'] = 'default_value' return default_value ##@brief Sets option in a config section. Writes in the conf file # @param section str : name of the section # @param keyname str # @param value str # @param validator callable : takes one argument value and raises validation fail # @return the option def setoption(self,section,keyname,value,validator): f_conf=copy.copy(self.__conf[section][keyname]['file']) if f_conf == 'default_value': f_conf = self.__conf_path + '/generated.ini' conf=self.__conf conf[section][keyname] = value config = configparser.ConfigParser() config.read(f_conf) if section not in config: config[section]={} config[section][keyname] = validator(value) with open(f_conf, 'w') as configfile: config.write(configfile) ##@brief Saves new partial configuration. Writes in the conf files corresponding # @param sections dict # @param validators dict of callable : takes one argument value and raises validation fail def saveconf(self, sections, validators): for sec in sections: for kname in sections[sec]: self.setoption(sec,kname,sections[sec][kname],validators[sec][kname]) ##@brief Returns the section to be configured # @param section_prefix str # @param default_section str # @return the section as dict() def getsection(self,section_prefix,default_section=None): conf=copy.copy(self.__conf) sections=[] if section_prefix in conf: sections.append(section_prefix) for sect_names in conf: if sect_names in sections: pass elif sect_names.startswith(section_prefix + '.'): sections.append(sect_names) if sections == [] and default_section: sections.append(section_prefix + '.' + default_section) elif sections == []: raise NameError("Not existing settings section : %s" % section__prefix) return sections; ## @brief Returns invalid settings # # This method returns all the settings that was not fecthed by # getsection() method. For the Settings object it allows to know # the list of invalids settings keys # @return a dict with SECTION_NAME+":"+KEY_NAME as key and the filename # where the settings was found as value def getremains(self): return self.__conf_sv