todict: better support for callback

This commit is contained in:
Emmanuel Garette 2019-05-09 20:32:43 +02:00
parent 5ea35bf84e
commit 552cd3740d
6 changed files with 97 additions and 98 deletions

View file

@ -14,7 +14,7 @@
"model": {},
"form": {
"options.integer": {
"allowedpattern": "[0-9]",
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [

View file

@ -18,7 +18,7 @@
},
"form": {
"options.integer": {
"allowedpattern": "[0-9]",
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [

View file

@ -21,7 +21,7 @@
"form": {
"options.integer": {
"clearable": true,
"allowedpattern": "[0-9]",
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [

View file

@ -21,7 +21,7 @@
"form": {
"options.integer": {
"clearable": true,
"allowedpattern": "[0-9]",
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [

View file

@ -271,6 +271,7 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
if isinstance(option, RegexpOption):
return option._regexp.pattern
if type == 'integer':
# FIXME negative too!
return r'^[0-9]+$'
if type == 'domainname':
return option.impl_get_extra('_domain_re').pattern
@ -384,11 +385,11 @@ class TiramisuOptionProperty(CommonTiramisuOption):
"""Remove new property for an option"""
option = self._option_bag.option
props = self._settings.getproperties(self._option_bag,
apply_requires=False)
apply_requires=False)
self._settings.setproperties(self._option_bag.path,
props - {prop},
self._option_bag,
self._option_bag.config_bag.context)
props - {prop},
self._option_bag,
self._option_bag.config_bag.context)
def reset(self):
"""Reset all personalised properties"""

View file

@ -46,68 +46,54 @@ class Callbacks(object):
def add(self,
path,
childapi,
options,
schema,
force_store_value):
self.callbacks.append((path, childapi, options, schema, force_store_value))
if self.remotable == 'all' or childapi.option.isoptiondescription():
return
callback, callback_params = childapi.option.callbacks()
if callback is None: # FIXME ? and force_store_value and self.clearable != 'all':
return
self.callbacks.append((callback, callback_params, path, childapi, schema, force_store_value))
def manage_callbacks(self,
path,
childapi,
options,
callback,
callback_params,
form,
schema):
if callback_params is not None:
remote = True
for callback_param in callback_params.args:
if isinstance(callback_param, ParamContext):
raise ValueError(_('context is not supported from now for {}').format(path))
if isinstance(callback_param, ParamOption):
if callback.__name__ == 'tiramisu_copy':
if self.clearable == 'minimum':
form.setdefault(path, {})['clearable'] = True
if form.get(path, {}).get('remote') is not True and form[options[callback_param.option]].get('remote', False) is not True:
form.setdefault(options[callback_param.option], {})
form[options[callback_param.option]].setdefault('copy', []).append(path)
remote = False
elif options.get(callback_param.option) is not None:
#form.setdefault(options[callback_param.option], {})
form.setdefault(path, {})
form[path]['remote'] = True
#break
if remote:
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
form.setdefault(path, {})['remote'] = True
else:
if 'expire' not in childapi.property.get() and childapi.owner.isdefault():
schema[path]['value'] = childapi.value.get()
if self.clearable == 'minimum':
form.setdefault(path, {})['clearable'] = True
else:
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
# FIXME is not default, show calculate
form.setdefault(path, {})['remote'] = True
def process_properties(self, form):
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
has_option = False
if callback_params is not None:
for callback_param in callback_params.args:
if isinstance(callback_param, ParamContext):
raise ValueError(_('context is not supported from now for {}').format(path))
if isinstance(callback_param, ParamOption):
has_option = True
if callback.__name__ != 'tiramisu_copy' or 'expire' in childapi.option.properties():
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
form[callback_param.option.impl_getpath()]['remote'] = True
remote = True
if not has_option and form.get(path, {}).get('remote') == False:
if 'expire' in childapi.option.properties():
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
form.setdefault(path, {})['remote'] = True
elif childapi.owner.isdefault():
# get calculated value and set clearable
schema[path]['value'] = childapi.value.get()
if self.clearable == 'minimum':
form.setdefault(path, {})['clearable'] = True
def manage_callbacks(self, form):
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
if callback_params is not None:
for callback_param in callback_params.args:
if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy':
opt_path = callback_param.option.impl_getpath()
if form.get(opt_path, {}).get('remote') is not True:
form.setdefault(opt_path, {})
form[opt_path].setdefault('copy', []).append(path)
def process(self,
form):
for path, childapi, options, schema, force_store_value in self.callbacks:
if not childapi.option.isoptiondescription():
callback, callback_params = childapi.option.callbacks()
if callback is not None:
if force_store_value and self.clearable != 'all':
return
self.manage_callbacks(path,
childapi,
options,
callback,
callback_params,
form,
schema)
self.process_properties(form)
self.manage_callbacks(form)
class Consistencies(object):
@ -158,7 +144,6 @@ class Requires(object):
self.remotable = tiramisu_web.remotable
def manage_requires(self,
require_obj,
childapi,
path,
form,
@ -170,58 +155,63 @@ class Requires(object):
transitive, same_action, operator = require
if transitive is False:
# transitive to "False" not supported yet for a requirement
if require_obj.remotable == 'none':
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(path, {'key': path})['remote'] = True
return
if same_action is False:
# same_action to "False" not supported yet for a requirement
if require_obj.remotable == 'none':
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(path, {'key': path})['remote'] = True
return
if operator == 'and':
# operator "and" not supported yet for a requirement
if require_obj.remotable == 'none':
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(path, {'key': path})['remote'] = True
return
for option, expected in options:
option_path = require_obj.options.get(option)
option_path = self.options.get(option)
if option_path is not None and action in action_hide:
if current_action is None:
current_action = action
elif current_action != action:
if require_obj.remotable == 'none':
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(option_path, {'key': option_path})['remote'] = True
if inverse:
act = 'show'
inv_act = 'hide'
else:
act = 'hide'
inv_act = 'show'
for exp in expected:
if inverse:
act = 'show'
inv_act = 'hide'
else:
act = 'hide'
inv_act = 'show'
require_obj.requires.setdefault(path,
{'expected': {}}
)['expected'].setdefault(exp,
{}).setdefault(act,
[]).append(option_path)
if isinstance(option, ChoiceOption):
for value in require_obj.config.unrestraint.option(option_path).value.list():
if value not in expected:
require_obj.requires.setdefault(path,
{'expected': {}}
)['expected'].setdefault(value,
{}).setdefault(inv_act,
[]).append(option_path)
require_obj.requires[path].setdefault('default', {}).setdefault(inv_act, []).append(option_path)
self.requires.setdefault(path,
{'expected': {}}
)['expected'].setdefault(exp,
{}).setdefault(act,
[]).append(option_path)
if isinstance(option, ChoiceOption):
choice_obj = self.config.unrestraint.option(option_path)
values = self.tiramisu_web.get_enum(choice_obj,
choice_obj.option.ismulti(),
option_path,
choice_obj.option.properties())
for value in values:
if value not in expected:
self.requires.setdefault(path,
{'expected': {}}
)['expected'].setdefault(value,
{}).setdefault(inv_act,
[]).append(option_path)
self.requires[path].setdefault('default', {}).setdefault(inv_act, []).append(option_path)
else:
if require_obj.remotable == 'none':
if self.remotable == 'none':
raise ValueError('require set for {} but remotable est "none"'
''.format(path))
form.setdefault(option_path, {'key': option_path})['remote'] = True
@ -234,8 +224,7 @@ class Requires(object):
self.options[child] = path
current_action = None
self.manage_requires(self,
childapi,
self.manage_requires(childapi,
path,
form,
ACTION_HIDE,
@ -384,7 +373,6 @@ class TiramisuDict:
childapi)
self.callbacks.add(path,
childapi,
self.requires.options,
schema,
'force_store_value' in props_no_requires)
childapi_option = childapi.option
@ -503,12 +491,22 @@ class TiramisuDict:
schema[path]['autoFreeze'] = True
if web_type == 'choice':
schema[path]['enum'] = childapi.value.list()
empty_is_required = not childapi.option.isfollower() and is_multi
if (empty_is_required and not 'empty' in props_no_requires) or \
(not empty_is_required and not 'mandatory' in props_no_requires):
schema[path]['enum'] = [''] + list(schema[path]['enum'])
schema[path]['enum'] = self.get_enum(childapi,
is_multi,
path,
props_no_requires)
def get_enum(self,
childapi,
is_multi,
path,
props_no_requires):
values = childapi.value.list()
empty_is_required = not childapi.option.isfollower() and is_multi
if '' not in values and ((empty_is_required and not 'empty' in props_no_requires) or \
(not empty_is_required and not 'mandatory' in props_no_requires)):
values = [''] + list(values)
return values
def gen_form(self,
form,