Browse Source

New picklediff datasource and "Seems to work" version of em_editor.

But really not debuged and without tests on the new datasource
Yann Weber 9 years ago
parent
commit
41b3d82dd9

+ 171
- 0
DataSource/picklediff/leapidatasource.py View File

@@ -0,0 +1,171 @@
1
+#-*- coding: utf-8 -*-
2
+
3
+import os, os.path
4
+import pickle
5
+import re
6
+from collections import OrderedDict
7
+from Lodel import logger
8
+
9
+from Lodel.settings import Settings
10
+
11
+## @brief Datasource designed to stores datas and datas diff in pickle files
12
+# 
13
+# @note designed to handle editorial model storage
14
+#
15
+# Datas organisation :
16
+#
17
+# - editorial_model :
18
+#  - components : dict with lodel_id as key and datas dict as value
19
+#   - datas : dict with field name as key and field value as value
20
+#  - class_link : dict with leo class as key and sets of lodel_id as value
21
+# - states : dict with editorial_model state hash as key and modifications_datas dict as value
22
+#  - modifications_datas : dict with action key and arguements for actions (example : { 'action': 'insert', 'target_class': EmClass, 'datas': dict() }
23
+#
24
+class LeapiDataSource(object):
25
+    
26
+    def __init__(self, filename = None):
27
+        if filename is None:
28
+            filename = Settings.datasource['default']['filename']
29
+        self.__filename = filename
30
+        self.__content = None
31
+        self.__load_file()
32
+        
33
+    def select(self, target_cls, field_list, filters, rel_filters = None, order = None, group = None, limit = None, offset = 0, instanciate = True):
34
+        if not target_cls.is_leobject() and target_cls.__class__ != target_cls.name2class('Lerelation'):
35
+            if target_cls.__name__ not in self.__content['editorial_model']['class_link'] or len(self.__content['editorial_model']['class_link'][target_cls.__name__]) == 0:
36
+                return []
37
+            lodel_ids = list(self.__content['editorial_model']['class_link'][target_cls.__name__])
38
+        else:
39
+            lodel_ids = list(self.__content['editorial_model']['components'].keys())
40
+            
41
+        for field, cmp_op, value in filters:
42
+            if cmp_op.endswith('like '): # *like case
43
+                value.replace('%', '.*')
44
+                tmp_ids = []
45
+                for lodel_id in lodel_ids:
46
+                    match = re.match(value, self.__field_value(lodel_id, field))
47
+                    if (cmp_op == ' like ' and match) or (cmp_op == ' not like ' and not match):
48
+                        tmp_ids.append(lodel_ids)
49
+                    elif cmp_op == ' in ':
50
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) in value]
51
+                    elif cmp_op == ' not in ':
52
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) not in value]
53
+                    elif cmp_op == '=':
54
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) == value]
55
+                    elif cmp_op == '<=':
56
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) <= value]
57
+                    elif cmp_op == '>=':
58
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) <= value]
59
+                    elif cmp_op == '!=':
60
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) != value]
61
+                    elif cmp_op == '<':
62
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) < value]
63
+                    elif cmp_op == '>':
64
+                        lodel_ids = [ lid for lid in lodel_ids if self.__field_value(lodel_id, field) < value]
65
+        # Now we got filtered lodel_id list in lodel_ids
66
+        result = []
67
+        for datas in [ self.__content['editorial_model']['components'][lodel_id] for lodel_id in lodel_ids ]:
68
+            comp_class = target_cls.name2class(datas['__component_leapi_class__'])
69
+            del(datas['__component_leapi_class__'])
70
+
71
+            if instanciate:
72
+                # Don't care about field_list... maybe it's not a good idea ?
73
+                result.append(comp_class(**datas))
74
+            else:
75
+                result.append({ fname: datas[fname] for fname in field_list })
76
+        return result
77
+            
78
+
79
+    def delete(self, target_cls, leo_id):
80
+        if leo_id not in self.__content['editorial_model']['class_link'][target_cls.__name__]:
81
+            raise AttributeError("No %s with id %d" % (target_cls.__name__, leo_id))
82
+        self.__content['editorial_model']['class_link'][target_cls.__name__] -= set([leo_id])
83
+        self.__content['editorial_model']['class_link'][target_cls.leclass.__name__] -= set([leo_id])
84
+        del(self.__content['editorial_model']['components'][leo_id])
85
+        self.__register_modification('delete', {'target_cls': target_cls, 'leo_id': leo_id})
86
+
87
+    def update(self, target_cls, leo_id, **datas):
88
+        if leo_id not in self.__content['editorial_model']['class_link'][target_cls.__name__]:
89
+            raise AttributeError("No %s with id %d" % (target_cls.__name__, leo_id))
90
+        for key, value in datas.items():
91
+            self.__content['editorial_model']['components'][leo_id][key] = value #no checks, leapi should have checked before...
92
+        self.__register_modification('update', {'target_cls': target_cls, 'leo_id': leo_id, 'datas': datas})
93
+        pass
94
+
95
+    def insert(self, target_cls, **datas):
96
+        new_id = self.__new_id()
97
+        datas[self.__id_name(target_cls)] = new_id
98
+        # Adding target_cls to datas
99
+        datas['__component_leapi_class__'] = target_cls.__name__
100
+        # Adding the component to component list
101
+        self.__content['editorial_model']['components'][new_id] = datas
102
+        # Creating class_link type entry
103
+        if target_cls.__name__ not in self.__content['editorial_model']['class_link']:
104
+            self.__content['editorial_model']['class_link'][target_cls.__name__] = set()
105
+        self.__content['editorial_model']['class_link'][target_cls.__name__] |= set([new_id])
106
+        # Creating class_link class entry
107
+        if target_cls._leclass.__name__ not in self.__content['editorial_model']['class_link']:
108
+            self.__content['editorial_model']['class_link'][target_cls._leclass.__name__] = set()
109
+        self.__content['editorial_model']['class_link'][target_cls._leclass.__name__] |= set([new_id])
110
+
111
+        self.__register_modification('insert', {'target_cls': target_cls, 'datas': datas})
112
+        return new_id
113
+
114
+    def insert_multi(self, target_cls, datas_list):
115
+        pass
116
+
117
+    def update_rank(self, le_relation, new_rank):
118
+        pass
119
+
120
+    def __id_name(self, target_cls):
121
+        return 'lodel_id' if target_cls.implements_leobject() else 'relation_id'
122
+
123
+    def __new_id(self):
124
+        # Find a new component id avoiding 'id holes'
125
+        lodel_id = 1
126
+        while lodel_id in self.__content['editorial_model']['components'].keys():
127
+            lodel_id += 1
128
+        return lodel_id
129
+
130
+    ## @brief Save memory repr of em into pickle file
131
+    def __save(self):
132
+        with open(self.__filename, 'wb') as ffd:
133
+            pickle.dump(self.__content, ffd)
134
+    
135
+    ## @brief Loads self.__content from self.__filename
136
+    def __load_file(self):
137
+        if not os.path.isfile(self.__filename):
138
+            logger.debug("File %s not found !" % self.__filename)
139
+            self.__content = dict()
140
+        else:
141
+            with open(self.__filename, 'rb') as ffd:
142
+                self.__content = pickle.load(ffd)
143
+        # dict initialisation
144
+        if self.__content is None:
145
+            self.__content = dict()
146
+        else:
147
+            logger.debug("Loaded : \n %s" % self.__content)
148
+        if 'editorial_model' not in self.__content:
149
+            self.__content['editorial_model'] = OrderedDict()
150
+        if 'components' not in self.__content['editorial_model']:
151
+            self.__content['editorial_model']['components'] = OrderedDict()
152
+        if 'class_link' not in self.__content['editorial_model']:
153
+            self.__content['editorial_model']['class_link'] = OrderedDict()
154
+        if 'states' not in self.__content:
155
+            self.__content['states'] = OrderedDict()
156
+
157
+    ## @brief Method that register a EM modification
158
+    # @warning this method MUST be called once the modification is made in the __content dict
159
+    # 
160
+    # @param action str : name of modification (update, delete or insert)
161
+    # @param kwargs dict : action arguments
162
+    def __register_modification(self, action, kwargs):
163
+        logger.debug("Registered a modification : action = %s kwargs = %s" % (action, kwargs))
164
+        em_hash = hash(pickle.dumps(self.__content['editorial_model']))
165
+        self.__content['states'][em_hash] = (action, kwargs)
166
+        self.__save()
167
+
168
+    ## @brief Given a lodel_id and a field name return the field value
169
+    # @return the field value of designated LeObject
170
+    def __field_value(self, lodel_id, field_name):
171
+        return self.__content['editorial_model']['components'][lodel_id][field_name]

