1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2025-11-14 18:09:17 +01:00

Supressed _fields from EmComponent and transforming the EmComponent in a standart object with standarts attributes

This commit is contained in:
Yann 2015-07-24 12:01:17 +02:00
commit b6ef37752f
8 changed files with 93 additions and 161 deletions

View file

@ -9,6 +9,13 @@ import json
## Manages a Json file based backend structure
class EmBackendJson(object):
cast_methods = {
'uid' : int,
'rank' : int,
'class_id' : int,
'fieldgroup_id' : int
}
## Constructor
#
# @param json_file str: path to the json_file used as data source
@ -22,5 +29,11 @@ class EmBackendJson(object):
def load(self):
data = {}
for index, component in self.data.items():
data[int(index)] = component
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

View file

@ -23,7 +23,16 @@ class EmClass(EmComponent):
('icon', ftypes.EmField_icon),
('sortcolumn', ftypes.EmField_char)
]
## EmClass instanciation
def __init__(self, model, uid, name, classtype, icon = '0', sortcolumn = 'rank', string = None, help_text = None, date_update = None, date_create = None, rank = None):
self.classtype = classtype
self.icon = icon
self.sortcolumn = 'rank'
super(EmClass, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
pass
## Check if the EmComponent is valid
# @return True if valid False if not
def check(self):

View file

@ -7,6 +7,7 @@ import datetime
import logging
import EditorialModel.fieldtypes as ftypes
from Lodel.utils.mlstring import MlString
from collections import OrderedDict
logger = logging.getLogger('Lodel2.EditorialModel')
@ -22,79 +23,22 @@ class EmComponent(object):
## Used by EmComponent::modify_rank
ranked_in = None
## Read only properties
_ro_properties = ['date_update', 'date_create', 'uid', 'rank', 'deleted']
## @brief List fields name and fieldtype
#
# This is a list that describe database fields common for each EmComponent child classes.
# A database field is defined here by a tuple(name, type) with name a string and type an EditorialModel.fieldtypes.EmFieldType
# @warning The EmFieldType in second position in the tuples must be a class type and not a class instance !!!
# @see EditorialModel::classes::EmClass::_fields EditorialModel::fieldgroups::EmFieldGroup::_fields EditorialModel::types::EmType::_fields EditorialModel::fields::EmField::_fields
_fields = [
('uid', ftypes.EmField_integer),
('name', ftypes.EmField_char),
('rank', ftypes.EmField_integer),
('date_update', ftypes.EmField_date),
('date_create', ftypes.EmField_date),
('string', ftypes.EmField_mlstring),
('help', ftypes.EmField_mlstring)
]
## Instaciate an EmComponent
# @param id_or_name int|str: name or id of the object
# @throw TypeError if id_or_name is not an integer nor a string
# @throw NotImplementedError if called with EmComponent
def __init__(self, data, model):
def __init__(self, model, uid, name, string = None, help_text = None, date_update = None, date_create = None, rank = None):
if type(self) == EmComponent:
raise NotImplementedError('Abstract class')
## @brief An OrderedDict storing fields name and values
# Values are handled by EditorialModel::fieldtypes::EmFieldType
# @warning \ref _fields instance property is not the same than EmComponent::_fields class property. In the instance property the EditorialModel::fieldtypes::EmFieldType are instanciated to be able to handle datas
# @see EmComponent::_fields EditorialModel::fieldtypes::EmFieldType
self._fields = OrderedDict([(name, ftype()) for (name, ftype) in (EmComponent._fields + self.__class__._fields)])
raise NotImplementedError('Abstract class')
self.model = model
self.uid = uid
self.name = name
self.string = MlString() if string is None else string
self.help_text = MlString() if help_text is None else help_text
self.date_update = datetime.datetime.now() if date_update is None else date_update #WARNING timezone !
self.date_create = datetime.datetime.now() if date_create is None else date_create #WARNING timezone !
for name, value in data.items():
if name in self._fields:
self._fields[name].from_string(value)
#Handling specials ranks for component creation
self.rank = rank
pass
## @brief Access an attribute of an EmComponent
# This method is overloads the default __getattr__ to search in EmComponents::_fields . If there is an EditorialModel::EmField with a corresponding name in the component
# it returns its value.
# @param name str: The attribute name
# @throw AttributeError if attribute don't exists
# @see EditorialModel::EmField::value
def __getattr__(self, name):
if name != '_fields' and name in self._fields:
return self._fields[name].value
else:
return super(EmComponent, self).__getattribute__(name)
## @brief Access an EmComponent attribute
# This function overload the default __getattribute__ in order to check if the EmComponent was deleted.
# @param name str: The attribute name
# @throw EmComponentNotExistError if the component was deleted
def __getattribute__(self, name):
if super(EmComponent, self).__getattribute__('deleted'):
raise EmComponentNotExistError("This " + super(EmComponent, self).__getattribute__('__class__').__name__ + " has been deleted")
res = super(EmComponent, self).__getattribute(name)
return res
## Set the value of an EmComponent attribute
# @param name str: The propertie name
# @param value *: The value
def __setattr__(self, name, value):
if name in self.__class__._ro_properties:
raise TypeError("Propertie '" + name + "' is readonly")
if name != '_fields' and hasattr(self, '_fields') and name in object.__getattribute__(self, '_fields'):
self._fields[name].from_python(value)
else:
object.__setattr__(self, name, value)
## @brief Hash function that allows to compare two EmComponent
# @return EmComponent+ClassName+uid
def __hash__(self):
@ -105,17 +49,6 @@ class EmComponent(object):
def __eq__(self, other):
return self.__class__ == other.__class__ and self.uid == other.uid
## Set all fields
def populate(self):
records = [] # TODO
for record in records:
for keys in self._fields.keys():
if keys in record:
self._fields[keys].from_string(record[keys])
super(EmComponent, self).__setattr__('deleted', False)
## Check if the EmComponent is valid
# This function has to check that rank are correct and continuous other checks are made in childs classes
# @warning Hardcoded minimum rank
@ -125,7 +58,7 @@ class EmComponent(object):
if self.get_max_rank() > len(self.same_rank_group()):
#Non continuous ranks
for i, component in enumerate(self.same_rank_group()):
component._fields['rank'].value = i + 1
component.rank = i + 1
# No need to sort again here
return True
@ -133,7 +66,7 @@ class EmComponent(object):
# @return A positive integer or -1 if no components
def get_max_rank(self):
components = self.same_rank_group()
return -1 if len(components) == 0 else components[-1].rank
return 1 if len(components) == 0 else components[-1].rank
## Return an array of instances that are concerned by the same rank
# @return An array of instances that are concerned by the same rank
@ -167,9 +100,9 @@ class EmComponent(object):
limits.sort()
for component in [ c for c in self.same_rank_group() if c.rank >= limits[0] and c.rank <= limits[1] ] :
component._fields['rank'].value = component.rank + ( -1 if mod > 0 else 1 )
component.rank = component.rank + ( -1 if mod > 0 else 1 )
self._fields['rank'].value = new_rank
self.rank = new_rank
self.model.sort_components(self.__class__)

View file

@ -13,8 +13,11 @@ class EmFieldGroup(EmComponent):
ranked_in = 'class_id'
## List of fields
_fields = [('class_id', ftypes.EmField_integer)]
## EmFieldGroup instanciation
def __init__(self, model, uid, name, class_id, string = None, help_text = None, date_update = None, date_create = None, rank = None):
self.class_id = class_id
super(EmFieldGroup, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
pass
## Check if the EmFieldGroup is valid
# @return True if valid False if not

View file

@ -9,20 +9,17 @@ from EditorialModel.fieldtypes import EmField_boolean, EmField_char, EmField_int
# Represents one data for a lodel2 document
class EmField(EmComponent):
table = 'em_field'
ranked_in = 'fieldgroup_id'
_fields = [
('fieldtype', EmField_char),
('fieldgroup_id', EmField_integer),
('rel_to_type_id', EmField_integer),
('rel_field_id', EmField_integer),
('optional', EmField_boolean),
('internal', EmField_boolean),
('icon', EmField_icon)
]
def __init__(self, datas, model):
super(EmField, self).__init__(datas, model)
def __init__(self, model, uid, name, fieldgroup_id, fieldtype, optional = False, internal = False, rel_to_type_id = None, rel_field_id = None, icon = '0', string = None, help_text = None, date_update = None, date_create = None, rank = None):
self.fieldgroup_id = fieldgroup_id
self.fieldtype = fieldtype
self.optional = optional
self.internal = internal
self.rel_to_type_id = rel_to_type_id
self.rel_field_id = rel_field_id
self.icon = icon
super(EmField, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
## Check if the EmField is valid
# @return True if valid False if not

View file

@ -50,14 +50,16 @@ class Model(object):
# @todo Change the thrown exception when a components check fails
# @throw ValueError When a component class don't exists
def load(self):
data = self.backend.load()
for uid, component in data.items():
cls_name = component['component']
datas = self.backend.load()
for uid, kwargs in datas.items():
#Store and delete the EmComponent class name from datas
cls_name = kwargs['component']
del kwargs['component']
cls = self.emclass_from_name(cls_name)
if cls:
component['uid'] = uid
kwargs['uid'] = uid
# create a dict for the component and one indexed by uids, store instanciated component in it
self._components['uids'][uid] = cls(component, self)
self._components['uids'][uid] = cls(self, **kwargs)
self._components[cls_name].append(self._components['uids'][uid])
else:
raise ValueError("Unknow EmComponent class : '" + cls_name + "'")
@ -114,36 +116,20 @@ class Model(object):
em_obj = self.emclass_from_name(component_type)
datas['uid'] = self.new_uid()
em_component = em_obj(datas, self)
rank = None
rank = 'last'
if 'rank' in datas:
rank = datas['rank']
datas['rank'] = None
del datas['rank']
datas['uid'] = self.new_uid()
em_component = em_obj(self, **datas)
self._components['uids'][em_component.uid] = em_component
self._components[self.name_from_emclass(em_component.__class__)].append(em_component)
create_fails = None
if rank is None or rank == 'last':
em_component.rank = em_component.get_max_rank()
elif datas['rank'] == 'first':
em_component.set_rank(1)
elif isinstance(rank, int):
em_component.set_rank(rank)
else:
create_fails = ValueError("Invalid rank : '"+str(datas['rank'])+"'")
self.delete(em_component.uid)
if not em_component.check():
create_fails = RuntimeError("After creation the component self check fails")
if not create_fails is None:
raise create_fails
em_component.rank = em_component.get_max_rank()
if rank != 'last':
em_component.set_rank( 1 if rank == 'first' else rank)
return em_component

View file

@ -1,53 +1,53 @@
{
"1" : {
"component":"EmClass", "name":"textes", "string":"{\"fre\":\"Texte\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "classtype":"entity", "icon":"0", "sortcolumn":"rank"
"component":"EmClass", "name":"textes", "string":"{\"fre\":\"Texte\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "classtype":"entity", "icon":"0", "sortcolumn":"rank"
},
"2" : {
"component":"EmClass", "name":"personnes", "string":"{\"fre\":\"Personnes\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "classtype":"person", "icon":"0", "sortcolumn":"rank"
"component":"EmClass", "name":"personnes", "string":"{\"fre\":\"Personnes\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "classtype":"person", "icon":"0", "sortcolumn":"rank"
},
"3" : {
"component":"EmFieldGroup", "name":"info", "string":"{\"fre\":\"Info\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"1"
"component":"EmFieldGroup", "name":"info", "string":"{\"fre\":\"Info\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"1"
},
"4" : {
"component":"EmField", "name":"titre", "string":"{\"fre\":\"Titre\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"3", "rel_to_type_id":"", "rel_field_id":"", "optional":"0", "internal":"", "icon":"0"
"component":"EmField", "name":"titre", "string":"{\"fre\":\"Titre\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"3", "rel_to_type_id":"", "rel_field_id":"", "optional":"0", "internal":"", "icon":"0"
},
"5" : {
"component":"EmType", "name":"article", "string":"{\"fre\":\"Article\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"1", "icon":"0", "sortcolumn":"rank", "selected_fields":[7]
"component":"EmType", "name":"article", "string":"{\"fre\":\"Article\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"1", "icon":"0", "sortcolumn":"rank", "selected_fields":[7]
},
"6" : {
"component":"EmType", "name":"personne", "string":"{\"fre\":\"Personne\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"2", "icon":"0", "sortcolumn":"rank", "selected_fields":[10]
"component":"EmType", "name":"personne", "string":"{\"fre\":\"Personne\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"2", "icon":"0", "sortcolumn":"rank", "selected_fields":[10]
},
"7" : {
"component":"EmField", "name":"soustitre", "string":"{\"fre\":\"Sous-titre\"}", "help":"{}", "rank":"2", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"3", "rel_to_type_id":"", "rel_field_id":"", "optional":"1", "internal":"", "icon":"0"
"component":"EmField", "name":"soustitre", "string":"{\"fre\":\"Sous-titre\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"3", "rel_to_type_id":"", "rel_field_id":"", "optional":"1", "internal":"", "icon":"0"
},
"8" : {
"component":"EmFieldGroup", "name":"civilité", "string":"{\"fre\":\"Civilité\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"2"
"component":"EmFieldGroup", "name":"civilité", "string":"{\"fre\":\"Civilité\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"2"
},
"9" : {
"component":"EmField", "name":"nom", "string":"{\"fre\":\"Nom\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"8", "rel_to_type_id":"", "rel_field_id":"", "optional":"0", "internal":"", "icon":"0"
"component":"EmField", "name":"nom", "string":"{\"fre\":\"Nom\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"8", "rel_to_type_id":"", "rel_field_id":"", "optional":"0", "internal":"", "icon":"0"
},
"10" : {
"component":"EmField", "name":"prenom", "string":"{\"fre\":\"Preom\"}", "help":"{}", "rank":"2", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"8", "rel_to_type_id":"", "rel_field_id":"", "optional":"1", "internal":"", "icon":"0"
"component":"EmField", "name":"prenom", "string":"{\"fre\":\"Preom\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"8", "rel_to_type_id":"", "rel_field_id":"", "optional":"1", "internal":"", "icon":"0"
},
"11" : {
"component":"EmField", "name":"auteur", "string":"{\"fre\":\"Auteur\"}", "help":"{}", "rank":"3", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"17", "rel_to_type_id":"6", "rel_field_id":"", "optional":"1", "internal":"", "icon":"0"
"component":"EmField", "name":"auteur", "string":"{\"fre\":\"Auteur\"}", "help_text":"{}", "rank":"3", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"17", "rel_to_type_id":"6", "rel_field_id":"", "optional":"1", "internal":"", "icon":"0"
},
"12" : {
"component":"EmField", "name":"adresse", "string":"{\"fre\":\"Adresse\"}", "help":"{}", "rank":"4", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"17", "rel_to_type_id":"", "rel_field_id":"11", "optional":"0", "internal":"", "icon":"0"
"component":"EmField", "name":"adresse", "string":"{\"fre\":\"Adresse\"}", "help_text":"{}", "rank":"4", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"17", "rel_to_type_id":"", "rel_field_id":"11", "optional":"0", "internal":"", "icon":"0"
},
"13" : {
"component":"EmClass", "name":"publication", "string":"{\"fre\":\"Publication\"}", "help":"{}", "rank":"2", "date_update":"", "date_create":"", "classtype":"entity", "icon":"0", "sortcolumn":"rank"
"component":"EmClass", "name":"publication", "string":"{\"fre\":\"Publication\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "classtype":"entity", "icon":"0", "sortcolumn":"rank"
},
"14" : {
"component":"EmType", "name":"rubrique", "string":"{\"fre\":\"Rubrique\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13", "icon":"0", "sortcolumn":"rank", "subordinates":[["parent",5], ["parent",14]]
"component":"EmType", "name":"rubrique", "string":"{\"fre\":\"Rubrique\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13", "icon":"0", "sortcolumn":"rank", "subordinates":[["parent",5], ["parent",14]]
},
"15" : {
"component":"EmFieldGroup", "name":"info", "string":"{\"fre\":\"Info\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13"
"component":"EmFieldGroup", "name":"info", "string":"{\"fre\":\"Info\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "class_id":"13"
},
"16" : {
"component":"EmField", "name":"titre", "string":"{\"fre\":\"Titre\"}", "help":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"15", "rel_to_type_id":"", "rel_field_id":"", "optional":"0", "internal":"", "icon":"0"
"component":"EmField", "name":"titre", "string":"{\"fre\":\"Titre\"}", "help_text":"{}", "rank":"1", "date_update":"", "date_create":"", "fieldtype":"", "fieldgroup_id":"15", "rel_to_type_id":"", "rel_field_id":"", "optional":"0", "internal":"", "icon":"0"
},
"17" : {
"component":"EmFieldGroup", "name":"gens", "string":"{\"fre\":\"Gens\"}", "help":"{}", "rank":"2", "date_update":"", "date_create":"", "class_id":"1"
"component":"EmFieldGroup", "name":"gens", "string":"{\"fre\":\"Gens\"}", "help_text":"{}", "rank":"2", "date_update":"", "date_create":"", "class_id":"1"
}
}

View file

@ -20,25 +20,16 @@ import EditorialModel.classes
# @see EditorialModel::components::EmComponent
# @todo sortcolumn handling
class EmType(EmComponent):
table = 'em_type'
table_hierarchy = 'em_type_hierarchy'
ranked_in = 'class_id'
## @brief Specific EmClass fields
# @see EditorialModel::components::EmComponent::_fields
_fields = [
('class_id', ftypes.EmField_integer),
('icon', ftypes.EmField_icon),
('sortcolumn', ftypes.EmField_char)
]
def __init__(self, data, model):
super(EmType, self).__init__(data, model)
for link in ['selected_fields', 'subordinates']:
if link in data:
self._fields[link] = data[link]
else:
self._fields[link] = []
def __init__(self, model, uid, name, class_id, selected_fields = [], subordinates = [], icon = '0', sortcolumn = 'rank', string = None, help_text = None, date_update = None, date_create = None, rank = None):
self.class_id = class_id
self.selected_fields = selected_fields
self.subordinates = subordinates
self.icon = icon
self.sortcolumn = sortcolumn
super(EmType, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
pass
@classmethod
## Create a new EmType and instanciate it