1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2026-07-05 07:10:48 +02:00

First commit with an em_editor instance

This commit is contained in:
Yann 2016-02-24 17:14:16 +01:00
commit 362c67529c
16 changed files with 1891 additions and 5 deletions

View file

@ -139,10 +139,6 @@ class EmField(EmComponent):
#Uniq Name check
if len([f for f in self.em_class.fields() if f.name == self.name]) > 1:
raise EmComponentCheckError("The field %d has a name '%s' that is not uniq in the EmClass %d" % (self.uid, self.name, self.em_class.uid))
#rel2type uniq check
if self.fieldtype == 'rel2type':
if len([f for f in self.em_class.fields() if f.fieldtype == 'rel2type' and f.rel_to_type_id == self.rel_to_type_id]) > 1:
raise EmComponentCheckError("The rel2type %d is not uniq, another field is linked to the same type '%s' in the same class '%s'" % (self.uid, self.model.component(self.rel_to_type_id).name, self.em_class.name))
## @brief Delete a field if it's not linked
# @return bool : True if deleted False if deletion aborded

View file

@ -183,7 +183,7 @@ class Model(object):
em_obj = self.emclass_from_name(component_type)
rank = 'last'
if 'rank' in datas:
if 'rank' in datas and not datas['rank'] is None:
rank = datas['rank']
del datas['rank']
@ -221,6 +221,28 @@ class Model(object):
return em_component
## @brief Create a new EmClass
def add_class(self, name, classtype, string=None, help_text=None, date_update = None, date_create = None, rank = None):
datas = locals()
del(datas['self'])
return self.create_component('EmClass', datas)
## @brief Create a new EmType
def add_type(self, name, emclass, fields_list = None, superiors_list = None, icon='0', sortcolumn='rank', string = None, help_text = None, date_update = None, date_create = None, rank = None):
datas = locals()
del(datas['self'])
emclass = datas['emclass']
del(datas['emclass'])
datas['class_id'] = emclass.uid if isinstance(emclass, EmClass) else emclass
return self.create_component('EmType', datas)
## @brief Add a new EmField
def add_field(self, name, emclass, fieldtype, **kwargs):
kwargs['name'] = name
kwargs['fieldtype'] = fieldtype
kwargs['class_id'] = emclass.uid if isinstance(emclass, EmClass) else emclass
return self.create_component('EmField', kwargs)
## @brief Add to a class (if not exists) the default fields
#
# @param class_uid int : An EmClass uid

26
em_editor/Makefile Normal file
View file

@ -0,0 +1,26 @@
all: refreshdyn dbinit dirinit
refreshdyn: distclean
python -c "import utils; utils.refreshdyn()"
dbinit:
python -c "import utils; utils.db_init()"
dirinit:
python -c "import utils; utils.dir_init()"
emgraph:
python -c "import utils; utils.em_graph()"
.PHONY: clean cleanpycache cleanpyc refreshdyn distclean
distclean: clean
-@rm -vf dynleapi.py
clean: cleanpycache
cleanpyc:
-@rm -vf *.pyc
cleanpycache: cleanpyc
-@rm -vfR __pycache__

11
em_editor/README.txt Normal file
View file

@ -0,0 +1,11 @@
Common operations :
===================
Refresh leapi dynamic code (when the Editorial Model is updated) :
make refreshdyn
Update or init the database :
make dbinit
To run an interactive python interpreter in the instance environnment run :
python loader.py

334
em_editor/dynleapi.py Normal file
View file