+ 11
- 0
DataSource/picklediff/migrationhandler.py View File

@@ -0,0 +1,11 @@
1
+#-*- coding: utf-8 -*-
2
+
3
+from DataSource.dummy.migrationhandler import MigrationHandler
4
+
5
+class MigrationHandler(MigrationHandler):
6
+
7
+    def __init__(self, debug=False): pass
8
+
9
+    def register_change(self, em, uid, initial_state, new_state): pass
10
+
11
+    def register_model_state(self, em, state_hash): pass

+ 22
- 0
DataSource/utils.py View File

@@ -0,0 +1,22 @@
1
+#-*- coding:utf-8 -*-
2
+
3
+import importlib
4
+from Lodel.settings import Settings
5
+
6
+def get_datasource_cls():
7
+    module = importlib.import_module("DataSource.{pkg_name}.leapidatasource".format(
8
+        pkg_name = Settings.ds_package,
9
+    ))
10
+    return getattr(module, 'LeapiDataSource')
11
+
12
+def get_datasource_instance():
13
+    return get_datasource_cls(Settings.datasource_options)
14
+
15
+def get_migrationhandler_cls():
16
+    module = importlib.import_module("DataSource.{pkg_name}.migrationhandler".format(
17
+        pkg_name = Settings.ds_package,
18
+    ))
19
+    return getattr(module, 'MigrationHandler')
20
+
21
+def get_migrationhandler_instance():
22
+    return get_migrationhandler_cls()(**Settings.migrationhandler_options)

