improvement
This commit is contained in:
parent
3446a38287
commit
e1f62e8044
|
@ -0,0 +1,4 @@
|
||||||
|
from .api import Config
|
||||||
|
|
||||||
|
__all__ = ('Config',)
|
||||||
|
|
|
@ -3,12 +3,16 @@ import warnings
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
from .tiramisu_json import TiramisuJson, _
|
|
||||||
from tiramisu.error import APIError, ValueWarning, ValueOptionError, ValueErrorWarning, PropertiesOptionError
|
from tiramisu.error import APIError, ValueWarning, ValueOptionError, ValueErrorWarning, PropertiesOptionError
|
||||||
from tiramisu.setting import undefined
|
from tiramisu.setting import undefined
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
def _(val):
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
class Option:
|
class Option:
|
||||||
|
# fake Option (IntOption, StrOption, ...)
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name,
|
name,
|
||||||
path):
|
path):
|
||||||
|
@ -26,11 +30,14 @@ class Option:
|
||||||
|
|
||||||
|
|
||||||
class TiramisuOptionOption:
|
class TiramisuOptionOption:
|
||||||
|
# config.option(path).option
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
path: str,
|
path: str,
|
||||||
schema: Dict) -> None:
|
schema: Dict,
|
||||||
|
model: Dict) -> None:
|
||||||
self._path = path
|
self._path = path
|
||||||
self.schema = schema
|
self.schema = schema
|
||||||
|
self.model = model
|
||||||
|
|
||||||
def doc(self):
|
def doc(self):
|
||||||
return self.schema['title']
|
return self.schema['title']
|
||||||
|
@ -38,6 +45,9 @@ class TiramisuOptionOption:
|
||||||
def path(self):
|
def path(self):
|
||||||
return self._path
|
return self._path
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return self._path.rsplit('.', 1)[-1]
|
||||||
|
|
||||||
def isoptiondescription(self):
|
def isoptiondescription(self):
|
||||||
return self.schema['type'] in ['object', 'array']
|
return self.schema['type'] in ['object', 'array']
|
||||||
|
|
||||||
|
@ -69,14 +79,29 @@ class TiramisuOptionOption:
|
||||||
return types[self.schema['type']]
|
return types[self.schema['type']]
|
||||||
raise Exception('unsupported type {}'.format(self.schema['type']))
|
raise Exception('unsupported type {}'.format(self.schema['type']))
|
||||||
|
|
||||||
|
def properties(self) -> List[str]:
|
||||||
|
props = []
|
||||||
|
model = self.model[self._path]
|
||||||
|
if model.get('required'):
|
||||||
|
#FIXME 'empty', 'needs_len'
|
||||||
|
props.append('mandatory')
|
||||||
|
if model.get('readOnly'):
|
||||||
|
props.append('frozen')
|
||||||
|
if model.get('hidden'):
|
||||||
|
props.append('hidden')
|
||||||
|
return props
|
||||||
|
|
||||||
|
def requires(self) -> None:
|
||||||
|
# FIXME
|
||||||
|
return None
|
||||||
|
|
||||||
class TiramisuOptionProperty:
|
class TiramisuOptionProperty:
|
||||||
|
# config.option(path).property
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
model: Dict) -> None:
|
model: Dict) -> None:
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
||||||
def get(self):
|
def get(self, only_raises=False):
|
||||||
properties = self.model.get('properties', [])[:]
|
|
||||||
# FIXME if slave:
|
# FIXME if slave:
|
||||||
#if not isslave and childapi.option.ismulti():
|
#if not isslave and childapi.option.ismulti():
|
||||||
# if 'empty' in props:
|
# if 'empty' in props:
|
||||||
|
@ -85,33 +110,54 @@ class TiramisuOptionProperty:
|
||||||
# if 'mandatory' in props:
|
# if 'mandatory' in props:
|
||||||
# obj['needs_len'] = True
|
# obj['needs_len'] = True
|
||||||
# props.remove('mandatory')
|
# props.remove('mandatory')
|
||||||
if self.model.get('required', False):
|
if not only_raises:
|
||||||
properties.append('mandatory')
|
properties = self.model.get('properties', [])[:]
|
||||||
if self.model.get('readOnly', False):
|
if self.model.get('required', False):
|
||||||
properties.append('frozen')
|
properties.append('mandatory')
|
||||||
|
if self.model.get('readOnly', False):
|
||||||
|
properties.append('frozen')
|
||||||
|
else:
|
||||||
|
properties = []
|
||||||
if self.model.get('hidden', False):
|
if self.model.get('hidden', False):
|
||||||
properties.append('hidden')
|
properties.append('hidden')
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
|
|
||||||
class TiramisuOptionValue:
|
class _Value:
|
||||||
def __init__(self,
|
def _dict_walk(self,
|
||||||
config: 'Config',
|
ret: Dict,
|
||||||
schema: Dict,
|
schema: Dict,
|
||||||
model: List[Dict],
|
root: str,
|
||||||
form: List[Dict],
|
fullpath: bool,
|
||||||
temp: List[Dict],
|
withwarning: bool):
|
||||||
path: str,
|
for key, option in schema['properties'].items():
|
||||||
index: int) -> None:
|
hidden = self.temp.get(key, {}).get('hidden', None)
|
||||||
self.config = config
|
model_hidden = not self.model.get(key, {}).get('hidden', False) and \
|
||||||
self.schema = schema
|
self.model.get(key, {}).get('display', True)
|
||||||
self.model = model
|
if hidden is False or (hidden is None and model_hidden):
|
||||||
self.form = form
|
if option['type'] == 'object':
|
||||||
self.temp = temp
|
self._dict_walk(ret,
|
||||||
self.path = path
|
option,
|
||||||
self.index = index
|
root,
|
||||||
|
fullpath,
|
||||||
|
withwarning)
|
||||||
|
else:
|
||||||
|
value = self._get_value(key, schema)
|
||||||
|
self._display_warnings(key, value, option['type'], option['name'], withwarning)
|
||||||
|
ret[key] = value
|
||||||
|
|
||||||
def _display_warnings(self, path, value, type, name):
|
def dict(self,
|
||||||
|
fullpath: bool=False,
|
||||||
|
withwarning: bool=False):
|
||||||
|
ret = {}
|
||||||
|
self._dict_walk(ret,
|
||||||
|
self.schema,
|
||||||
|
self.path,
|
||||||
|
fullpath,
|
||||||
|
withwarning)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def _display_warnings(self, path, value, type, name, withwarning=True):
|
||||||
if self.model.get(path, {}).get('error'):
|
if self.model.get(path, {}).get('error'):
|
||||||
for err in self.model.get(path, {}).get('error'):
|
for err in self.model.get(path, {}).get('error'):
|
||||||
warnings.warn_explicit(ValueOptionError(value,
|
warnings.warn_explicit(ValueOptionError(value,
|
||||||
|
@ -121,28 +167,13 @@ class TiramisuOptionValue:
|
||||||
ValueErrorWarning,
|
ValueErrorWarning,
|
||||||
self.__class__.__name__, 0)
|
self.__class__.__name__, 0)
|
||||||
|
|
||||||
if self.model.get(path, {}).get('warnings'):
|
if withwarning and self.model.get(path, {}).get('warnings'):
|
||||||
for warn in self.model.get(path, {}).get('warnings'):
|
for warn in self.model.get(path, {}).get('warnings'):
|
||||||
warnings.warn_explicit(ValueWarning('{0}'.format(warn),
|
warnings.warn_explicit(ValueWarning('{0}'.format(warn),
|
||||||
Option(name, path)),
|
Option(name, path)),
|
||||||
ValueWarning,
|
ValueWarning,
|
||||||
self.__class__.__name__, 0)
|
self.__class__.__name__, 0)
|
||||||
|
|
||||||
def _dict_walk(self,
|
|
||||||
ret: Dict,
|
|
||||||
schema: Dict):
|
|
||||||
for key, option in schema['properties'].items():
|
|
||||||
hidden = self.temp.get(self.path, {}).get('hidden', None)
|
|
||||||
if hidden is False or (hidden is None and \
|
|
||||||
not self.model.get(self.path, {}).get('hidden', False) and \
|
|
||||||
self.model.get(self.path, {}).get('display', True)):
|
|
||||||
if option['type'] == 'object':
|
|
||||||
self._dict_walk(ret, option)
|
|
||||||
else:
|
|
||||||
value = self._get_value(key, schema)
|
|
||||||
self._display_warnings(key, value, option['type'], option['name'])
|
|
||||||
ret[key] = value
|
|
||||||
|
|
||||||
def _get_value(self,
|
def _get_value(self,
|
||||||
path: str,
|
path: str,
|
||||||
schema: Dict) -> Any:
|
schema: Dict) -> Any:
|
||||||
|
@ -154,14 +185,26 @@ class TiramisuOptionValue:
|
||||||
value = []
|
value = []
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def dict(self,
|
|
||||||
fullpath: bool=False,
|
class TiramisuOptionValue(_Value):
|
||||||
withwarning: bool=False):
|
# config.option(path).value
|
||||||
if not fullpath or not withwarning:
|
def __init__(self,
|
||||||
raise NotImplementedError()
|
config: 'Config',
|
||||||
ret = {}
|
schema: Dict,
|
||||||
self._dict_walk(ret, self.schema)
|
model: List[Dict],
|
||||||
return ret
|
form: List[Dict],
|
||||||
|
temp: List[Dict],
|
||||||
|
path: str,
|
||||||
|
index: int) -> None:
|
||||||
|
self.config = config
|
||||||
|
self.schema = schema
|
||||||
|
if schema.get('properties') != None:
|
||||||
|
raise Exception('pouet')
|
||||||
|
self.model = model
|
||||||
|
self.form = form
|
||||||
|
self.temp = temp
|
||||||
|
self.path = path
|
||||||
|
self.index = index
|
||||||
|
|
||||||
def get(self) -> Any:
|
def get(self) -> Any:
|
||||||
value = self._get_value(self.path, self.schema)
|
value = self._get_value(self.path, self.schema)
|
||||||
|
@ -184,7 +227,75 @@ class TiramisuOptionValue:
|
||||||
self.form.get(self.path, {}).get('remote', False))
|
self.form.get(self.path, {}).get('remote', False))
|
||||||
|
|
||||||
|
|
||||||
|
class _Option:
|
||||||
|
def list(self,
|
||||||
|
type='option'):
|
||||||
|
if type not in ['all', 'option']:
|
||||||
|
raise NotImplementedError()
|
||||||
|
if self.schema.get('properties') is None:
|
||||||
|
raise Exception(list(self.schema.keys()))
|
||||||
|
for path, schema in self.schema['properties'].items():
|
||||||
|
if type == 'all' or schema['type'] not in ['object', 'array']:
|
||||||
|
hidden = self.temp.get(path, {}).get('hidden', None)
|
||||||
|
if self.temp.get(path, {}).get('hidden', False) is not True and \
|
||||||
|
not self.model.get(path, {}).get('hidden', False) and \
|
||||||
|
self.model.get(path, {}).get('display', True):
|
||||||
|
if schema['type'] in ['object', 'array']:
|
||||||
|
yield TiramisuOptionDescription(self.config,
|
||||||
|
schema,
|
||||||
|
self.model,
|
||||||
|
self.form,
|
||||||
|
self.temp,
|
||||||
|
path)
|
||||||
|
else:
|
||||||
|
yield TiramisuOption(self.config,
|
||||||
|
schema,
|
||||||
|
self.model,
|
||||||
|
self.form,
|
||||||
|
self.temp,
|
||||||
|
path,
|
||||||
|
self.index)
|
||||||
|
|
||||||
|
|
||||||
|
class TiramisuOptionDescription(_Option):
|
||||||
|
# config.option(path) (with path == OptionDescription)
|
||||||
|
def __init__(self,
|
||||||
|
config: 'Config',
|
||||||
|
schema: Dict,
|
||||||
|
model: List[Dict],
|
||||||
|
form: List[Dict],
|
||||||
|
temp: List[Dict],
|
||||||
|
path: str) -> None:
|
||||||
|
self.config = config
|
||||||
|
self.schema = schema
|
||||||
|
self.model = model
|
||||||
|
self.form = form
|
||||||
|
self.temp = temp
|
||||||
|
self.path = path
|
||||||
|
self.index = None
|
||||||
|
|
||||||
|
def __getattr__(self,
|
||||||
|
subfunc: str) -> Any:
|
||||||
|
if subfunc == 'option':
|
||||||
|
return TiramisuOptionOption(self.path,
|
||||||
|
self.schema,
|
||||||
|
self.model)
|
||||||
|
if subfunc == 'property':
|
||||||
|
return TiramisuOptionProperty(self.model.get(self.path, {}))
|
||||||
|
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||||
|
|
||||||
|
def group_type(self):
|
||||||
|
hidden = self.temp.get(self.path, {}).get('hidden', None)
|
||||||
|
if hidden is False or (hidden is None and \
|
||||||
|
not self.model.get(self.path, {}).get('hidden', False) and \
|
||||||
|
self.model.get(self.path, {}).get('display', True)):
|
||||||
|
# FIXME
|
||||||
|
return 'default'
|
||||||
|
raise PropertiesOptionError(None, None, None, opt_type='optiondescription')
|
||||||
|
|
||||||
|
|
||||||
class TiramisuOption:
|
class TiramisuOption:
|
||||||
|
# config.option(path) (with path == Option)
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
config: 'Config',
|
config: 'Config',
|
||||||
schema: Dict,
|
schema: Dict,
|
||||||
|
@ -207,7 +318,8 @@ class TiramisuOption:
|
||||||
if self.index != None:
|
if self.index != None:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
return TiramisuOptionOption(self.path,
|
return TiramisuOptionOption(self.path,
|
||||||
self.schema)
|
self.schema,
|
||||||
|
self.model)
|
||||||
if subfunc == 'value':
|
if subfunc == 'value':
|
||||||
return TiramisuOptionValue(self.config,
|
return TiramisuOptionValue(self.config,
|
||||||
self.schema,
|
self.schema,
|
||||||
|
@ -222,34 +334,9 @@ class TiramisuOption:
|
||||||
return TiramisuOptionProperty(self.model.get(self.path, {}))
|
return TiramisuOptionProperty(self.model.get(self.path, {}))
|
||||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||||
|
|
||||||
def group_type(self):
|
|
||||||
hidden = self.temp.get(self.path, {}).get('hidden', None)
|
|
||||||
if hidden is False or (hidden is None and \
|
|
||||||
not self.model.get(self.path, {}).get('hidden', False) and \
|
|
||||||
self.model.get(self.path, {}).get('display', True)):
|
|
||||||
# FIXME
|
|
||||||
return 'default'
|
|
||||||
raise PropertiesOptionError(None, None, None, opt_type='optiondescription')
|
|
||||||
|
|
||||||
def list(self,
|
|
||||||
type='option'):
|
|
||||||
if type != 'all':
|
|
||||||
raise NotImplementedError()
|
|
||||||
for path, schema in self.schema['properties'].items():
|
|
||||||
hidden = self.temp.get(path, {}).get('hidden', None)
|
|
||||||
if self.temp.get(path, {}).get('hidden', False) is not True and \
|
|
||||||
not self.model.get(path, {}).get('hidden', False) and \
|
|
||||||
self.model.get(path, {}).get('display', True):
|
|
||||||
yield TiramisuOption(self.config,
|
|
||||||
schema,
|
|
||||||
self.model,
|
|
||||||
self.form,
|
|
||||||
self.temp,
|
|
||||||
path,
|
|
||||||
self.index)
|
|
||||||
|
|
||||||
|
|
||||||
class TiramisuContextProperty:
|
class TiramisuContextProperty:
|
||||||
|
# config.property
|
||||||
# def __init__(self,
|
# def __init__(self,
|
||||||
# json):
|
# json):
|
||||||
# self.json = json
|
# self.json = json
|
||||||
|
@ -259,7 +346,63 @@ class TiramisuContextProperty:
|
||||||
return ['demoting_error_warning']
|
return ['demoting_error_warning']
|
||||||
|
|
||||||
|
|
||||||
|
class ContextOption(_Option):
|
||||||
|
# config.option
|
||||||
|
def __init__(self,
|
||||||
|
config: 'Config',
|
||||||
|
model: Dict,
|
||||||
|
form: Dict,
|
||||||
|
schema: Dict,
|
||||||
|
temp: Dict) -> None:
|
||||||
|
self.config = config
|
||||||
|
self.model = model
|
||||||
|
self.form = form
|
||||||
|
schema = {'properties': schema}
|
||||||
|
self.schema = schema
|
||||||
|
self.temp = temp
|
||||||
|
self.index = None
|
||||||
|
|
||||||
|
def __call__(self,
|
||||||
|
path: str,
|
||||||
|
index: Optional[int]=None) -> TiramisuOption:
|
||||||
|
return TiramisuOption(self.config,
|
||||||
|
self.config.get_schema(path),
|
||||||
|
self.model,
|
||||||
|
self.form,
|
||||||
|
self.temp,
|
||||||
|
path,
|
||||||
|
index)
|
||||||
|
|
||||||
|
|
||||||
|
class ContextValue(_Value):
|
||||||
|
# config.value
|
||||||
|
def __init__(self,
|
||||||
|
config: 'Config',
|
||||||
|
model: Dict,
|
||||||
|
form: Dict,
|
||||||
|
schema: Dict,
|
||||||
|
temp: Dict) -> None:
|
||||||
|
self.config = config
|
||||||
|
self.model = model
|
||||||
|
self.form = form
|
||||||
|
first = next(iter(schema.keys()))
|
||||||
|
self.path = first.rsplit('.', 1)[0]
|
||||||
|
schema = {'properties': schema}
|
||||||
|
self.schema = schema
|
||||||
|
self.temp = temp
|
||||||
|
|
||||||
|
def __call__(self) -> TiramisuOptionValue:
|
||||||
|
return TiramisuOptionValue(self.config,
|
||||||
|
self.schema,
|
||||||
|
self.model,
|
||||||
|
self.form,
|
||||||
|
self.temp,
|
||||||
|
path,
|
||||||
|
index)
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
# config
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
json):
|
json):
|
||||||
self.model_ori = json['model']
|
self.model_ori = json['model']
|
||||||
|
@ -273,43 +416,31 @@ class Config:
|
||||||
self.temp = {}
|
self.temp = {}
|
||||||
self.schema = json['schema']
|
self.schema = json['schema']
|
||||||
self.updates = []
|
self.updates = []
|
||||||
|
first_path = next(iter(self.schema.keys()))
|
||||||
|
if '.' in first_path:
|
||||||
|
self.root = first_path.rsplit('.', 1)[0]
|
||||||
|
else:
|
||||||
|
self.root = ''
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(self,
|
def __getattr__(self,
|
||||||
subfunc: str) -> Any:
|
subfunc: str) -> Any:
|
||||||
if subfunc == 'property':
|
if subfunc == 'property':
|
||||||
return TiramisuContextProperty()
|
return TiramisuContextProperty()
|
||||||
|
if subfunc == 'option':
|
||||||
|
return ContextOption(self,
|
||||||
|
self.model,
|
||||||
|
self.form,
|
||||||
|
self.schema,
|
||||||
|
self.temp)
|
||||||
|
if subfunc == 'value':
|
||||||
|
return ContextValue(self,
|
||||||
|
self.model,
|
||||||
|
self.form,
|
||||||
|
self.schema,
|
||||||
|
self.temp)
|
||||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||||
|
|
||||||
def option(self,
|
|
||||||
path: str,
|
|
||||||
index: Optional[int]=None) -> TiramisuOption:
|
|
||||||
|
|
||||||
first = next(iter(self.schema.keys()))
|
|
||||||
if '.' in first:
|
|
||||||
root_path = first.rsplit('.', 1)[0]
|
|
||||||
len_root_path = len(root_path)
|
|
||||||
len_path = len(path)
|
|
||||||
if len_root_path >= len_path:
|
|
||||||
spath = []
|
|
||||||
else:
|
|
||||||
spath = path[len_root_path + 1:].split('.')
|
|
||||||
schema = {'properties': self.schema}
|
|
||||||
else:
|
|
||||||
root_path, *spath = path.split('.')
|
|
||||||
schema = self.schema[root_path]['properties']
|
|
||||||
fullsubpath = [root_path]
|
|
||||||
for subpath in spath:
|
|
||||||
fullsubpath.append(subpath)
|
|
||||||
schema = schema['properties']['.'.join(fullsubpath)]
|
|
||||||
|
|
||||||
return TiramisuOption(self,
|
|
||||||
schema,
|
|
||||||
self.model,
|
|
||||||
self.form,
|
|
||||||
self.temp,
|
|
||||||
path,
|
|
||||||
index)
|
|
||||||
|
|
||||||
def add_value(self,
|
def add_value(self,
|
||||||
path: str,
|
path: str,
|
||||||
index: Optional[int],
|
index: Optional[int],
|
||||||
|
@ -360,21 +491,20 @@ class Config:
|
||||||
|
|
||||||
def get_schema(self,
|
def get_schema(self,
|
||||||
path):
|
path):
|
||||||
first_path = next(iter(self.schema.keys()))
|
root_path = self.root
|
||||||
if '.' in first_path:
|
if root_path:
|
||||||
root = first_path.rsplit('.', 1)[0].split('.')
|
schema = {'properties': self.schema}
|
||||||
|
root = self.root.split('.')
|
||||||
|
subpaths = path.split('.')[len(root):]
|
||||||
|
for subpath in subpaths:
|
||||||
|
if root_path:
|
||||||
|
root_path += '.' + subpath
|
||||||
|
else:
|
||||||
|
root_path = subpath
|
||||||
|
schema = schema['properties'][root_path]
|
||||||
|
print(path, schema)
|
||||||
else:
|
else:
|
||||||
root = []
|
schema = self.schema[path]
|
||||||
|
|
||||||
s_path = path.split('.')
|
|
||||||
schema = {'properties': self.schema}
|
|
||||||
root_path = '.'.join(root)
|
|
||||||
for subpath in path.split('.')[len(root):]:
|
|
||||||
if root_path:
|
|
||||||
root_path += '.' + subpath
|
|
||||||
else:
|
|
||||||
root_path = subpath
|
|
||||||
schema = schema['properties'][root_path]
|
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
|
||||||
|
@ -411,7 +541,7 @@ class Config:
|
||||||
last_body['action'] == 'modify' and action == 'delete':
|
last_body['action'] == 'modify' and action == 'delete':
|
||||||
update_last_action = True
|
update_last_action = True
|
||||||
elif last_body['action'] == 'add' and action == 'delete':
|
elif last_body['action'] == 'add' and action == 'delete':
|
||||||
del this.updates[-1]
|
del self.updates[-1]
|
||||||
|
|
||||||
if update_last_action:
|
if update_last_action:
|
||||||
if value is None:
|
if value is None:
|
||||||
|
|
Loading…
Reference in New Issue