@ -0,0 +1,334 @@
## @author LeFactory
import EditorialModel
from EditorialModel import fieldtypes
from EditorialModel.fieldtypes import naturerelation, leo, datetime, dictionary, rank, namerelation, pk, bool, i18n, char, integer, emuid
from Lodel.utils.mlstring import MlString
import leapi
import leapi.lecrud
import leapi.leobject
import leapi.lerelation
from leapi.leclass import _LeClass
from leapi.letype import _LeType
import DataSource.MySQL.leapidatasource
## @brief _LeCrud concret class
# @see leapi.lecrud._LeCrud
class LeCrud(leapi.lecrud._LeCrud):
_datasource = DataSource.MySQL.leapidatasource.LeDataSourceSQL(**{})
_uid_fieldtype = None
## @brief _LeObject concret class
# @see leapi.leobject._LeObject
class LeObject(LeCrud, leapi.leobject._LeObject):
_me_uid = {32: 'Emclass', 33: 'Emtype', 34: 'Emfield', 22: 'Emcomponent', 1: '_Editorialmodel', 8: '_Classtype', 15: '_Hierarchy', 29: 'Classtype', 30: 'Hierarchyoptions', 31: 'Editorialmodel'}
_me_uid_field_names = ('class_id', 'type_id')
_uid_fieldtype = { 'lodel_id': EditorialModel.fieldtypes.pk.EmFieldType(**{'uniq': False, 'nullable': False, 'immutable': True, 'internal': 'autosql', 'string': '{"___": "", "fre": "identifiant lodel", "eng": "lodel identifier"}'}) }
_leo_fieldtypes = {
'class_id': EditorialModel.fieldtypes.emuid.EmFieldType(**{'uniq': False, 'nullable': False, 'immutable': True, 'internal': 'automatic', 'string': '{"___": "", "fre": "identifiant de la classe", "eng": "class identifier"}', 'is_id_class': True}),
'type_id': EditorialModel.fieldtypes.emuid.EmFieldType(**{'uniq': False, 'nullable': False, 'immutable': True, 'internal': 'automatic', 'string': '{"___": "", "fre": "identifiant de la type", "eng": "type identifier"}', 'is_id_class': False}),
'modification_date': EditorialModel.fieldtypes.datetime.EmFieldType(**{'uniq': False, 'internal': 'autosql', 'now_on_update': True, 'immutable': True, 'nullable': False, 'now_on_create': True, 'string': '{"___": "", "fre": "Date de modification", "eng": "Modification date"}'}),
'string': None,
'creation_date': EditorialModel.fieldtypes.datetime.EmFieldType(**{'uniq': False, 'internal': 'autosql', 'now_on_create': True, 'immutable': True, 'nullable': False, 'string': '{"___": "", "fre": "Date de création", "eng": "Creation date"}'})
}
## @brief _LeRelation concret class
# @see leapi.lerelation._LeRelation
class LeRelation(LeCrud, leapi.lerelation._LeRelation):
_uid_fieldtype = { 'id_relation': EditorialModel.fieldtypes.pk.EmFieldType(**{'immutable': True, 'internal': 'autosql'}) }
_rel_fieldtypes = {
'relation_name': EditorialModel.fieldtypes.namerelation.EmFieldType(**{'max_length': 128, 'immutable': True}),
'nature': EditorialModel.fieldtypes.naturerelation.EmFieldType(**{'immutable': True}),
'superior': EditorialModel.fieldtypes.leo.EmFieldType(**{'immutable': True, 'superior': True}),
'depth': EditorialModel.fieldtypes.integer.EmFieldType(**{'immutable': True, 'internal': 'automatic'}),
'rank': EditorialModel.fieldtypes.rank.EmFieldType(**{'immutable': True, 'internal': 'automatic'}),
'subordinate': EditorialModel.fieldtypes.leo.EmFieldType(**{'immutable': True, 'superior': False})
}
## WARNING !!!! OBSOLETE ! DON'T USE IT
_superior_field_name = 'superior'
## WARNING !!!! OBSOLETE ! DON'T USE IT
_subordinate_field_name = 'subordinate'
class LeHierarch(LeRelation, leapi.lerelation._LeHierarch):
pass
class LeRel2Type(LeRelation, leapi.lerelation._LeRel2Type):
pass
class LeClass(LeObject, _LeClass):
pass
class LeType(LeClass, _LeType):
pass
## @brief EmClass _Editorialmodel LeClass child class
# @see leapi.leclass.LeClass
class _Editorialmodel(LeClass, LeObject):
_class_id = 1
ml_string = MlString('_EditorialModel')
## @brief EmClass _Classtype LeClass child class
# @see leapi.leclass.LeClass
class _Classtype(LeClass, LeObject):
_class_id = 8
ml_string = MlString('_ClassType')
## @brief EmClass _Hierarchy LeClass child class
# @see leapi.leclass.LeClass
class _Hierarchy(LeClass, LeObject):
_class_id = 15
ml_string = MlString('_Hierarchy')
## @brief EmClass Emcomponent LeClass child class
# @see leapi.leclass.LeClass
class Emcomponent(LeClass, LeObject):
_class_id = 22
ml_string = MlString('EmComponent')
## @brief EmType Classtype LeType child class
# @see leobject::letype::LeType
class Classtype(LeType, _Classtype):
_type_id = 29
ml_string = MlString('ClassType')
## @brief EmType Hierarchyoptions LeType child class
# @see leobject::letype::LeType
class Hierarchyoptions(LeType, _Hierarchy):
_type_id = 30
ml_string = MlString('HierarchyOptions')
## @brief EmType Editorialmodel LeType child class
# @see leobject::letype::LeType
class Editorialmodel(LeType, _Editorialmodel):
_type_id = 31
ml_string = MlString('EditorialModel')
## @brief EmType Emclass LeType child class
# @see leobject::letype::LeType
class Emclass(LeType, Emcomponent):
_type_id = 32
ml_string = MlString('EmClass')
## @brief EmType Emtype LeType child class
# @see leobject::letype::LeType
class Emtype(LeType, Emcomponent):
_type_id = 33
ml_string = MlString('EmType')
## @brief EmType Emfield LeType child class
# @see leobject::letype::LeType
class Emfield(LeType, Emcomponent):
_type_id = 34
ml_string = MlString('EmField')
class Rel_ClasstypeHierarchyoptionsHierarchy_Specs(LeRel2Type):
_rel_attr_fieldtypes = {
'nature': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 10, 'uniq': False, 'nullable': False})
}
_superior_cls = _Classtype
_subordinate_cls = Hierarchyoptions
_relation_name = 'hierarchy_specs'
class RelEmcomponentClasstypeClasstype(LeRel2Type):
_rel_attr_fieldtypes = {
}
_superior_cls = Emcomponent
_subordinate_cls = Classtype
_relation_name = 'classtype'
class RelEmcomponentEmfieldSort_Column(LeRel2Type):
_rel_attr_fieldtypes = {
}
_superior_cls = Emcomponent
_subordinate_cls = Emfield
_relation_name = 'sort_column'
class RelEmcomponentEmclassParent_Class(LeRel2Type):
_rel_attr_fieldtypes = {
}
_superior_cls = Emcomponent
_subordinate_cls = Emclass
_relation_name = 'parent_class'
class RelEmcomponentEmfieldSelected_Field(LeRel2Type):
_rel_attr_fieldtypes = {
}
_superior_cls = Emcomponent
_subordinate_cls = Emfield
_relation_name = 'selected_field'
class RelEmcomponentEmtypeSuperiors(LeRel2Type):
_rel_attr_fieldtypes = {
'nature': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': '10', 'uniq': False, 'nullable': False})
}
_superior_cls = Emcomponent
_subordinate_cls = Emtype
_relation_name = 'superiors'
class RelEmcomponentEmfieldRel_Field(LeRel2Type):
_rel_attr_fieldtypes = {
}
_superior_cls = Emcomponent
_subordinate_cls = Emfield
_relation_name = 'rel_field'
#Initialisation of _Editorialmodel class attributes
_Editorialmodel._fieldtypes = {
'description': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 4096, 'uniq': False, 'nullable': False}),
'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
'name': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 56, 'uniq': False, 'nullable': False})
}
_Editorialmodel.ml_fields_strings = {
'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
'name': MlString({"___": "name"}),
'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
'description': MlString({"___": "description"})
}
_Editorialmodel._linked_types = {
}
_Editorialmodel._classtype = 'entity'
#Initialisation of _Classtype class attributes
_Classtype._fieldtypes = {
'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
'name': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 56, 'uniq': False, 'nullable': False})
}
_Classtype.ml_fields_strings = {
'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
'name': MlString({"___": "name"}),
'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
'hierarchy_specs': MlString({"___": "hierarchy_specs"}),
'nature': MlString({"___": "nature"})
}
_Classtype._linked_types = {
'hierarchy_specs': Hierarchyoptions
}
_Classtype._classtype = 'entity'
#Initialisation of _Hierarchy class attributes
_Hierarchy._fieldtypes = {
'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
'attach': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 10, 'uniq': False, 'nullable': False}),
'maxdepth': EditorialModel.fieldtypes.integer.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
'maxchildren': EditorialModel.fieldtypes.integer.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
'automatic': EditorialModel.fieldtypes.bool.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False})
}
_Hierarchy.ml_fields_strings = {
'maxchildren': MlString({"___": "maxchildren"}),
'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
'automatic': MlString({"___": "automatic"}),
'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
'attach': MlString({"___": "attach"}),
'maxdepth': MlString({"___": "maxdepth"})
}
_Hierarchy._linked_types = {
}
_Hierarchy._classtype = 'entity'
#Initialisation of Emcomponent class attributes
Emcomponent._fieldtypes = {
'fieldtype': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
'name': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 56, 'uniq': False, 'nullable': False}),
'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
'help_text': EditorialModel.fieldtypes.i18n.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
'fieldtype_options': EditorialModel.fieldtypes.dictionary.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
'date_update': EditorialModel.fieldtypes.datetime.EmFieldType(**{'now_on_update': True, 'nullable': False, 'uniq': False, 'internal': False}),
'date_create': EditorialModel.fieldtypes.datetime.EmFieldType(**{'now_on_create': True, 'internal': False, 'uniq': False, 'nullable': False}),
'rank': EditorialModel.fieldtypes.integer.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False})
}
Emcomponent.ml_fields_strings = {
'superiors': MlString({"___": "superiors"}),
'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
'name': MlString({"___": "name"}),
'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
'parent_class': MlString({"___": "parent_class"}),
'fieldtype_options': MlString({"___": "fieldtype_options"}),
'help_text': MlString({"___": "help_text"}),
'rank': MlString({"___": "rank"}),
'sort_column': MlString({"___": "sort_column"}),
'fieldtype': MlString({"___": "fieldtype"}),
'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
'selected_field': MlString({"___": "selected_field"}),
'rel_field': MlString({"___": "rel_field"}),
'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
'classtype': MlString({"___": "classtype"}),
'date_create': MlString({"___": "date_create"}),
'nature': MlString({"___": "nature"}),
'date_update': MlString({"___": "date_update"})
}
Emcomponent._linked_types = {
'superiors': Emtype,
'rel_field': Emfield,
'classtype': Classtype,
'parent_class': Emclass,
'sort_column': Emfield,
'selected_field': Emfield
}
Emcomponent._classtype = 'entity'
#Initialisation of Classtype class attributes
Classtype._fields = ['name']
Classtype._superiors = {}
Classtype._leclass = _Classtype
#Initialisation of Hierarchyoptions class attributes
Hierarchyoptions._fields = ['attach', 'automatic', 'maxdepth', 'maxchildren']
Hierarchyoptions._superiors = {}
Hierarchyoptions._leclass = _Hierarchy
#Initialisation of Editorialmodel class attributes
Editorialmodel._fields = ['name', 'description']
Editorialmodel._superiors = {}
Editorialmodel._leclass = _Editorialmodel
#Initialisation of Emclass class attributes
Emclass._fields = ['name', 'help_text', 'date_update', 'date_create', 'rank']
Emclass._superiors = {'parent': [Editorialmodel]}
Emclass._leclass = Emcomponent
#Initialisation of Emtype class attributes
Emtype._fields = ['name', 'help_text', 'date_update', 'date_create', 'rank']
Emtype._superiors = {'parent': [Emclass]}
Emtype._leclass = Emcomponent
#Initialisation of Emfield class attributes
Emfield._fields = ['name', 'help_text', 'date_update', 'date_create', 'rank', 'fieldtype', 'fieldtype_options']
Emfield._superiors = {'parent': [Emtype]}
Emfield._leclass = Emcomponent
## @brief Dict for getting LeClass and LeType child classes given an EM uid
LeObject._me_uid = {32: Emclass, 1: _Editorialmodel, 34: Emfield, 22: Emcomponent, 33: Emtype, 8: _Classtype, 31: Editorialmodel, 29: Classtype, 30: Hierarchyoptions, 15: _Hierarchy}

