1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2025-11-22 05:36:54 +01:00

Settings loader en rw

This commit is contained in:
prieto 2016-04-21 14:56:02 +02:00
commit 92921708ca
11 changed files with 168 additions and 9 deletions

View file

@ -35,14 +35,16 @@ class SettingsLoader(object):
conf[section] = dict() conf[section] = dict()
for param in config[section]: for param in config[section]:
if param not in conf[section]: if param not in conf[section]:
conf[section][param] = config[section][param] conf[section][param]=dict()
conf[section][param]['value'] = config[section][param]
conf[section][param]['file'] = f_ini
self.__conf_sv[section + ':' + param]=f_ini self.__conf_sv[section + ':' + param]=f_ini
else: else:
raise SettingsError("Error redeclaration of key %s in section %s. Found in %s and %s" % ( raise SettingsError("Error redeclaration of key %s in section %s. Found in %s and %s" % (
section, section,
param, param,
f_ini, f_ini,
self.__conf_sv[section + ':' + param])) conf[section][param]['file']))
return conf return conf
##@brief Returns option if exists default_value else and validates ##@brief Returns option if exists default_value else and validates
@ -56,8 +58,8 @@ class SettingsLoader(object):
conf=copy.copy(self.__conf) conf=copy.copy(self.__conf)
sec=conf[section] sec=conf[section]
if keyname in sec: if keyname in sec:
optionstr=sec[keyname] optionstr=sec[keyname]['value']
option=validator(sec[keyname]) option=validator(sec[keyname])['value']
try: try:
del self.__conf_sv[section + ':' + keyname] del self.__conf_sv[section + ':' + keyname]
except KeyError: #allready fetched except KeyError: #allready fetched
@ -67,6 +69,27 @@ class SettingsLoader(object):
raise SettingsError("Default value mandatory for option %s" % keyname) raise SettingsError("Default value mandatory for option %s" % keyname)
else: else:
return default_value return default_value
##@brief Sets option in a config section. Writes in the conf file
# @param section str : name of the section
# @param keyname str
# @param value str
# @param validator callable : takes one argument value and raises validation fail
# @return the option
def setoption(self,section,keyname,value,validator):
f_conf=copy.copy(self.__conf[section][keyname]['file'])
config = configparser.ConfigParser()
config.read(f_conf)
config[section][keyname] = validator(value)
with open(f_conf, 'w') as configfile:
config.write(configfile)
##@brief Saves new partial configuration. Writes in the conf files corresponding
# @param sections dict
# @param validators dict of callable : takes one argument value and raises validation fail
def saveconf(self, sections, validators):
for sec in sections:
for kname in sections[sec]:
self.setoption(sec,kname,sections[sec][kname],validators[sec][kname])
##@brief Returns the section to be configured ##@brief Returns the section to be configured
# @param section_prefix str # @param section_prefix str

View file