+ 10
- 0
EditorialModel/fieldtypes/datetime.py View File

@@ -2,6 +2,7 @@
2 2
 
3 3
 from .generic import SingleValueFieldType
4 4
 
5
+import datetime
5 6
 
6 7
 class EmFieldType(SingleValueFieldType):
7 8
 
@@ -15,3 +16,12 @@ class EmFieldType(SingleValueFieldType):
15 16
         self.now_on_update = now_on_update
16 17
         self.now_on_create = now_on_create
17 18
         super(EmFieldType, self).__init__(**kwargs)
19
+
20
+    def construct_data(self, lec, fname, datas, cur_value):
21
+        if self.now_on_update:
22
+            return datetime.datetime.now()
23
+        elif cur_value is None:
24
+            if self.now_on_create:
25
+                return datetime.datetime.now()
26
+        return super().construct_data(self, lec, fname, datas, cur_value)
27
+            

+ 2
- 0
Lodel/utils/mlstring.py View File

@@ -77,6 +77,8 @@ class MlString(object):
77 77
     ## @brief Equivalent to json_dumps
78 78
     def dumps(self): return self.json_dumps()
79 79
 
80
+    def to_JSON(self): return self.json_dumps()
81
+
80 82
     ## Test if two MlString instance are equivalent
81 83
     # @param other MlString|str : Another MlString instance or a string (json formated)
82 84
     # @return True or False

+ 106
- 77
em_editor/dynleapi.py View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 import EditorialModel
4 4
 from EditorialModel import fieldtypes
5
-from EditorialModel.fieldtypes import naturerelation, leo, datetime, dictionary, rank, namerelation, pk, bool, i18n, char, integer, emuid
5
+from EditorialModel.fieldtypes import pk, dictionary, integer, leo, rank, bool, char, emuid, datetime, namerelation, naturerelation, i18n
6 6
 from Lodel.utils.mlstring import MlString
7 7
 
8 8
 import leapi
@@ -12,27 +12,23 @@ import leapi.lerelation
12 12
 from leapi.leclass import _LeClass
13 13
 from leapi.letype import _LeType
14 14
 
15
-import DataSource.MySQL.leapidatasource
16
-
17
-
18 15
 ## @brief _LeCrud concret class
19 16
 # @see leapi.lecrud._LeCrud
20 17
 class LeCrud(leapi.lecrud._LeCrud):
21
-    _datasource = DataSource.MySQL.leapidatasource.LeDataSourceSQL(**{})
22 18
     _uid_fieldtype = None
23 19
 
24 20
 ## @brief _LeObject concret class
25 21
 # @see leapi.leobject._LeObject
26 22
 class LeObject(LeCrud, leapi.leobject._LeObject):
27
-    _me_uid = {32: 'Emclass', 33: 'Emtype', 34: 'Emfield', 22: 'Emcomponent', 1: '_Editorialmodel', 8: '_Classtype', 15: '_Hierarchy', 29: 'Classtype', 30: 'Hierarchyoptions', 31: 'Editorialmodel'}
23
+    _me_uid = {1: '_Editorialmodel', 36: 'Classtype', 37: 'Hierarchyoptions', 38: 'Editorialmodel', 39: 'Emclass', 40: 'Emtype', 41: 'Emfield', 42: 'Emmodification', 15: '_Hierarchy', 8: '_Classtype', 22: 'Emcomponent', 29: '_Emmodification'}
28 24
     _me_uid_field_names = ('class_id', 'type_id')
29
-    _uid_fieldtype = { 'lodel_id': EditorialModel.fieldtypes.pk.EmFieldType(**{'uniq': False, 'nullable': False, 'immutable': True, 'internal': 'autosql', 'string': '{"___": "", "fre": "identifiant lodel", "eng": "lodel identifier"}'}) }
25
+    _uid_fieldtype = { 'lodel_id': EditorialModel.fieldtypes.pk.EmFieldType(**{'immutable': True, 'string': '{"___": "", "fre": "identifiant lodel", "eng": "lodel identifier"}', 'nullable': False, 'uniq': False, 'internal': 'autosql'}) }
30 26
     _leo_fieldtypes = {
31
-	'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}),
32
-	'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}),
33
-	'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"}'}),
27
+	'class_id': EditorialModel.fieldtypes.emuid.EmFieldType(**{'immutable': True, 'is_id_class': True, 'string': '{"___": "", "fre": "identifiant de la classe", "eng": "class identifier"}', 'nullable': False, 'uniq': False, 'internal': 'automatic'}),
28
+	'type_id': EditorialModel.fieldtypes.emuid.EmFieldType(**{'immutable': True, 'is_id_class': False, 'string': '{"___": "", "fre": "identifiant de la type", "eng": "type identifier"}', 'nullable': False, 'uniq': False, 'internal': 'automatic'}),
34 29
 	'string': None,
