def parse_configs(framework): """ Parse all available config definition files as for all availbale apps and for project itself at last. Also we need to read additional types and additional default values before parsing start. """ additional_types = framework.get_additional_types() all_settings = SettingsContainer() default_values = {} fail_silently = framework.fail_silently # Use ``OrderedDict`` instance for reading sections on config file instead # of default ``dict`` that can shuffle the sections. config = ConfigParser(dict_type=OrderedDict) # First we need to read default values file default_values_file = framework.find_default_values_file() if default_values_file: config.no_sections_mode = True try: config.read(default_values_file) except ConfigParserError: logger.exception('Cannot read default values from %r', default_values_file) else: default_values = config.defaults() finally: config.no_sections_mode = False # Read available settings files from framework pathes = framework.find_settings_files() for app_name, path in pathes.items(): if app_name == '__project__': continue settings = \ parse_config(path, additional_types, default_values, app_name) all_settings.add(app_name, settings) # And finally read project configuration definition file if any path = pathes.get('__project__') settings = parse_config(path, additional_types, default_values, all_settings=all_settings) all_settings.add('__project__', settings) all_settings.path = settings.path return all_settings
def parse_config(path, additional_types=None, default_values=None, app_name=None, all_settings=None): """ Parse Configuration Definition File. In most cases this file needs to be placed in same folder where project settings module exist and named as ``settings.cfg``. But you can customize things with using ``SETMAN_SETTINGS_FILE`` option. Provide there path where settings file actually placed. Also current function can called with ``path`` string. """ config = ConfigParser(dict_type=OrderedDict) empty_settings = SettingsContainer(path, app_name) try: config.read(path) except ConfigParserError: logger.exception('Cannot parse configuration definition file from ' \ '%r', path) return empty_settings settings = copy.deepcopy(empty_settings) for setting in config.sections(): if '.' in setting: full_setting = setting app_name, setting = setting.split('.', 1) try: app_settings = getattr(all_settings, app_name) except AttributeError: logger.exception('Cannot find settings for %r app', app_name) continue try: app_setting = getattr(app_settings, setting) except AttributeError: logger.exception('Cannot find %r app setting %r', app_name, setting) continue data = dict(config.items(full_setting)) if default_values and full_setting in default_values: data.update({'default': default_values[setting]}) try: app_setting = update_app_setting(app_setting, data) except ValueError: logger.exception('Cannot redefine ``type`` attr for %r ' \ 'setting', full_setting) continue else: data = dict(config.items(setting)) data.update({'app_name': app_name, 'name': setting}) if default_values and setting in default_values: data.update({'default': default_values[setting]}) try: setting = data_to_setting(data, additional_types) except SettingTypeDoesNotExist: logger.exception('Cannot find proper setting class for %r ' \ 'type', data.get('type')) return empty_settings settings.add(setting.name, setting) return settings