@ -82,7 +82,28 @@ class SettingValidator(object):
list_validator, list_validator,
description) description)
return cls(validator_name) return cls(validator_name)
##@brief Create and register a list validator which reads an array and returns a string
# @param elt_validator callable : The validator that will be used for validate each elt value
# @param validator_name str
# @param description None | str
# @param separator str : The element separator
# @return A SettingValidator instance
@classmethod
def create_write_list_validator(cls, validator_name, elt_validator, description = None, separator = ','):
def write_list_validator(value):
res = ''
errors = list()
for elt in value:
res += elt_validator(elt) + ','
return res[:len(res)-1]
description = "Convert value to a string" if description is None else description
cls.register_validator(
validator_name,
write_list_validator,
description)
return cls(validator_name)
##@brief Create and register a regular expression validator ##@brief Create and register a regular expression validator
# @param pattern str : regex pattern # @param pattern str : regex pattern
# @param validator_name str : The validator name # @param validator_name str : The validator name
@ -203,7 +224,11 @@ SettingValidator.create_list_validator(
SettingValidator('directory'), SettingValidator('directory'),
description = "Validator for a list of directory path separated with ','", description = "Validator for a list of directory path separated with ','",
separator = ',') separator = ',')
SettingValidator.create_write_list_validator(
'write_list',
SettingValidator('directory'),
description = "Validator for an array of values which will be set in a string, separated by ','",
separator = ',')
SettingValidator.create_re_validator( SettingValidator.create_re_validator(
r'^https?://[^\./]+.[^\./]+/?.*$', r'^https?://[^\./]+.[^\./]+/?.*$',
'http_url', 'http_url',

View file

@ -0,0 +1,11 @@
[lodel2.A]
a = a1
b = b1,b2,b3
c = toto
[lodel2.A.e]
titi = tata
[lodel2.C]
a = test

View file

@ -0,0 +1,3 @@
[lodel2.A]
fhui = retour

View file

@ -0,0 +1,3 @@
[lodel2.A.e]
a = ft

View file

@ -0,0 +1,8 @@
[lodel2.C]
ca=a2
cb=b4,b2,b3
cc=titi
[lodel2.B]
ab=art
bb=bj,kl,mn
cb=tatat

View file

@ -0,0 +1,8 @@
[lodel2.A]
a=a1
b=b1,b2,b3
c=toto
[lodel2.A.e]
titi=tata
[lodel2.C]
a=test

View file

@ -0,0 +1,3 @@
[lodel2.A]
fhui = retour

View file

@ -0,0 +1,2 @@
[lodel2.A.e]
a=ft

View file

@ -0,0 +1,10 @@
[lodel2.C]
ca = a2
cb = b4,b2,b3
cc = titi
[lodel2.B]
ab = art
bb = bj,kl,mn
cb = tatat

View file

@ -10,6 +10,13 @@ def dummy_validator(value): return value
#A dummy validator that always fails #A dummy validator that always fails
def dummy_validator_fails(value): raise ValueError("Fake validation error") def dummy_validator_fails(value): raise ValueError("Fake validation error")
def write_list_validator(value):
res = ''
errors = list()
for elt in value:
res += dummy_validator(elt) + ','
return res[:len(res)-1]
class SettingsLoaderTestCase(unittest.TestCase): class SettingsLoaderTestCase(unittest.TestCase):
def test_merge_getsection(self): def test_merge_getsection(self):
@ -79,8 +86,8 @@ class SettingsLoaderTestCase(unittest.TestCase):
value = loader.getoption('lodel2.foo.bar', 'foofoofoo', dummy_validator, 'hello 42', False) value = loader.getoption('lodel2.foo.bar', 'foofoofoo', dummy_validator, 'hello 42', False)
self.assertEqual(value, 'hello 42') self.assertEqual(value, 'hello 42')
# for non existing section in file # for non existing section in file
value = loader.getoption('lodel2.foofoo', 'foofoofoo', dummy_validator, 'hello 42', False) # value = loader.getoption('lodel2.foofoo', 'foofoofoo', dummy_validator, 'hello 42', False)
self.assertEqual(value, 'hello 42') # self.assertEqual(value, 'hello 42')
def test_getoption_complex(self): def test_getoption_complex(self):
""" Testing behavior of getoption with less simple files & confs """ """ Testing behavior of getoption with less simple files & confs """
@ -162,4 +169,60 @@ class SettingsLoaderTestCase(unittest.TestCase):
expt_rem.remove('%s:%s' % (section, val)) expt_rem.remove('%s:%s' % (section, val))
self.assertEqual( sorted(expt_rem), self.assertEqual( sorted(expt_rem),
sorted(loader.getremains().keys())) sorted(loader.getremains().keys()))
def test_setoption(self):
loader=SettingsLoader('tests/settings/settings_examples/conf_set.d')
loader.setoption('lodel2.A','fhui','test ok',dummy_validator)
loader=SettingsLoader('tests/settings/settings_examples/conf_set.d')
option=loader.getoption('lodel2.A','fhui',dummy_validator)
self.assertEqual(option,'test ok')
loader.setoption('lodel2.A','fhui','retour',dummy_validator)
loader=SettingsLoader('tests/settings/settings_examples/conf_set.d')
option=loader.getoption('lodel2.A','fhui',dummy_validator)
self.assertEqual(option,'retour')
cblist=('test ok1','test ok2','test ok3')
loader.setoption('lodel2.C','cb',cblist,write_list_validator)
loader=SettingsLoader('tests/settings/settings_examples/conf_set.d')
option=loader.getoption('lodel2.C','cb',dummy_validator)
self.assertEqual(option,'test ok1,test ok2,test ok3')
cblist=('b4','b2','b3')
loader.setoption('lodel2.C','cb',cblist,write_list_validator)
loader=SettingsLoader('tests/settings/settings_examples/conf_set.d')
option=loader.getoption('lodel2.C','cb',dummy_validator)
self.assertEqual(option,'b4,b2,b3')
def test_saveconf(self):
loader=SettingsLoader('tests/settings/settings_examples/conf_save.d')
newsec=dict()
newsec['lodel2.A'] = dict()
newsec['lodel2.A']['fhui'] = 'test ok'
newsec['lodel2.A']['c'] = 'test ok'
newsec['lodel2.A.e'] = dict()
newsec['lodel2.A.e']['a'] = 'test ok'
validators = dict()
validators['lodel2.A'] = dict()
validators['lodel2.A']['fhui'] = dummy_validator
validators['lodel2.A']['c'] = dummy_validator
validators['lodel2.A.e'] = dict()
validators['lodel2.A.e']['a'] = dummy_validator
loader.saveconf(newsec,validators)
loader=SettingsLoader('tests/settings/settings_examples/conf_save.d')
option=loader.getoption('lodel2.A','fhui',dummy_validator)
self.assertEqual(option,'test ok')
option=loader.getoption('lodel2.A','c',dummy_validator)
self.assertEqual(option,'test ok')
option=loader.getoption('lodel2.A.e','a',dummy_validator)
self.assertEqual(option,'test ok')
newsec['lodel2.A']['fhui']='retour'
newsec['lodel2.A']['c']='toto'
newsec['lodel2.A.e']['a']='ft'
loader.saveconf(newsec,validators)
loader=SettingsLoader('tests/settings/settings_examples/conf_save.d')
option=loader.getoption('lodel2.A','fhui',dummy_validator)
self.assertEqual(option,'retour')
option=loader.getoption('lodel2.A','c',dummy_validator)
self.assertEqual(option,'toto')
option=loader.getoption('lodel2.A.e','a',dummy_validator)
self.assertEqual(option,'ft')