35
-	'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"}'})
30
+	'creation_date': EditorialModel.fieldtypes.datetime.EmFieldType(**{'immutable': True, 'string': '{"___": "", "fre": "Date de création", "eng": "Creation date"}', 'now_on_create': True, 'nullable': False, 'uniq': False, 'internal': 'autosql'}),
31
+	'modification_date': EditorialModel.fieldtypes.datetime.EmFieldType(**{'immutable': True, 'string': '{"___": "", "fre": "Date de modification", "eng": "Modification date"}', 'now_on_create': True, 'nullable': False, 'uniq': False, 'internal': 'autosql', 'now_on_update': True})
36 32
 	}
37 33
 
38 34
 ## @brief _LeRelation concret class
@@ -40,12 +36,12 @@ class LeObject(LeCrud, leapi.leobject._LeObject):
40 36
 class LeRelation(LeCrud, leapi.lerelation._LeRelation):
41 37
     _uid_fieldtype = { 'id_relation': EditorialModel.fieldtypes.pk.EmFieldType(**{'immutable': True, 'internal': 'autosql'}) }
42 38
     _rel_fieldtypes = {
43
-	'relation_name': EditorialModel.fieldtypes.namerelation.EmFieldType(**{'max_length': 128, 'immutable': True}),
44
-	'nature': EditorialModel.fieldtypes.naturerelation.EmFieldType(**{'immutable': True}),
45
-	'superior': EditorialModel.fieldtypes.leo.EmFieldType(**{'immutable': True, 'superior': True}),
46 39
 	'depth': EditorialModel.fieldtypes.integer.EmFieldType(**{'immutable': True, 'internal': 'automatic'}),
40
+	'subordinate': EditorialModel.fieldtypes.leo.EmFieldType(**{'immutable': True, 'superior': False}),
41
+	'superior': EditorialModel.fieldtypes.leo.EmFieldType(**{'immutable': True, 'superior': True}),
42
+	'relation_name': EditorialModel.fieldtypes.namerelation.EmFieldType(**{'immutable': True, 'max_length': 128}),
47 43
 	'rank': EditorialModel.fieldtypes.rank.EmFieldType(**{'immutable': True, 'internal': 'automatic'}),
48
-	'subordinate': EditorialModel.fieldtypes.leo.EmFieldType(**{'immutable': True, 'superior': False})
44
+	'nature': EditorialModel.fieldtypes.naturerelation.EmFieldType(**{'immutable': True})
49 45
 	}
50 46
     ## WARNING !!!! OBSOLETE ! DON'T USE IT
51 47
     _superior_field_name = 'superior'
@@ -92,51 +88,65 @@ class Emcomponent(LeClass, LeObject):
92 88
     ml_string = MlString('EmComponent')
93 89
 
94 90
 
91
+## @brief EmClass _Emmodification LeClass child class
92
+# @see leapi.leclass.LeClass
93
+class _Emmodification(LeClass, LeObject):
94
+    _class_id = 29
95
+    ml_string = MlString('_EmModification')
96
+
97
+
95 98
 ## @brief EmType Classtype LeType child class
96 99
 # @see leobject::letype::LeType
97 100
 class Classtype(LeType, _Classtype):
98
-    _type_id = 29
101
+    _type_id = 36
99 102
     ml_string = MlString('ClassType')
100 103
 
101 104
 
102 105
 ## @brief EmType Hierarchyoptions LeType child class
103 106
 # @see leobject::letype::LeType
104 107
 class Hierarchyoptions(LeType, _Hierarchy):
105
-    _type_id = 30
108
+    _type_id = 37
106 109
     ml_string = MlString('HierarchyOptions')
107 110
 
108 111
 
109 112
 ## @brief EmType Editorialmodel LeType child class
110 113
 # @see leobject::letype::LeType
111 114
 class Editorialmodel(LeType, _Editorialmodel):
112
-    _type_id = 31
115
+    _type_id = 38
113 116
     ml_string = MlString('EditorialModel')
114 117
 
115 118
 
116 119
 ## @brief EmType Emclass LeType child class
117 120
 # @see leobject::letype::LeType
118 121
 class Emclass(LeType, Emcomponent):
119
-    _type_id = 32
122
+    _type_id = 39
120 123
     ml_string = MlString('EmClass')
121 124
 
122 125
 
126
+## @brief EmType Emmodification LeType child class
127
+# @see leobject::letype::LeType
128
+class Emmodification(LeType, _Emmodification):
129
+    _type_id = 42
130
+    ml_string = MlString('EmModification')
131
+
132
+
123 133
 ## @brief EmType Emtype LeType child class
124 134
 # @see leobject::letype::LeType
125 135
 class Emtype(LeType, Emcomponent):
126
-    _type_id = 33
136
+    _type_id = 40
127 137
     ml_string = MlString('EmType')
128 138
 
129 139
 
130 140
 ## @brief EmType Emfield LeType child class
131 141
 # @see leobject::letype::LeType
132 142
 class Emfield(LeType, Emcomponent):
133
-    _type_id = 34
143
+    _type_id = 41
134 144
     ml_string = MlString('EmField')
135 145
 
136 146
 
137 147
 class Rel_ClasstypeHierarchyoptionsHierarchy_Specs(LeRel2Type):
138 148
     _rel_attr_fieldtypes = {
139
-    'nature': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 10, 'uniq': False, 'nullable': False})
149
+    'nature': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 10, 'internal': False})
140 150
 }
