aboutsummaryrefslogtreecommitdiff
path: root/dodai/config/sections.py
diff options
context:
space:
mode:
Diffstat (limited to 'dodai/config/sections.py')
-rw-r--r--dodai/config/sections.py172
1 files changed, 172 insertions, 0 deletions
diff --git a/dodai/config/sections.py b/dodai/config/sections.py
new file mode 100644
index 0000000..feb59be
--- /dev/null
+++ b/dodai/config/sections.py
@@ -0,0 +1,172 @@
1# Copyright (C) 2010 Leonard Thomas
2#
3# This file is part of Dodai.
4#
5# Dodai is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# Dodai is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Dodai. If not, see <http://www.gnu.org/licenses/>.
17
18import unicodedata
19
20class ConfigSections(object):
21 """
22 An iterable object that contains ConfigSection objects
23
24 """
25
26 def __init__(self, string_object = None):
27 """
28 Iterable object that handles the conversion of a config
29 parser object to a list of section objects.
30
31
32 string_object: This is an object (non instantiated or
33 callable) that the results of the config's
34 sections, and options will be stored in.
35 This enables you to store your values as a
36 custom object. A good object to use is the
37 dodai.tools.himo Himo object. If the
38 string_object is not given the default python
39 str() object will be used.
40
41 """
42 self._string_object = string_object or None
43 self._sections = {}
44
45 def __call__(self, parser):
46 """
47 Parses the given parser object into this object's sections.
48
49 parser: The actual parser object that is used to
50 get the sections. This object must have
51 the sections(), options() and get()
52 methods. A good object to use is the native
53 ConfigParse object. However, you can create
54 your own
55
56 """
57 self._build_sections(parser)
58
59 def _build_sections(self, parser):
60 # Builds ConfigSection objects from the parser object
61
62 for section_name in parser.sections():
63 section = self.get_section(section_name)
64 self._build_options(parser, section_name, section)
65
66 def _build_options(self, parser, section_name, section):
67 # Adds the options to the section object
68
69 for key in parser.options(section_name):
70 key = unicode(self._build_string_object(key))
71 value = self._build_string_object(parser.get(section_name, key))
72 setattr(section, key, value)
73
74 def _build_string_object(self, data):
75 if self._string_object:
76 return self._string_object(data)
77 else:
78 return data
79
80 def get_section(self, section_name):
81 """
82 Returns a ConfigSection object from this object's section
83 dictionary or creates a new ConfigSection object, which is
84 stored int this object's section dictionary then is returned
85
86 """
87 section_name = unicode(self._build_string_object(section_name))
88 if section_name in self._sections:
89 return self._sections[section_name]
90 else:
91 section = ConfigSection(section_name)
92 self._sections[section_name] = section
93 return section
94
95 def __getitem__(self, key):
96 key = normalize_key(key)
97 return self._sections[key]
98
99 def __getattr__(self, key):
100 key = normalize_key(key)
101 try:
102 out = self._sections[key]
103 except KeyError:
104 return getattr(self._sections, key)
105 else:
106 return out
107
108 def __iter__(self, *args, **kargs):
109 return self._sections.__iter__(*args, **kargs)
110
111
112 def __len__(self):
113 return len(self._sections)
114
115class ConfigSection(object):
116 """
117 A generic object to hold keys and values primarily from a config file
118
119 """
120 def __init__(self, title):
121 """
122 Holds keys and values primarily from a section of a config file
123
124 title: The title of the section of the config file
125
126 """
127 self.___title___ = title
128 self.___options___ = {}
129
130
131 def get_title(self):
132 """
133 Returns the title of the section
134
135 """
136 return self.___title___
137
138
139 def __setattr__(self, key, value):
140 if key.startswith('___') and key.endswith('___'):
141 object.__setattr__(self, key, value)
142 else:
143 key = normalize_key(key)
144 if self.___options___.has_key(key):
145 self.___options___[key] = value
146 else:
147 dict.__setitem__(self.___options___, key, value)
148
149 def __getattr__(self, key):
150 if key.startswith('___') and key.endswith('___'):
151 return self.__dict__[key]
152 else:
153 key = normalize_key(key)
154 try:
155 out = self.___options___[key]
156 except KeyError:
157 return getattr(self.___options___, key)
158 else:
159 return out
160
161 def __getitem__(self, key):
162 key = normalize_key(key)
163 return self.___options___[key]
164
165 def __iter__(self, *args, **kargs):
166 return self.___options___.__iter__(*args, **kargs)
167
168
169def normalize_key(key):
170 key = unicode(key)
171 key = unicodedata.normalize('NFC', key)
172 return key