1022
em_editor/em.json Normal file

File diff suppressed because it is too large Load diff

32
em_editor/em_editor.py Normal file
View file

@ -0,0 +1,32 @@
#-*- coding: utf-8 -*-
from loader import *
import os, os.path, code
from EditorialModel.model import Model
from EditorialModel.backend.json_backend import EmBackendJson
from EditorialModel.classes import EmClass
from EditorialModel.types import EmType
from EditorialModel.fields import EmField
from EditorialModel.classtypes import *
emfile = input("Enter em path please : ")
if not os.path.isfile(emfile):
with open(emfile,'w+') as fd:
fd.write('{}')
em = Model(EmBackendJson(emfile))
print("Editorial model loaded in em variable : ")
for comptype in [ 'EmClass', 'EmType', 'EmField' ]:
print("\t* %s :" % comptype)
complist = em.components(comptype)
if len(complist) == 0:
print("\t\tEMPTY")
for comp in complist:
print("\t\t- %s" % comp.name)
code.interact(local=locals())

112
em_editor/init_em.py Normal file
View file

@ -0,0 +1,112 @@
#-*- coding: utf-8 -*-
from loader import *
import os, os.path, code
from EditorialModel.model import Model
from EditorialModel.backend.json_backend import EmBackendJson
from EditorialModel.classes import EmClass
from EditorialModel.types import EmType
from EditorialModel.fields import EmField
from EditorialModel.classtypes import *
from EditorialModel.fieldtypes.generic import GenericFieldType
emfile = 'em.json'
if not os.path.isfile(emfile):
with open(emfile,'w+') as fd:
fd.write('{}')
em = Model(EmBackendJson(emfile))
#GenericFieldType.from_name()
def ft(name):
return GenericFieldType.from_name()
class_em = em.add_class('_EditorialModel', classtype = 'entity')
class_ctype = em.add_class('_ClassType', classtype='entity')
class_ctype_h = em.add_class('_Hierarchy', classtype='entity')
class_comp = em.add_class('EmComponent', classtype='entity')
# class_ftype = em.add_class('_FieldType', classtype = 'entity')
# type_ftype = em.add_type('FieldType', class_ftype)
type_ctype = em.add_type('ClassType', class_ctype)
type_ctype_h = em.add_type('HierarchyOptions', class_ctype_h)
type_em = em.add_type('EditorialModel', class_em)
type_class = em.add_type('EmClass', class_comp, superiors_list = {'parent': [type_em.uid]})
type_type = em.add_type('EmType', class_comp, superiors_list = {'parent':[type_class.uid]})
type_field = em.add_type('EmField', class_comp, superiors_list = {'parent':[type_type.uid]})
# FieldType common fields
# em.add_field('name', class_ftype, fieldtype = 'char', max_length = 56)
# em.add_field('max_length', class_ftype, optional = True, fieldtype = 'integer')
# EditorialModel common fields
em.add_field('name', class_em, fieldtype = 'char', max_length = 56)
em.add_field('description', class_em, fieldtype = 'char', max_length = 4096)
# Hierarchy options common fields
em.add_field('attach', class_ctype_h, fieldtype = 'char', max_length = 10)
em.add_field('automatic', class_ctype_h, fieldtype = 'bool')
em.add_field('maxdepth', class_ctype_h, fieldtype = 'integer')
em.add_field('maxchildren', class_ctype_h, fieldtype = 'integer')
# ClassType common fields
em.add_field('name', class_ctype, fieldtype = 'char', max_length = 56)
field_hspec = em.add_field('hierarchy_specs', class_ctype, fieldtype = 'rel2type', rel_to_type_id = type_ctype_h)
em.add_field('nature', class_ctype, fieldtype = 'char', max_length = 10, rel_field_id = field_hspec.uid)
# EmComponent common fields
em.add_field('name', class_comp, fieldtype = 'char', max_length = 56)
# Part of default fields #em.add_field('string', class_comp, fieldtype = 'i18n')
em.add_field('help_text', class_comp, fieldtype = 'i18n')
em.add_field('date_update', class_comp, fieldtype = 'datetime', now_on_update = True)
em.add_field('date_create', class_comp, fieldtype = 'datetime', now_on_create = True)
em.add_field('rank', class_comp, fieldtype = 'integer')
# EmComponent optional fields
field_ctype = em.add_field('classtype', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_ctype.uid)
field_sortcol = em.add_field('sort_column', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_field.uid)
field_pclass = em.add_field('parent_class', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_class.uid)
field_selfield = em.add_field('selected_field', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_field.uid)
field_superior = em.add_field('superiors', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_type.uid)
field_nature = em.add_field('nature', class_comp, optional = True, fieldtype = 'char', max_length = 10, rel_field_id = field_superior.uid)
# field_ftype = em.add_field('fieldtype', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_ftype)
field_ftype = em.add_field('fieldtype', class_comp, optional = True, fieldtype = 'char')
field_ftypeopt = em.add_field('fieldtype_options', class_comp, optional = True, fieldtype = 'dictionary')
field_relfield = em.add_field('rel_field', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_field)
# EmClass field selection
type_class.select_field(field_ctype)
type_class.select_field(field_sortcol)
# EmType field selection
type_type.select_field(field_sortcol)
type_type.select_field(field_pclass)
type_type.select_field(field_selfield)
type_type.select_field(field_superior)
type_type.select_field(field_nature)
# EmField field selection
type_field.select_field(field_ftype)
type_field.select_field(field_relfield)
type_field.select_field(field_ftypeopt)
em.save()
"""
print("Editorial model loaded in em variable : ")
for comptype in [ 'EmClass', 'EmType', 'EmField' ]:
print("\t* %s :" % comptype)
complist = em.components(comptype)
if len(complist) == 0:
print("\t\tEMPTY")
for comp in complist:
print("\t\t- %s" % comp.name)
code.interact(local=locals())
"""