141 151
     _superior_cls = _Classtype
142 152
     _subordinate_cls = Hierarchyoptions
@@ -177,7 +187,7 @@ class RelEmcomponentEmfieldSelected_Field(LeRel2Type):
177 187
 
178 188
 class RelEmcomponentEmtypeSuperiors(LeRel2Type):
179 189
     _rel_attr_fieldtypes = {
180
-    'nature': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': '10', 'uniq': False, 'nullable': False})
190
+    'nature': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 10, 'internal': False})
181 191
 }
182 192
     _superior_cls = Emcomponent
183 193
     _subordinate_cls = Emtype
@@ -194,19 +204,19 @@ class RelEmcomponentEmfieldRel_Field(LeRel2Type):
194 204
 
195 205
 #Initialisation of _Editorialmodel class attributes
196 206
 _Editorialmodel._fieldtypes = {
197
-    'description': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 4096, 'uniq': False, 'nullable': False}),
198
-    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
199
-    'name': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 56, 'uniq': False, 'nullable': False})
207
+    'description': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 4096, 'internal': False}),
208
+    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'immutable': False, 'nullable': True, 'max_length': 128, 'internal': 'automatic', 'uniq': False}),
209
+    'name': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 56, 'internal': False})
200 210
 }
201 211
 _Editorialmodel.ml_fields_strings = {
202 212
    'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
203 213
    'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
204
-   'name': MlString({"___": "name"}),
205
-   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
206
-   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
207 214
    'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
208 215
    'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
209
-   'description': MlString({"___": "description"})
216
+   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
217
+   'name': MlString({"___": "name"}),
218
+   'description': MlString({"___": "description"}),
219
+   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"})
210 220
 }
211 221
 _Editorialmodel._linked_types = {
212 222
 }
@@ -214,19 +224,19 @@ _Editorialmodel._classtype = 'entity'
214 224
 
215 225
 #Initialisation of _Classtype class attributes
216 226
 _Classtype._fieldtypes = {
217
-    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
218
-    'name': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 56, 'uniq': False, 'nullable': False})
227
+    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'immutable': False, 'nullable': True, 'max_length': 128, 'internal': 'automatic', 'uniq': False}),
228
+    'name': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 56, 'internal': False})
219 229
 }
220 230
 _Classtype.ml_fields_strings = {
221 231
    'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
232
+   'hierarchy_specs': MlString({"___": "hierarchy_specs"}),
233
+   'nature': MlString({"___": "nature"}),
222 234
    'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
223
-   'name': MlString({"___": "name"}),
224
-   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
225
-   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
226 235
    'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
227 236
    'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
228
-   'hierarchy_specs': MlString({"___": "hierarchy_specs"}),
229
-   'nature': MlString({"___": "nature"})
237
+   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
238
+   'name': MlString({"___": "name"}),
239
+   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"})
230 240
 }
231 241
 _Classtype._linked_types = {
232 242
     'hierarchy_specs': Hierarchyoptions
@@ -235,23 +245,23 @@ _Classtype._classtype = 'entity'
235 245
 
236 246
 #Initialisation of _Hierarchy class attributes
237 247
 _Hierarchy._fieldtypes = {
238
-    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
239
-    'attach': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 10, 'uniq': False, 'nullable': False}),
240
-    'maxdepth': EditorialModel.fieldtypes.integer.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
241
-    'maxchildren': EditorialModel.fieldtypes.integer.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
242
-    'automatic': EditorialModel.fieldtypes.bool.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False})
248
+    'automatic': EditorialModel.fieldtypes.bool.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': False}),
249
+    'maxchildren': EditorialModel.fieldtypes.integer.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': False}),
250
+    'maxdepth': EditorialModel.fieldtypes.integer.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': False}),
251
+    'attach': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 10, 'internal': False}),
252
+    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'immutable': False, 'nullable': True, 'max_length': 128, 'internal': 'automatic', 'uniq': False})
243 253
 }
244 254
 _Hierarchy.ml_fields_strings = {
245
-   'maxchildren': MlString({"___": "maxchildren"}),
246 255
    'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
247
-   'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
248
-   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
249
-   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
250 256
    'automatic': MlString({"___": "automatic"}),
257
+   'maxdepth': MlString({"___": "maxdepth"}),
258
+   'maxchildren': MlString({"___": "maxchildren"}),
259
+   'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
251 260
    'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
252 261
    'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
262
+   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
253 263
    'attach': MlString({"___": "attach"}),
254
-   'maxdepth': MlString({"___": "maxdepth"})
264
+   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"})
255 265
 }
256 266
 _Hierarchy._linked_types = {
257 267
 }
@@ -259,47 +269,61 @@ _Hierarchy._classtype = 'entity'
259 269
 
260 270
 #Initialisation of Emcomponent class attributes
