# Copyright (C) 2010 Leonard Thomas # # This file is part of Dodai. # # Dodai is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Dodai is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Dodai. If not, see . import unicodedata class ConfigSections(object): """ An iterable object that contains ConfigSection objects """ def __init__(self, string_object = None): """ Iterable object that handles the conversion of a config parser object to a list of section objects. string_object: This is an object (non instantiated or callable) that the results of the config's sections, and options will be stored in. This enables you to store your values as a custom object. A good object to use is the dodai.tools.himo Himo object. If the string_object is not given the default python str() object will be used. The callable of this object must also allow for encoding to be passed in string_object(data, 'UTF-8') """ self._string_object = string_object or None self._sections = {} def __call__(self, parser, encoding=None): """ Parses the given parser object into this object's sections. parser: The actual parser object that is used to get the sections. This object must have the sections(), options() and get() methods. A good object to use is the native ConfigParse object. However, you can create your own """ self._build_sections(parser, encoding) def _build_sections(self, parser, encoding): # Builds ConfigSection objects from the parser object for section_name in parser.sections(): section = self.get_section(section_name, encoding) self._build_options(parser, section_name, section, encoding) def _build_options(self, parser, section_name, section, encoding): # Adds the options to the section object for key in parser.options(section_name): key = self._build_string_object(key, encoding) value = self._build_string_object(parser.get(section_name, key), encoding) setattr(section, key, value) def _build_string_object(self, data, encoding=None): if self._string_object: return self._string_object(data, encoding) else: return data def get_section(self, section_name, encoding=None): """ Returns a ConfigSection object from this object's section dictionary or creates a new ConfigSection object, which is stored int this object's section dictionary then is returned """ section_name = self._build_string_object(section_name, encoding) if section_name in self._sections: return self._sections[section_name] else: section = ConfigSection(section_name) self._sections[section_name] = section return section def __getitem__(self, key): key = normalize_key(key) return self._sections[key] def __getattr__(self, key): key = normalize_key(key) try: out = self._sections[key] except KeyError: return getattr(self._sections, key) else: return out def __iter__(self, *args, **kargs): return self._sections.__iter__(*args, **kargs) def __len__(self): return len(self._sections) class ConfigSection(object): """ A generic object to hold keys and values primarily from a config file """ def __init__(self, title): """ Holds keys and values primarily from a section of a config file title: The title of the section of the config file """ self.___title___ = title self.___options___ = {} def get_title(self): """ Returns the title of the section """ return self.___title___ def __setattr__(self, key, value): if key.startswith('___') and key.endswith('___'): object.__setattr__(self, key, value) else: key = normalize_key(key) if self.___options___.has_key(key): self.___options___[key] = value else: dict.__setitem__(self.___options___, key, value) def __getattr__(self, key): if key.startswith('___') and key.endswith('___'): return self.__dict__[key] else: key = normalize_key(key) try: out = self.___options___[key] except KeyError: return getattr(self.___options___, key) else: return out def __getitem__(self, key): key = normalize_key(key) return self.___options___[key] def __iter__(self, *args, **kargs): return self.___options___.__iter__(*args, **kargs) def normalize_key(key): key = unicode(key) key = unicodedata.normalize('NFC', key) return key