View file

@ -0,0 +1,26 @@
#-*- coding:utf8 -*-
import pymysql
import os
sitename = 'em_editor'
lodel2_lib_path = '/home/yannweb/dev/lodel2/lodel2-git'
templates_base_dir = 'LODEL2_INSTANCE_TEMPLATES_BASE_DIR'
debug = False
em_file = 'em.json'
dynamic_code_file = 'dynleapi.py'
ds_package = 'MySQL'
mh_classname = 'MysqlMigrationHandler'
datasource = {
'default': {
'module': pymysql,
'host': '127.0.0.1',
'user': 'lodel',
'passwd': 'bruno',
'db': 'lodel2tests'
}
}

38
em_editor/loader.py Normal file
View file

@ -0,0 +1,38 @@
import instance_settings
import importlib
import sys
import os
sys.path.append(instance_settings.lodel2_lib_path)
from Lodel.settings import Settings
# Settings initialisation
Settings.load_module(instance_settings)
globals()['Settings'] = Settings
from Lodel import logger # logger import and initialisation
from plugins import * #Load activated plugins
# Import dynamic code
if os.path.isfile(Settings.dynamic_code_file):
from dynleapi import *
# Import wanted datasource objects
for db_modname in ['leapidatasource', 'migrationhandler']:
mod = importlib.import_module("DataSource.{pkg_name}.{mod_name}".format(
pkg_name=Settings.get('ds_package'),
mod_name=db_modname,
)
)
# Expose the module in globals
globals()[db_modname] = mod
if __name__ == '__main__':
import code
print("""
Running interactive python in Lodel2 %s instance environment
"""%Settings.sitename)
code.interact(local=locals())

