예제 #1
0
    def to_python(self, content):
        data = None

        if self.format == 'ini':
            output = StringIO(content)

            config = ConfigParser()
            config.readfp(output)

            data = config._defaults.copy()

            for section in config.sections():
                if not section in data:
                    data[section] = {}

                for key, value in config.items(section):
                    data[section].update({key: value})
        elif self.format == 'json':
            if content:
                kwargs = self._prepare_json_kwargs(loads=True)
                data = json.loads(content, **kwargs)
            else:
                data = {}
        elif self.format == 'pickle':
            data = pickle.loads(content)

        if data is None:
            raise ImproperlyConfigured('File format %r is not supported.' % \
                                       self.format)

        return self._batch_method('to_python', data)
예제 #2
0
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
예제 #3
0
    def from_python(self, data):
        data = self._batch_method('to_python', data)

        if self.format == 'ini':
            output = StringIO()
            old_data = data

            data, defaults = {}, {}

            for key, value in old_data.items():
                if isinstance(value, dict):
                    data[key] = value
                else:
                    defaults[key] = value

            config = ConfigParser(defaults=defaults)

            for section, subdata in data.items():
                if not config.has_section(section):
                    config.add_section(section)

                for key, value in subdata.items():
                    config.set(section, key, str(value))

            config.write(output)

            output.seek(0)
            return output.read()
        elif self.format == 'json':
            kwargs = self._prepare_json_kwargs(dumps=True)
            return json.dumps(data, **kwargs)
        elif self.format == 'pickle':
            return pickle.dumps(data)

        raise ImproperlyConfigured('File format %r is not supported.' % \
                                   self.format)
예제 #4
0
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