261 271
 Emcomponent._fieldtypes = {
262
-    'fieldtype': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
263
-    'name': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': False, 'max_length': 56, 'uniq': False, 'nullable': False}),
264
-    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'internal': 'automatic', 'max_length': 128, 'immutable': False, 'uniq': False, 'nullable': True}),
265
-    'help_text': EditorialModel.fieldtypes.i18n.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
266
-    'fieldtype_options': EditorialModel.fieldtypes.dictionary.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False}),
267
-    'date_update': EditorialModel.fieldtypes.datetime.EmFieldType(**{'now_on_update': True, 'nullable': False, 'uniq': False, 'internal': False}),
268
-    'date_create': EditorialModel.fieldtypes.datetime.EmFieldType(**{'now_on_create': True, 'internal': False, 'uniq': False, 'nullable': False}),
269
-    'rank': EditorialModel.fieldtypes.integer.EmFieldType(**{'internal': False, 'uniq': False, 'nullable': False})
272
+    'date_update': EditorialModel.fieldtypes.datetime.EmFieldType(**{'now_on_update': True, 'nullable': False, 'uniq': False, 'internal': 'automatic'}),
273
+    'fieldtype': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': False}),
274
+    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'immutable': False, 'nullable': True, 'max_length': 128, 'internal': 'automatic', 'uniq': False}),
275
+    'name': EditorialModel.fieldtypes.char.EmFieldType(**{'uniq': False, 'nullable': False, 'max_length': 56, 'internal': False}),
276
+    'help_text': EditorialModel.fieldtypes.i18n.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': False, 'default': {'en': 'no help'}}),
277
+    'fieldtype_options': EditorialModel.fieldtypes.dictionary.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': False}),
278
+    'date_create': EditorialModel.fieldtypes.datetime.EmFieldType(**{'uniq': False, 'nullable': False, 'internal': 'automatic', 'now_on_create': True})
270 279
 }
271 280
 Emcomponent.ml_fields_strings = {
272
-   'superiors': MlString({"___": "superiors"}),
273
-   'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
274
-   'name': MlString({"___": "name"}),
275
-   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
276
-   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
277
-   'parent_class': MlString({"___": "parent_class"}),
278
-   'fieldtype_options': MlString({"___": "fieldtype_options"}),
279
-   'help_text': MlString({"___": "help_text"}),
280
-   'rank': MlString({"___": "rank"}),
281
-   'sort_column': MlString({"___": "sort_column"}),
282
-   'fieldtype': MlString({"___": "fieldtype"}),
283 281
    'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
284
-   'selected_field': MlString({"___": "selected_field"}),
282
+   'classtype': MlString({"___": "classtype"}),
285 283
    'rel_field': MlString({"___": "rel_field"}),
284
+   'superiors': MlString({"___": "superiors"}),
286 285
    'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
287 286
    'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
288
-   'classtype': MlString({"___": "classtype"}),
287
+   'fieldtype': MlString({"___": "fieldtype"}),
288
+   'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
289
+   'selected_field': MlString({"___": "selected_field"}),
290
+   'fieldtype_options': MlString({"___": "fieldtype_options"}),
289 291
    'date_create': MlString({"___": "date_create"}),
290
-   'nature': MlString({"___": "nature"}),
291
-   'date_update': MlString({"___": "date_update"})
292
+   'date_update': MlString({"___": "date_update"}),
293
+   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"}),
294
+   'name': MlString({"___": "name"}),
295
+   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
296
+   'sort_column': MlString({"___": "sort_column"}),
297
+   'help_text': MlString({"___": "help_text"}),
298
+   'parent_class': MlString({"___": "parent_class"}),
299
+   'nature': MlString({"___": "nature"})
292 300
 }
293 301
 Emcomponent._linked_types = {
302
+    'classtype': Classtype,
294 303
     'superiors': Emtype,
295 304
     'rel_field': Emfield,
296
-    'classtype': Classtype,
297
-    'parent_class': Emclass,
298 305
     'sort_column': Emfield,
299
-    'selected_field': Emfield
306
+    'selected_field': Emfield,
307
+    'parent_class': Emclass
300 308
 }
301 309
 Emcomponent._classtype = 'entity'
302 310
 
311
+#Initialisation of _Emmodification class attributes
312
+_Emmodification._fieldtypes = {
313
+    'string': EditorialModel.fieldtypes.char.EmFieldType(**{'immutable': False, 'nullable': True, 'max_length': 128, 'internal': 'automatic', 'uniq': False})
314
+}
315
+_Emmodification.ml_fields_strings = {
316
+   'class_id': MlString({"___": "class_id", "eng": "class identifier", "fre": "identifiant de la classe"}),
317
+   'type_id': MlString({"___": "type_id", "eng": "type identifier", "fre": "identifiant de la type"}),
318
+   'string': MlString({"___": "string", "eng": "String representation", "fre": "Repr\u00e9sentation textuel"}),
319
+   'creation_date': MlString({"___": "creation_date", "eng": "Creation date", "fre": "Date de cr\u00e9ation"}),
320
+   'lodel_id': MlString({"___": "lodel_id", "eng": "lodel identifier", "fre": "identifiant lodel"}),
321
+   'modification_date': MlString({"___": "modification_date", "eng": "Modification date", "fre": "Date de modification"})
322
+}
323
+_Emmodification._linked_types = {
324
+}
325
+_Emmodification._classtype = 'entity'
326
+
303 327
 #Initialisation of Classtype class attributes