64
em_editor/manage_lodel.py Normal file
View file

@ -0,0 +1,64 @@
#-*- coding: utf-8 -*-
import sys
import argparse
try:
from loader import *
except ImportError: pass
from plugins import *
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'--list-hooks',
action='store_const',
const=True,
default=False,
help='Display the list of registered hooks'
)
parser.add_argument(
'--list-plugins',
action='store_const',
const=True,
default=False,
help='Display the list of plugins'
)
parser.add_argument(
'--plugin',
action='store',
type=str,
metavar='PLUGIN_NAME',
nargs='+',
help='Filter on plugins name'
)
parser.add_argument(
'--hookname',
action='store',
type=str,
metavar='HOOK_NAME',
nargs='+',
help='Filter on hook name'
)
kwargs = parser.parse_args()
# Listing registered hooks
if kwargs.list_hooks:
import Lodel.plugins
list_args = {}
if kwargs.plugin is not None and len(kwargs.plugin) > 0:
list_args['plugins'] = kwargs.plugin
if kwargs.hookname is not None and len(kwargs.hookname) > 0:
list_args['names'] = kwargs.hookname
print(Lodel.plugins.list_hooks(**list_args))
exit(0)
# Listing plugins
elif kwargs.list_plugins:
import Lodel.plugins
print(Lodel.plugins.list_plugins())
exit(0)
parser.print_help()
exit(1)

88
em_editor/netipy.py Normal file
View file

@ -0,0 +1,88 @@
#!/usr/bin/python3
#-*- coding: utf-8 -*-
#
# A server that provide access to interactive python interpreter through network
#
# This is a demo implementation of a Lodel2 interface
import socket
import threading
import subprocess
import time
import sys
import signal
PORT = 1337
#BIND = None
BIND = 'localhost'
THREAD_COUNT = 10
SOCK_TIMEOUT = 5
servsock = None # Stores the server socket in order to close it when exception is raised
# Thread function called when client connected
def client_thread(sock, addr):
# Starting interactive Lodel2 python in a subprocess
sock.setblocking(True)
sock_stdin = sock.makefile(mode='r', encoding='utf-8', newline="\n")
sock_stdout = sock.makefile(mode='w', encoding='utf-8', newline="\n")
ipy = subprocess.Popen(['python', 'netipy_loader.py', addr[0]], stdin=sock_stdin, stdout=sock_stdout, stderr=sock_stdout)
ipy.wait()
sock.close()
return True
# Main loop
def main():
servsock = socket.socket(family = socket.AF_INET, type=socket.SOCK_STREAM)
servsock.settimeout(5)
bind_addr = socket.gethostname() if BIND is None else BIND
servsock.bind((bind_addr, PORT))
servsock.listen(5)
globals()['servsock'] = servsock
threads = list()
print("Server listening on %s:%s" % (bind_addr, PORT))
while True:
# Accept if rooms left in threads list
if len(threads) < THREAD_COUNT:
try:
(clientsocket, addr) = servsock.accept()
print("Client connected : %s" % addr[0])
thread = threading.Thread(target = client_thread, kwargs = {'sock': clientsocket, 'addr': addr})
threads.append(thread)
thread.start()
except socket.timeout:
pass
# Thread cleanup
for i in range(len(threads)-1,-1,-1):
thread = threads[i]
thread.join(0.1) #useless ?
if not thread.is_alive():
print("Thread %d exited" % i)
threads.pop(i)
# Signal handler designed to close socket when SIGINT
def sigint_sock_close(signal, frame):
if globals()['servsock'] is not None:
globals()['servsock'].close()
print("\nCtrl+c pressed, exiting...")
exit(0)
if __name__ == '__main__':
signal.signal(signal.SIGINT, sigint_sock_close)
try:
main()
except Exception as e:
if globals()['servsock'] is not None:
globals()['servsock'].close()
raise e

