mirror of
https://github.com/yweber/lodel2.git
synced 2026-03-15 15:52:02 +01:00
Implement the BackendJson save method
This commit is contained in:
parent
d199d571bd
commit
18695e3a72
4 changed files with 59 additions and 22 deletions
|
|
@ -9,17 +9,23 @@
|
|||
import json
|
||||
import datetime
|
||||
from Lodel.utils.mlstring import MlString
|
||||
import EditorialModel
|
||||
|
||||
|
||||
def date_cast(date):
|
||||
if len(date):
|
||||
return datetime.datetime(date)
|
||||
return datetime.datetime.strptime(date, '%c')
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
## @brief dirty obsolote cast function
|
||||
def int_or_none(i):
|
||||
if len(i):
|
||||
if isinstance(i, int):
|
||||
return i
|
||||
elif i is None:
|
||||
return None
|
||||
elif len(i):
|
||||
return int(i)
|
||||
else:
|
||||
return None
|
||||
|
|
@ -47,27 +53,35 @@ class EmBackendJson(object):
|
|||
#
|
||||
# @param json_file str: path to the json_file used as data source
|
||||
def __init__(self, json_file):
|
||||
with open(json_file) as json_data:
|
||||
self.data = json.loads(json_data.read())
|
||||
self.json_file = json_file
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
## @brief Used by json.dumps to serialize date and datetime
|
||||
def date_handler(obj):
|
||||
return obj.strftime('%c') if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) else None
|
||||
|
||||
|
||||
## Loads the data in the data source json file
|
||||
#
|
||||
# @return list
|
||||
def load(self):
|
||||
data = {}
|
||||
for index, component in self.data.items():
|
||||
attributes = {}
|
||||
for attr_name, attr_value in component.items():
|
||||
if attr_name in EmBackendJson.cast_methods:
|
||||
attributes[attr_name] = EmBackendJson.cast_methods[attr_name](attr_value)
|
||||
else:
|
||||
attributes[attr_name] = attr_value
|
||||
data[int(index)] = attributes
|
||||
with open(self.json_file) as json_data:
|
||||
rdata = json.loads(json_data.read())
|
||||
for index, component in rdata.items():
|
||||
attributes = {}
|
||||
for attr_name, attr_value in component.items():
|
||||
if attr_name in EmBackendJson.cast_methods:
|
||||
attributes[attr_name] = EmBackendJson.cast_methods[attr_name](attr_value)
|
||||
else:
|
||||
attributes[attr_name] = attr_value
|
||||
data[int(index)] = attributes
|
||||
return data
|
||||
|
||||
## Saves the data in the data source json file
|
||||
#
|
||||
# @return bool
|
||||
# @todo à implémenter
|
||||
def save(self, em):
|
||||
return True
|
||||
# @param filename str : The filename to save the EM in (if None use self.json_file provided at init )
|
||||
def save(self, em, filename = None):
|
||||
with open(self.json_file if filename is None else filename, 'w') as fp:
|
||||
fp.write(json.dumps({ component.uid : component.dumps() for component in em.components() }, default=self.date_handler))
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class EmComponent(object):
|
|||
## @brief Return a dict with attributes name as key and attributes value as value
|
||||
# @note Used at creation and deletion to call the migration handler
|
||||
def attr_dump(self):
|
||||
return {fname: fval for fname, fval in self.__dict__.items() if not (fname.startswith('__') or (fname == 'uid'))}
|
||||
return {fname: fval for fname, fval in self.__dict__.items() if not (fname.startswith('_') or (fname == 'uid'))}
|
||||
|
||||
@property
|
||||
## @brief Provide a uniq name
|
||||
|
|
@ -71,6 +71,23 @@ class EmComponent(object):
|
|||
uname += '_'+self.name
|
||||
return uname
|
||||
|
||||
## @brief dumps attr for serialization
|
||||
def dumps(self):
|
||||
#attr = {fname: fval for fname, fval in self.__dict__.items() if not (fname.startswith('_'))}
|
||||
attr = self.attr_dump
|
||||
del(attr['model'])
|
||||
for attr_f in attr:
|
||||
if isinstance(attr[attr_f], EmComponent):
|
||||
attr[attr_f] = attr[attr_f].uid
|
||||
elif isinstance(attr[attr_f], MlString):
|
||||
attr[attr_f] = attr[attr_f].__str__()
|
||||
if isinstance(self, EditorialModel.fields.EmField):
|
||||
attr['component'] = 'EmField'
|
||||
attr['type'] = self.fieldtype
|
||||
else:
|
||||
attr['component'] = self.__class__.__name__
|
||||
return attr
|
||||
|
||||
## @brief This function has to be called after the instanciation, checks, and init manipulations are done
|
||||
# @note Create a new attribute _inited that allow __setattr__ to know if it has or not to call the migration handler
|
||||
def init_ended(self):
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class EmField(EmComponent):
|
|||
## Instanciate a new EmField
|
||||
# @todo define and test type for icon and fieldtype
|
||||
# @warning nullable == True by default
|
||||
def __init__(self, model, uid, name, fieldgroup_id, optional=False, internal=False, rel_field_id=None, icon='0', string=None, help_text=None, date_update=None, date_create=None, rank=None, nullable = True, default = None, uniq = False, **kwargs):
|
||||
def __init__(self, model, uid, name, fieldgroup_id, fieldtype, optional=False, internal=False, rel_field_id=None, icon='0', string=None, help_text=None, date_update=None, date_create=None, rank=None, nullable = True, default = None, uniq = False, **kwargs):
|
||||
|
||||
if self.ftype == None:
|
||||
raise NotImplementedError("Trying to instanciate an EmField and not one of the fieldtypes child classes")
|
||||
|
|
@ -37,7 +37,9 @@ class EmField(EmComponent):
|
|||
self.check_type('rel_field_id', (int, type(None)))
|
||||
self.icon = icon
|
||||
|
||||
|
||||
#Field type elements
|
||||
self.fieldtype = fieldtype
|
||||
self.nullable = nullable
|
||||
self.default = default
|
||||
self.uniq = uniq
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class Model(object):
|
|||
if not 'type' in kwargs:
|
||||
raise AttributeError("Missing 'type' from EmField instanciation")
|
||||
cls = EditorialModel.fields.EmField.get_field_class(kwargs['type'])
|
||||
kwargs['fieldtype'] = kwargs['type']
|
||||
del(kwargs['type'])
|
||||
else:
|
||||
cls = self.emclass_from_name(cls_name)
|
||||
|
|
@ -103,13 +104,16 @@ class Model(object):
|
|||
component.init_ended()
|
||||
|
||||
## Saves data using the current backend
|
||||
def save(self):
|
||||
return self.backend.save(self)
|
||||
# @param filename str | None : if None use the current backend file (provided at backend instanciation)
|
||||
def save(self, filename = None):
|
||||
return self.backend.save(self, filename)
|
||||
|
||||
## Given a EmComponent child class return a list of instances
|
||||
# @param cls EmComponent : A python class
|
||||
# @return a list of instances or False if the class is not an EmComponent child
|
||||
def components(self, cls):
|
||||
def components(self, cls=None):
|
||||
if cls is None:
|
||||
return [ self.component(uid) for uid in self._components['uids'] ]
|
||||
key_name = self.name_from_emclass(cls)
|
||||
return False if key_name is False else self._components[key_name]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue