root/cherokee/trunk/admin/config.py

Revision 2210, 7.9 kB (checked in by taher, 1 month ago)

--

Line 
1 import copy
2 import types
3
4 class ConfigNode (object):
5     def __init__ (self):
6         self._val   = None
7         self._child = {}
8
9     # Value
10     #
11     def _get_value (self):
12         return self._val
13     def _set_value (self, val):
14         self._val = val
15
16     value = property (_get_value, _set_value)
17
18     def get_val (self, key, default=None):
19         try:
20             subcfg = self[key]
21         except:
22             return default
23         if not subcfg:
24             return default
25         return subcfg.value
26
27     # Get child
28     #
29     def _getitem_simple (self, key):
30         if not key in self._child:
31             return None
32
33         r = self._child[key]
34         assert (isinstance(r, ConfigNode))
35         return r
36
37     def _getitem_complex (self, path):
38         node = self
39         for p in path.split('!'):
40             tmp = node[p]
41             if not tmp:
42                 return None
43             node = tmp
44         return node
45
46     def __getitem__ (self, path):
47         if '!' in path:
48             return self._getitem_complex (path)
49         else:
50             return self._getitem_simple (path)
51
52     # Add children
53     #
54     def _create_path (self, path):
55         node = self
56         for p in path.split('!'):
57             tmp = node[p]
58             if not tmp:
59                 tmp = ConfigNode()
60                 node[p] = tmp
61             node = tmp
62         return node
63
64     def _setitem_simple (self, key, val):
65         assert (isinstance(val, ConfigNode))
66         self._child[key] = val
67
68     def __setitem__ (self, key, val):
69         if '!' in key:
70             obj = self[key]
71             if not obj:
72                 self._create_path(key)
73
74         if isinstance (val, ConfigNode):
75             if '!' in key:
76                 parts = key.split('!')
77                 last  = parts[-1]
78                 prev  = reduce (lambda x,y: "%s!%s" % (x,y), parts[:-1])
79                 obj = self[prev]
80                 obj._child[last] = val
81             else:
82                 self._child[key] = val
83         else:
84             if '!' in key:
85                 self[key].value = val
86             else:
87                 child = self[key]
88                 if not child:
89                     child = self._create_path (key)
90                 child.value = val
91
92     # Modify child
93     #
94     def __delitem__ (self, key):
95         del (self._child[key])
96
97     def __iter__ (self):
98         return iter(self._child)
99
100     # Serialize
101     def serialize (self, path=''):
102         content = ''
103         if self._val is not None:
104             if type(self._val) == types.BooleanType:
105                 val = str(int(self._val))
106             else:
107                 val = str(self._val)
108             content += '%s = %s\n' % (path, val)
109
110         for name in self._child:
111             if name == 'tmp':
112                 continue
113
114             node = self._child[name]
115             if len(path) != 0:
116                 new_path = "%s!%s" % (path, name)
117             else:
118                 new_path = name
119
120             content += node.serialize (new_path)
121         return content
122
123     # Sub-tree operations
124     def set_value (self, key, val):
125         if not key in self._child:
126             cfg = ConfigNode()
127             self._child[key] = cfg
128         else:
129             cfg = self._child[key]
130
131         cfg.value = val
132
133     def has_child (self):
134         return len(self._child) > 0
135
136     def keys (self):
137         return self._child.keys()
138
139
140 class Config:
141     def __init__ (self, file=None):
142         self.root = ConfigNode()
143         self.file = file
144
145         # Build ConfigNode tree
146         if file:
147             try:
148                 f = open (file, "r")
149             except:
150                 pass
151             else:
152                 self._parse (f.read())
153                 f.close()
154
155     def _create_path (self, path):
156         node = self.root
157         for p in path.split('!'):
158             tmp = node[p]
159             if not tmp:
160                 tmp = ConfigNode()
161                 node[p] = tmp
162             node = tmp
163         return node
164
165     def _parse (self, config_string):
166         for line in config_string.split('\n'):
167             node = self.root
168
169             while len(line) > 1 and line[-1] in " \r\n\t":
170                 line = line[:-1]
171
172             if len(line) < 5: continue
173             if line[0] == '#': continue
174
175             try:
176                 path, value = line.split (" = ")
177             except:
178                 print "ERROR: Couldn't unpack '%s'"%(line)
179                 raise
180
181             node = self._create_path (path)
182             node.value = value
183
184     def __str__ (self):
185         return self.root.serialize()
186
187     # Access
188     def __getitem__ (self, path):
189         return self.root[path]
190
191     def clone (self, path_old, path_new):
192         parent, parent_path, child_name = self._get_parent_node (path_old)
193         if self.root[path_new]:
194             return True
195         copied = copy.deepcopy (self[path_old])
196         self.set_sub_node (path_new, copied)
197
198     def rename (self, path_old, path_new):
199         error = self.clone (path_old, path_new)
200         if not error:
201             del(self[path_old])
202         return error
203
204     def set_sub_node (self, path, config_node):
205         assert (isinstance(config_node, ConfigNode))
206
207         parent, parent_path, child_name = self._get_parent_node (path)
208         if parent:
209             if not parent._child.has_key(child_name):
210                 parent._create_path(child_name)
211             parent._child[child_name] = config_node
212
213     def __setitem__ (self, path, val):
214         if not isinstance (val, ConfigNode):
215             if not val or len(val) == 0:
216                 del (self[path])
217                 return
218
219         tmp = self[path]
220         if not tmp:
221             tmp = self._create_path (path)
222
223         tmp.value = val
224
225     def _get_parent_node (self, path):
226         preg = path.split('!')
227         last = preg[-1]
228         pres = reduce (lambda x,y: "%s!%s" % (x,y), preg[:-1])
229         return (self[pres], pres, last)
230
231     def get_val (self, path, default=None):
232         return self.root.get_val (path, default)
233
234     def __delitem__ (self, path):
235         parent, parent_path, child_name = self._get_parent_node (path)
236         if parent and parent._child.has_key(child_name):
237             del (parent._child[child_name])
238
239     def keys (self, path):
240         tmp = self[path]
241         if not tmp:
242             return []
243         return tmp.keys()
244
245     def pop (self, key):
246         tmp = self.get_val(key)
247         del (self[key])
248         return tmp
249
250     # Serialization
251     def serialize (self):
252         def sorter(x,y):
253             order = ['server', 'vserver', 'source', 'icons', 'mime']
254             a = x.split('!')
255             b = y.split('!')
256             try:
257                 ai = order.index(a[0])
258                 bi = order.index(b[0])
259             except:
260                 return cmp(x,y)
261
262             # Different tags
263             if ai > bi:
264                 return  1
265             elif ai < bi:
266                 return -1
267
268             # Sort rules: reverse
269             if ((len(a) > 3) and
270                 (a[0] == b[0] == 'vserver') and
271                 (a[1] == b[1]) and
272                 (a[2] == b[2] == 'rule')):
273                 re = cmp (int(b[3]), int(a[3]))
274                 if re != 0:
275                     return re
276
277             return cmp(x,y)
278
279         tmp = self.root.serialize().split('\n')
280         tmp.sort(sorter)
281         return '\n'.join(tmp)
282
283     def save (self):
284         # Try to make a copy
285         try:
286             t = open (self.file+'.backup', 'w')
287             s = open (self.file, 'r')
288             t.write (s.read())
289             t.close()
290             s.close()
291         except:
292             print ("Could copy configuration to " + self.file+'.backup')
293
294         # Write the new one
295         cfg = self.serialize()
296
297         t = open (self.file, 'w')
298         t.write (cfg)
299         t.close()
300
301     # Checks
302     def is_writable (self):
303         import os
304
305         if not os.path.exists (self.file):
306             return False
307         return os.access (self.file, os.W_OK)
308
309     def has_tree (self):
310         return len(self.root._child) > 0
311
Note: See TracBrowser for help on using the browser.