View file

@ -0,0 +1,22 @@
#-*- coding: utf-8 -*-
import sys
import code
from loader import *
from Lodel import logger
from Lodel.user import UserContext
logger.remove_console_handlers()
if __name__ == '__main__':
if len(sys.argv) < 2:
raise RuntimeError("Usage : %s client_ip")
UserContext.init(sys.argv[1])
print("""
netipy interface of Lodel2 %s instance environment.
Welcome %s.
To authenticate use UserContext.authenticate(identifier, proof) function
""" % (Settings.sitename, UserContext.identity().username))
code.interact(local=locals())

View file

@ -0,0 +1 @@
{% extends "templates/base.html" %}

View file

@ -0,0 +1 @@
{% extends "templates/base_backend.html" %}

91
em_editor/utils.py Executable file
View file

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
from loader import *
import warnings
def refreshdyn():
import sys
from EditorialModel.model import Model
from leapi.lefactory import LeFactory
from EditorialModel.backend.json_backend import EmBackendJson
from DataSource.MySQL.leapidatasource import LeDataSourceSQL
OUTPUT = Settings.dynamic_code_file
EMJSON = Settings.em_file
# Load editorial model
em = Model(EmBackendJson(EMJSON))
# Generate dynamic code
fact = LeFactory(OUTPUT)
# Create the python file
fact.create_pyfile(em, LeDataSourceSQL, {})
def db_init():
from EditorialModel.backend.json_backend import EmBackendJson
from EditorialModel.model import Model
mh = getattr(migrationhandler,Settings.mh_classname)()
em = Model(EmBackendJson(Settings.em_file))
em.migrate_handler(mh)
def em_graph(output_file = None, image_format = None):
from EditorialModel.model import Model
from EditorialModel.backend.json_backend import EmBackendJson
from EditorialModel.backend.graphviz import EmBackendGraphviz
import subprocess
if image_format is None:
if hasattr(Settings, 'em_graph_format'):
image_format = Settings.em_graph_format
else:
image_format = 'png'
if output_file is None:
if hasattr(Settings, 'em_graph_output'):
output_file = Settings.em_graph_output
else:
output_file = '/tmp/em_%s_graph.dot'
image_format = image_format.lower()
try:
output_file = output_file%Settings.sitename
except TypeError:
warnings.warn("Bad filename for em_graph output. The filename should be in the form '/foo/bar/file_%s_name.png")
pass
dot_file = output_file+".dot"
graphviz_bckend = EmBackendGraphviz(dot_file)
edmod = Model(EmBackendJson(Settings.em_file))
graphviz_bckend.save(edmod)
dot_cmd = [
"dot",
"-T%s"%image_format,
dot_file
]
with open(output_file, "w+") as outfp:
subprocess.check_call(dot_cmd, stdout=outfp)
os.unlink(dot_file)
print("Output image written in file : '%s'" % output_file)
def dir_init():
import os
# Templates
print("Creating Base Templates ...")
templates = {
'base': {'file': 'base.html', 'content': '{% extends "templates/base.html" %}'},
'base_backend': {'file': 'base_backend.html', 'content': '{% extends "templates/base_backend.html" %}'}
}
current_directory = os.path.dirname(os.path.abspath(__file__))
templates_directory = os.path.join(current_directory,'templates')
if not os.path.exists(templates_directory):
os.makedirs(templates_directory)
for _, template in templates.items():
my_file_path = os.path.join(templates_directory, template['file'])
if os.path.exists(my_file_path):
os.unlink(my_file_path)
with open(my_file_path, 'w') as my_file:
my_file.write(template['content'])
print("Created %s" % my_file_path)