304 328
 Classtype._fields = ['name']
305 329
 Classtype._superiors = {}
@@ -316,19 +340,24 @@ Editorialmodel._superiors = {}
316 340
 Editorialmodel._leclass = _Editorialmodel
317 341
 
318 342
 #Initialisation of Emclass class attributes
319
-Emclass._fields = ['name', 'help_text', 'date_update', 'date_create', 'rank']
343
+Emclass._fields = ['name', 'help_text', 'date_update', 'date_create']
320 344
 Emclass._superiors = {'parent': [Editorialmodel]}
321 345
 Emclass._leclass = Emcomponent
322 346
 
347
+#Initialisation of Emmodification class attributes
348
+Emmodification._fields = []
349
+Emmodification._superiors = {}
350
+Emmodification._leclass = _Emmodification
351
+
323 352
 #Initialisation of Emtype class attributes
324
-Emtype._fields = ['name', 'help_text', 'date_update', 'date_create', 'rank']
353
+Emtype._fields = ['name', 'help_text', 'date_update', 'date_create']
325 354
 Emtype._superiors = {'parent': [Emclass]}
326 355
 Emtype._leclass = Emcomponent
327 356
 
328 357
 #Initialisation of Emfield class attributes
329
-Emfield._fields = ['name', 'help_text', 'date_update', 'date_create', 'rank', 'fieldtype', 'fieldtype_options']
358
+Emfield._fields = ['name', 'help_text', 'date_update', 'date_create', 'fieldtype', 'fieldtype_options']
330 359
 Emfield._superiors = {'parent': [Emtype]}
331 360
 Emfield._leclass = Emcomponent
332 361
 
333 362
 ## @brief Dict for getting LeClass and LeType child classes given an EM uid
334
-LeObject._me_uid = {32: Emclass, 1: _Editorialmodel, 34: Emfield, 22: Emcomponent, 33: Emtype, 8: _Classtype, 31: Editorialmodel, 29: Classtype, 30: Hierarchyoptions, 15: _Hierarchy}
363
+LeObject._me_uid = {1: _Editorialmodel, 36: Classtype, 37: Hierarchyoptions, 38: Editorialmodel, 39: Emclass, 40: Emtype, 41: Emfield, 42: Emmodification, 15: _Hierarchy, 8: _Classtype, 22: Emcomponent, 29: _Emmodification}

+ 790
- 664
em_editor/em.json
File diff suppressed because it is too large
View File


+ 10
- 4
em_editor/init_em.py View File

@@ -31,6 +31,8 @@ class_em = em.add_class('_EditorialModel', classtype = 'entity')
31 31
 class_ctype = em.add_class('_ClassType', classtype='entity')
32 32
 class_ctype_h = em.add_class('_Hierarchy', classtype='entity')
33 33
 class_comp = em.add_class('EmComponent', classtype='entity')
34
+
35
+class_emmod = em.add_class('_EmModification', classtype='entity')
34 36
 #       class_ftype = em.add_class('_FieldType', classtype = 'entity')
35 37
 
36 38
 #       type_ftype = em.add_type('FieldType', class_ftype)
