|
@@ -5,6 +5,7 @@ import os
|
5
|
5
|
import configparser
|
6
|
6
|
import copy
|
7
|
7
|
import warnings
|
|
8
|
+import types # for dynamic bindings
|
8
|
9
|
from collections import namedtuple
|
9
|
10
|
|
10
|
11
|
from lodel.plugin.plugins import Plugins, PluginError
|
|
@@ -21,6 +22,7 @@ PYTHON_SYS_LIB_PATH = '/usr/local/lib/python{major}.{minor}/'.format(
|
21
|
22
|
|
22
|
23
|
major = sys.version_info.major,
|
23
|
24
|
minor = sys.version_info.minor)
|
|
25
|
+
|
24
|
26
|
##@brief Handles configuration load etc.
|
25
|
27
|
#
|
26
|
28
|
# To see howto bootstrap Settings and use it in lodel instance see
|
|
@@ -71,7 +73,7 @@ class Settings(object):
|
71
|
73
|
##@brief Should be called only by the boostrap classmethod
|
72
|
74
|
# @param conf_file str : Path to the global lodel2 configuration file
|
73
|
75
|
# @param conf_dir str : Path to the conf directory
|
74
|
|
- def __init__(self, conf_file = '/etc/lodel2/lodel2.conf', conf_dir = 'conf.d'):
|
|
76
|
+ def __init__(self, conf_file, conf_dir):
|
75
|
77
|
self.__confs = dict()
|
76
|
78
|
self.__conf_dir = conf_dir
|
77
|
79
|
self.__load_bootstrap_conf(conf_file)
|
|
@@ -98,6 +100,14 @@ class Settings(object):
|
98
|
100
|
##@brief This method handlers Settings instance bootstraping
|
99
|
101
|
def __bootstrap(self):
|
100
|
102
|
lodel2_specs = LODEL2_CONF_SPECS
|
|
103
|
+ for section in lodel2_specs:
|
|
104
|
+ if section.lower() != section:
|
|
105
|
+ raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
|
|
106
|
+ for kname in lodel2_specs[section]:
|
|
107
|
+ if kname.lower() != kname:
|
|
108
|
+ raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
|
|
109
|
+
|
|
110
|
+
|
101
|
111
|
plugins_opt_specs = lodel2_specs['lodel2']['plugins']
|
102
|
112
|
|
103
|
113
|
# Init the settings loader
|
|
@@ -129,12 +139,16 @@ class Settings(object):
|
129
|
139
|
res = copy.copy(specs.pop())
|
130
|
140
|
for spec in specs:
|
131
|
141
|
for section in spec:
|
|
142
|
+ if section.lower() != section:
|
|
143
|
+ raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
|
132
|
144
|
if section not in res:
|
133
|
145
|
res[section] = dict()
|
134
|
146
|
for kname in spec[section]:
|
|
147
|
+ if kname.lower() != kname:
|
|
148
|
+ raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
|
135
|
149
|
if kname in res[section]:
|
136
|
150
|
raise SettingsError("Duplicated key '%s' in section '%s'" % (kname, section))
|
137
|
|
- res[section][kname] = copy.copy(spec[section][kname])
|
|
151
|
+ res[section.lower()][kname] = copy.copy(spec[section][kname])
|
138
|
152
|
return res
|
139
|
153
|
|
140
|
154
|
##@brief Populate the Settings instance with options values fecthed with the loader from merged specs
|
|
@@ -152,11 +166,11 @@ class Settings(object):
|
152
|
166
|
for section in loader.getsection(preffix, 'default'): #WARNING : hardcoded default section
|
153
|
167
|
specs[section] = copy.copy(specs[vsec])
|
154
|
168
|
del(specs[vsec])
|
155
|
|
- # Fetching valuds for sections
|
|
169
|
+ # Fetching values for sections
|
156
|
170
|
for section in specs:
|
157
|
171
|
for kname in specs[section]:
|
158
|
|
- validator = specs[section][kname][0]
|
159
|
|
- default = specs[section][kname][1]
|
|
172
|
+ validator = specs[section][kname][1]
|
|
173
|
+ default = specs[section][kname][0]
|
160
|
174
|
if section not in self.__confs:
|
161
|
175
|
self.__confs[section] = dict()
|
162
|
176
|
self.__confs[section][kname] = loader.getoption(section, kname, validator, default)
|
|
@@ -191,17 +205,17 @@ class Settings(object):
|
191
|
205
|
raise SettingsError("Duplicated key for '%s.%s'" % (section_name, kname))
|
192
|
206
|
cur[kname] = kval
|
193
|
207
|
|
194
|
|
- path = [ ('root', self.__confs) ]
|
195
|
|
- visited = list()
|
|
208
|
+ path = [ ('root', section_tree) ]
|
|
209
|
+ visited = set()
|
196
|
210
|
|
197
|
211
|
curname = 'root'
|
198
|
|
- nodename = 'Root'
|
199
|
|
- cur = self.__confs
|
|
212
|
+ nodename = 'Lodel2Settings'
|
|
213
|
+ cur = section_tree
|
200
|
214
|
while True:
|
201
|
|
- visited.append(cur)
|
|
215
|
+ visited.add(nodename)
|
202
|
216
|
left = [ (kname, cur[kname])
|
203
|
217
|
for kname in cur
|
204
|
|
- if cur[kname] not in visited and isinstance(cur[kname], dict)
|
|
218
|
+ if nodename+'.'+kname.title() not in visited and isinstance(cur[kname], dict)
|
205
|
219
|
]
|
206
|
220
|
if len(left) == 0:
|
207
|
221
|
name, leaf = path.pop()
|
|
@@ -213,6 +227,7 @@ class Settings(object):
|
213
|
227
|
else:
|
214
|
228
|
path[-1][1][name] = self.__tree2namedtuple(leaf,typename)
|
215
|
229
|
nodename = '.'.join(nodename.split('.')[:-1])
|
|
230
|
+ cur = path[-1][1]
|
216
|
231
|
else:
|
217
|
232
|
curname, cur = left[0]
|
218
|
233
|
path.append( (curname, cur) )
|