@@ -42,10 +44,14 @@ type_class = em.add_type('EmClass', class_comp, superiors_list = {'parent': [typ
42 44
 type_type = em.add_type('EmType', class_comp, superiors_list = {'parent':[type_class.uid]})
43 45
 type_field = em.add_type('EmField', class_comp, superiors_list = {'parent':[type_type.uid]})
44 46
 
47
+
48
+type_emmod = em.add_type('EmModification', class_emmod)
45 49
 #        FieldType common fields
46 50
 #       em.add_field('name', class_ftype, fieldtype = 'char', max_length = 56)
47 51
 #       em.add_field('max_length', class_ftype, optional = True, fieldtype = 'integer')
48 52
 
53
+# EditorialModel modification fields
54
+
49 55
 # EditorialModel common fields
50 56
 em.add_field('name', class_em, fieldtype = 'char', max_length = 56)
51 57
 em.add_field('description', class_em, fieldtype = 'char', max_length = 4096)
@@ -64,10 +70,10 @@ em.add_field('nature', class_ctype, fieldtype = 'char', max_length = 10, rel_fie
64 70
 # EmComponent common fields
65 71
 em.add_field('name', class_comp, fieldtype = 'char', max_length = 56)
66 72
 # Part of default fields #em.add_field('string', class_comp, fieldtype = 'i18n')
67
-em.add_field('help_text', class_comp, fieldtype = 'i18n')
68
-em.add_field('date_update', class_comp, fieldtype = 'datetime', now_on_update = True)
69
-em.add_field('date_create', class_comp, fieldtype = 'datetime', now_on_create = True)
70
-em.add_field('rank', class_comp, fieldtype = 'integer')
73
+em.add_field('help_text', class_comp, fieldtype = 'i18n', default={'en':'no help'})
74
+em.add_field('date_update', class_comp, fieldtype = 'datetime', now_on_update = True, internal='automatic')
75
+em.add_field('date_create', class_comp, fieldtype = 'datetime', now_on_create = True, internal='automatic')
76
+#em.add_field('rank', class_comp, fieldtype = 'rank', internal='automatic')
71 77
 # EmComponent optional fields
72 78
 field_ctype = em.add_field('classtype', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_ctype.uid)
73 79
 field_sortcol = em.add_field('sort_column', class_comp, optional = True, fieldtype = 'rel2type', rel_to_type_id = type_field.uid)

+ 4
- 11
em_editor/instance_settings.py View File

@@ -10,17 +10,10 @@ templates_base_dir = 'LODEL2_INSTANCE_TEMPLATES_BASE_DIR'
10 10
 
11 11
 debug = False
12 12
 
13
-em_file = 'em.json'
13
+em_file = 'em.pickle'
14 14
 dynamic_code_file = 'dynleapi.py'
15 15
 
16
-ds_package = 'MySQL'
17
-mh_classname = 'MysqlMigrationHandler'
18
-datasource = {
19
-    'default': {
20
-        'module': pymysql,
21
-        'host': '127.0.0.1',
22
-        'user': 'lodel',
23
-        'passwd': 'bruno',
24
-        'db': 'lodel2tests'
25
-    }
16
+ds_package = 'picklediff'
17
+datasource_options = {
18
+    'filename': '/tmp/em_em.json',
26 19
 }

+ 3
- 3
em_editor/utils.py View File

@@ -9,7 +9,6 @@ def refreshdyn():
9 9
     from EditorialModel.model import Model
10 10
     from leapi.lefactory import LeFactory
11 11
     from EditorialModel.backend.json_backend import EmBackendJson
12
-    from DataSource.MySQL.leapidatasource import LeDataSourceSQL
13 12
     OUTPUT = Settings.dynamic_code_file
14 13
     EMJSON = Settings.em_file
15 14
     # Load editorial model
@@ -17,13 +16,14 @@ def refreshdyn():
17 16
     # Generate dynamic code
18 17
     fact = LeFactory(OUTPUT)
19 18
     # Create the python file
20
-    fact.create_pyfile(em, LeDataSourceSQL, {})
19
+    fact.create_pyfile(em)
21 20
 
22 21
 
23 22
 def db_init():
24 23
     from EditorialModel.backend.json_backend import EmBackendJson
25 24
     from EditorialModel.model import Model
26
-    mh = getattr(migrationhandler,Settings.mh_classname)()
25
+    import DataSource.utils
26
+    mh = DataSource.utils.get_migrationhandler_instance()
27 27
     em = Model(EmBackendJson(Settings.em_file))
28 28
     em.migrate_handler(mh)
29 29
 

+ 2
- 1
leapi/leclass.py View File

@@ -37,7 +37,8 @@ class _LeClass(_LeObject):
37 37
         return list(cls.fieldtypes(complete).keys())
38 38
 
39 39
     @classmethod
40
-    def get(cls, query_filters, field_list=None, order=None, group=None, limit=None, offset=0):
40
+    def get(cls, query_filters = None, field_list=None, order=None, group=None, limit=None, offset=0):
41
+        query_filters = list() if query_filters is None else query_filters
41 42
         query_filters.append(('class_id', '=', cls._class_id))
42 43
         return super().get(query_filters, field_list, order=order, group=group, limit=limit, offset=offset)
43 44
 

+ 2
- 1
leapi/lecrud.py View File

@@ -396,7 +396,8 @@ class _LeCrud(object, metaclass = _MetaLeCrud):
396 396
     # @return A list of lodel editorial components instance
397 397
     # @todo think about LeObject and LeClass instanciation (partial instanciation, etc)
398 398
     @classmethod
399
-    def get(cls, query_filters, field_list=None, order=None, group=None, limit=None, offset=0, instanciate=True):
399
+    def get(cls, query_filters = None, field_list=None, order=None, group=None, limit=None, offset=0, instanciate=True):
400
+        query_filters = list() if query_filters is None else query_filters
400 401
         kwargs = locals()
401 402
         del(kwargs['cls'])
402 403
         kwargs = LodelHook.call_hook('leapi_get_pre', cls, kwargs)

+ 2
- 1
leapi/letype.py View File

@@ -52,7 +52,8 @@ class _LeType(_LeClass):
52 52
             return list(set(cls._fields + cls.name2class('LeObject').fieldlist()))
53 53
 
54 54
     @classmethod
55
-    def get(cls, query_filters, field_list = None, order = None, group = None, limit = None, offset = 0):
55
+    def get(cls, query_filters = None, field_list = None, order = None, group = None, limit = None, offset = 0):
56
+        query_filters = list() if query_filters is None else query_filters
56 57
         query_filters.append(('type_id', '=', cls._type_id))
57 58
         return super().get(
58 59
                             query_filters = query_filters,

+ 2
- 2
settings.py View File

@@ -39,8 +39,8 @@ em_graph_output = '/tmp/em_%s_graph.png'
39 39
 
40 40
 logging = {
41 41
     'stderr': {
42
-        'level': 'INFO',
43
-        'context': False,
42
+        'level': 'DEBUG',
43
+        'context': True,
44 44
     },
45 45
     'logfile': {
46 46
         'level': 'DEBUG',

Loading…
Cancel
Save