Browse Source

Add Save of Settings, EM translator in xml

prieto 8 years ago
parent
commit
9497130e8b

+ 328
- 0
lodel/editorial_model/translator/xmlfile.py View File

@@ -0,0 +1,328 @@
1
+#-*- coding: utf-8 -*-
2
+
3
+import lxml
4
+import os
5
+from lxml import etree
6
+from lodel.editorial_model.model import EditorialModel
7
+from lodel.editorial_model.components import *
8
+from lodel.utils.mlstring import MlString
9
+
10
+##@brief Saves a model in a xml file
11
+# @param model EditorialModel : the model to save
12
+# @param filename str|None : if None display on stdout
13
+
14
+def save(model, **kwargs):
15
+    Em = etree.Element("editorial_model")
16
+    em_name = etree.SubElement(Em, 'name')
17
+    write_mlstring_xml(etree, em_name, model.name)
18
+    
19
+    em_description = etree.SubElement(Em, 'description')
20
+    write_mlstring_xml(etree, em_description, model.description)
21
+    
22
+    em_classes = etree.SubElement(Em, 'classes')
23
+    classes = model.all_classes()
24
+    for emclass in classes:
25
+        write_emclass_xml(etree, em_classes, classes[emclass].uid, classes[emclass].display_name, 
26
+                          classes[emclass].help_text, classes[emclass].group, 
27
+                          classes[emclass].fields(), classes[emclass].parents, 
28
+                          classes[emclass].abstract, classes[emclass].pure_abstract)
29
+
30
+    em_groups = etree.SubElement(Em, 'groups')
31
+    groups = model.all_groups()
32
+    for group in groups:
33
+        requires = groups[group].dependencies()
34
+        write_emgroup_xml(etree, em_groups, groups[group].uid, groups[group].display_name, groups[group].help_text, 
35
+                          list(requires.keys()), groups[group].components())
36
+        
37
+    emodel = etree.tostring(Em, encoding='utf-8',  xml_declaration=True, method='xml', pretty_print= True)
38
+    if len(kwargs) == 0:
39
+        print(emodel.decode())
40
+    else:
41
+        outfile = open(kwargs['filename'], "w")
42
+        outfile.write(emodel.decode())
43
+        outfile.close()
44
+    
45
+    
46
+##@brief Writes a representation of a MlString in xml
47
+# @param etree : the xml object
48
+# @param elem : the element which represents a MlString
49
+# @param mlstr : the mlstr to write
50
+def write_mlstring_xml(etree, elem, mlstr):
51
+    for lang in mlstr.values:
52
+        ss_mlstr = etree.SubElement(elem,lang)
53
+        ss_mlstr.text = mlstr.get(lang)
54
+        
55
+##@brief Writes the definition of a datahandler in xml
56
+# @param etree : the xml object
57
+# @param elem : the element which defines a datahandler
58
+# @param dhdl_name : the name of the datahandler
59
+# @param kwargs : the options of the datahandler
60
+def write_datahandler_xml(etree, elem, dhdl_name, **kwargs):
61
+    dhdl = etree.SubElement(elem,'datahandler_name')
62
+    dhdl.text = dhdl_name
63
+    dhdl_opt = etree.SubElement(elem, 'datahandler_options')
64
+    for argname, argval in kwargs.items():
65
+        arg = etree.SubElement(dhdl_opt, argname)
66
+        arg.text = argval
67
+        
68
+##@brief Writes a representation in xml of a EmField
69
+# @param etree : the xml object
70
+# @param elem : the element for the EmField
71
+# @param uid : the uid of the EmField
72
+# @param name : the name of the field
73
+# @param help_text : explanations of the EmField
74
+# @param group_uid : the uid of a group, can be None
75
+# @datahandler_name
76
+# @**kwargs : options of the datahandler
77
+def write_emfield_xml(etree, elem, uid, name, help_text, group, datahandler_name, **kwargs):
78
+    emfield = etree.SubElement(elem,'field')
79
+    emfield_uid = etree.SubElement(emfield, 'uid')
80
+    emfield_uid.text = uid
81
+    emfield_name = etree.SubElement(emfield, 'display_name')
82
+    if name is None:
83
+        pass
84
+    else:
85
+        write_mlstring_xml(etree, emfield_name, name)
86
+    emfield_help = etree.SubElement(emfield, 'help_text')
87
+    if help_text is None:
88
+        pass
89
+    else:
90
+        write_mlstring_xml(etree, emfield_help, help_text)
91
+    emfield_group = etree.SubElement(emfield, 'group')
92
+    if group is not None:
93
+        emfield_group.text = group.uid #write_emgroup_xml(etree, emfield_group, group.uid, group.display_name, group.help_text, group.requires)
94
+    write_datahandler_xml(etree,emfield,datahandler_name, **kwargs)
95
+
96
+##@brief Writes a representation of a EmGroup in xml
97
+# @param etree : the xml object
98
+# @param elem : the element for the EmGroup
99
+# @param name  : the name of the group
100
+# @param help_text : explanations of the EmGroup
101
+# @param requires : a list of the group's uids whose this group depends
102
+
103
+def write_emgroup_xml(etree, elem, uid, name, help_text, requires, components):
104
+    emgroup = etree.SubElement(elem, 'group')
105
+    emgroup_uid = etree.SubElement(emgroup, 'uid')
106
+    emgroup_uid.text = uid
107
+    emgroup_name = etree.SubElement(emgroup, 'display_name')
108
+    if name is None:
109
+        pass
110
+    else:
111
+        write_mlstring_xml(etree, emgroup_name, name)
112
+    emgroup_help = etree.SubElement(emgroup, 'help_text')
113
+    if help_text is None:
114
+        pass
115
+    else:
116
+        write_mlstring_xml(etree, emgroup_help, help_text)
117
+    emgroup_requires = etree.SubElement(emgroup, 'requires')
118
+    emgroup_requires.text = ",".join(requires)
119
+    emgroup_comp = etree.SubElement(emgroup, 'components')
120
+    emgroup_comp_cls = etree.SubElement(emgroup_comp, 'emclasses')
121
+    emgroup_comp_fld = etree.SubElement(emgroup_comp, 'emfields')
122
+    
123
+    for component in components:
124
+        if isinstance(component, EmField):
125
+            emgroup_comp_fld_ins = etree.SubElement(emgroup_comp_fld, 'emfield')
126
+            em_group_comp_fld_ins_uid =  etree.SubElement(emgroup_comp_fld_ins,'uid')
127
+            em_group_comp_fld_ins_uid.text = component.uid
128
+            em_group_comp_fld_ins_cls = etree.SubElement(emgroup_comp_fld_ins,'class')
129
+            em_group_comp_fld_ins_cls.text = component.get_emclass_uid()
130
+            #write_emfield_xml(etree, emgroup_comp_fld, component.uid, component.display_name, 
131
+            #                   component.help_text, component.group, component.data_handler_name, **(component.data_handler_options))
132
+        elif isinstance(component, EmClass):
133
+            em_group_comp_cls_ins = etree.SubElement(emgroup_comp_cls, 'emclass')
134
+            em_group_comp_cls_ins.text = component.uid
135
+            #write_emclass_xml(etree, emgroup_comp_cls, component.uid, component.display_name, component.help_text, component.group, 
136
+            #                  component.fields(), component.parents, component.abstract, component.pure_abstract)
137
+
138
+##@brief Writes a representation of a EmClass in xml
139
+# @param etree : the xml object
140
+# @param elem : the element for the EmClass
141
+# @param name  : the name of the group
142
+# @param help_text : explanations of the EmClass
143
+# @param fields : a dict
144
+# @param parents : a list of EmClass uids
145
+# @param abstract : a boolean
146
+# @param pure_abstract : a boolean
147
+
148
+def write_emclass_xml(etree, elem, uid, name, help_text, group, fields, parents, abstract = False, pure_abstract = False):
149
+    emclass = etree.SubElement(elem, 'class')
150
+    emclass_uid  = etree.SubElement(emclass, 'uid')
151
+    emclass_uid.text = uid
152
+    emclass_name = etree.SubElement(emclass, 'display_name')
153
+    if name is None:
154
+        pass
155
+    else:
156
+        write_mlstring_xml(etree, emclass_name, name)
157
+    emclass_help = etree.SubElement(emclass, 'help_text')
158
+    if help_text is None:
159
+        pass
160
+    else:
161
+        write_mlstring_xml(etree, emclass_help, help_text)
162
+    emclass_abstract = etree.SubElement(emclass, 'abstract')
163
+    emclass_abstract.text ="True" if abstract else "False"
164
+    emclass_pure_abstract = etree.SubElement(emclass, 'pure_abstract')
165
+    emclass_pure_abstract.text = "True" if pure_abstract else "False"
166
+    emclass_group = etree.SubElement(emclass, 'group')
167
+    if group is not None:
168
+        emclass_group.text = group.uid #write_emgroup_xml(etree, emclass_group, group.uid, group.name, group.help_text, group.require, group.components)
169
+    emclass_fields = etree.SubElement(emclass, 'fields')
170
+    for field in fields:
171
+        write_emfield_xml(etree, emclass_fields, field.uid, field.display_name, field.help_text, 
172
+                          field.group,field.data_handler_name, **field.data_handler_options)
173
+    parents_list=list()
174
+    for parent in parents:
175
+        parents_list.append(parent['uid'])
176
+    emclass_parents = etree.SubElement(emclass, 'parents')
177
+    emclass_parents.text = ",".join(parents_list)
178
+
179
+##@brief Loads a model from a xml file
180
+# @param model EditorialModel : the model to load
181
+
182
+def load(**kwargs):
183
+
184
+    Em = etree.parse(kwargs['filename'])
185
+    emodel = Em.getroot()
186
+    name = emodel.find('name')
187
+    description = emodel.find('description')
188
+
189
+    model = EditorialModel(load_mlstring_xml(name), load_mlstring_xml(description))
190
+        
191
+    classes = emodel.find('classes')
192
+    for emclass in classes:
193
+        model.add_class(load_class_xml(model, emclass))
194
+    
195
+    groups = emodel.find('groups')
196
+    for group in groups:
197
+        grp = load_group_xml(model, group)
198
+        grp = model.add_group(grp)
199
+
200
+    return model;
201
+
202
+def load_class_xml(model, elem):
203
+    uid = elem.find('uid').text
204
+    name = load_mlstring_xml(elem.find('display_name'))
205
+    help_text = load_mlstring_xml(elem.find('help_text'))
206
+    abstract = True if elem.find('abstract').text == 'True' else False
207
+    pure_abstract = True if elem.find('pure_abstract').text == 'True' else False
208
+    requires = list()
209
+    classes = model.all_classes()
210
+    req = elem.find('parents')
211
+    if req.text is not None:
212
+        l_req = req.text.split(',')
213
+        for r in l_req:
214
+            if r in classes:
215
+                requires.append(model.all_classes_ref(r))
216
+            else:
217
+                requires.append(model.add_class(EmClass(r)))
218
+    group = elem.find('group')
219
+    if group:
220
+        grp = model.add_group(EmGroup(group.text))
221
+    else:
222
+        grp = None
223
+        
224
+    if uid in classes:
225
+        emclass = model.all_classes_ref(uid)
226
+        emclass.display_name = name
227
+        emclass.help_text = help_text
228
+        emclass.parents=requires
229
+        emclass.group = grp
230
+    else:
231
+        emclass = EmClass(uid, name, help_text, abstract,requires, grp, pure_abstract)
232
+        
233
+    fields = elem.find('fields')
234
+    for field in fields:
235
+        emfield = load_field_xml(model, field)
236
+        l_emfields = emclass.fields()
237
+        incls = False
238
+        for emf in l_emfields:
239
+            if emfield.uid == emf.uid:
240
+                incls = True
241
+        if not incls:
242
+            emclass.add_field(emfield)
243
+            
244
+    return emclass
245
+    
246
+
247
+def load_field_xml(model, elem):
248
+    uid = elem.find('uid').text
249
+    if elem.find('display_name').text is None:
250
+        name = None
251
+    else:
252
+        name = load_mlstring_xml(elem.find('display_name'))
253
+        
254
+    if elem.find('help_text').text is None:
255
+        help_text = None
256
+    else:
257
+        help_text = load_mlstring_xml(elem.find('help_text'))
258
+    emgroup = elem.find('group')
259
+    if emgroup:
260
+        group = model.add_group(EmGroup(emgroup.text))
261
+    else:
262
+        group = None
263
+    dhdl = elem.find('datahandler_name')
264
+    if elem.find('datahandler_options').text is not None:
265
+        dhdl_options = elem.find('datahandler_options').text.split()
266
+        emfield = EmField(uid, dhdl, name, help_text, group, **dhdl_options)
267
+    else:
268
+        emfield = EmField(uid, dhdl.text, name, help_text, group)
269
+    
270
+    return emfield
271
+    
272
+def load_group_xml(model, elem):
273
+    uid = elem.find('uid')
274
+    
275
+    if elem.find('display_name').text is None:
276
+        name = None
277
+    else:
278
+        name = load_mlstring_xml(elem.find('display_name'))
279
+        
280
+    if elem.find('help_text').text is None:
281
+        help_text = None
282
+    else:
283
+        help_text = load_mlstring_xml(elem.find('help_text'))
284
+        
285
+    requires = list()
286
+    groups = model.all_groups()
287
+    req = elem.find('requires')
288
+    if req.text is not None:
289
+        l_req = req.text.split(',')
290
+        for r in l_req:
291
+            if r in groups:
292
+                requires.append(model.all_groups_ref(r))
293
+            else:
294
+                grp = model.new_group(r)
295
+                requires.append(grp)
296
+    if uid in groups:
297
+        group = model.all_groups_ref(uid)
298
+        group.display_name = name
299
+        group.help_text = help_text
300
+        group.add_dependencie(requires)
301
+    else:
302
+        group = EmGroup(uid.text, requires, name, help_text)
303
+    
304
+    comp= list()
305
+    components = elem.find('components')
306
+    fields = components.find('emfields')
307
+    for field in fields:
308
+        fld_uid = field.find('uid').text
309
+        fld_class = field.find('class').text
310
+        fld = model.all_classes_ref(fld_class).fields(fld_uid)
311
+        comp.append(fld)
312
+    classes = components.find('emclasses')
313
+    for classe in classes:
314
+        comp.append(model.all_classes_ref(classe.text))
315
+    group.add_components(comp)
316
+        
317
+    return group
318
+
319
+def load_mlstring_xml(elem):
320
+    mlstr = dict()
321
+    for lang in elem:
322
+        mlstr[lang.tag] = lang.text 
323
+    return MlString(mlstr)
324
+
325
+
326
+
327
+
328
+        

+ 3
- 1
lodel/settings/settings.py View File

@@ -120,7 +120,8 @@ class Settings(object, metaclass=MetaSettings):
120 120
     #@param confvalue is a dict with variables to save
121 121
     #@param validators is a dict with adapted validator
122 122
     @classmethod
123
-    def set(cls, confname, confvalue,validator, loader):
123
+    def set(cls, confname, confvalue,validator):
124
+        loader = SettingsLoader(cls.instance.__conf_dir)
124 125
         confkey=confname.rpartition('.')
125 126
         loader.setoption(confkey[0], confkey[2], confvalue, validator)
126 127
 
@@ -140,6 +141,7 @@ class Settings(object, metaclass=MetaSettings):
140 141
         # Init the settings loader
141 142
         loader = SettingsLoader(self.__conf_dir)
142 143
         # fetching list of plugins to load
144
+
143 145
         plugins_list = loader.getoption(    'lodel2',
144 146
                                             'plugins',
145 147
                                             plugins_opt_specs[1],

+ 80
- 0
tests/editorial_model/test_translator_xmlfile.py View File

@@ -0,0 +1,80 @@
1
+#-*- coding: utf-8 -*-
2
+
3
+import unittest
4
+import tempfile
5
+import os
6
+
7
+import tests.loader_utils
8
+from lodel.editorial_model.translator import xmlfile
9
+from lodel.editorial_model.model import EditorialModel
10
+from lodel.editorial_model.components import *
11
+from lodel.editorial_model.exceptions import *
12
+
13
+class XmlFileTestCase(unittest.TestCase):
14
+    
15
+    def test_save(self):
16
+        emmodel = EditorialModel("test model", description = "Test EM")
17
+        cls1 = emmodel.new_class('testclass1', display_name = 'Classe de test 1', help_text = 'super aide')
18
+        c1f1 = cls1.new_field('testfield1', data_handler = 'varchar')
19
+        c1f2 = cls1.new_field('testfield2', data_handler = 'varchar')
20
+        cls2 = emmodel.new_class('testclass2', display_name = 'Classe de test 2', help_text = 'super aide')
21
+        c2f1 = cls2.new_field('testfield1', data_handler = 'varchar')
22
+        c2f2 = cls2.new_field('testfield2', data_handler = 'varchar')
23
+
24
+        grp1 = emmodel.new_group('testgroup1')
25
+        grp1.add_components((cls1, c1f1))
26
+        grp2 = emmodel.new_group('testgroup2')
27
+        grp2.add_components((cls2, c1f2, c2f1, c2f2))
28
+
29
+        grp2.add_dependencie(grp1)
30
+        
31
+        filename = {'filename' : 'savemodel.xml'}
32
+        emmodel.save(xmlfile, **filename)
33
+        new_model = EditorialModel.load(xmlfile, **filename)
34
+        
35
+        fname = {'filename' : 'savemodel_bis.xml'}
36
+        new_model.save(xmlfile, **fname)
37
+        #new_model2 = EditorialModel.load(xmlfile, **fname)
38
+    
39
+        self.assertNotEqual(id(new_model), id(emmodel))
40
+
41
+        #self.assertEqual(new_model.d_hash(), new_model2.d_hash())
42
+        new_cls2 = new_model.all_classes('testclass2')
43
+        em_cls2 = emmodel.all_classes('testclass2')
44
+        new_fields = new_cls2.fields()
45
+        em_fields = em_cls2.fields()
46
+        #for fld in new_fields:
47
+        #    print(fld.d_hash())
48
+        #for fld in em_fields:
49
+        #    print(fld.d_hash())
50
+        # fields OK
51
+        
52
+        new_cls1 = new_model.all_classes('testclass1')
53
+        em_cls1 = emmodel.all_classes('testclass1')
54
+        new_fields = new_cls1.fields()
55
+        em_fields = em_cls1.fields()
56
+        #for fld in new_fields:
57
+        #    print(fld.d_hash())
58
+        #for fld in em_fields:
59
+        #    print(fld.d_hash())
60
+        # fields OK
61
+        
62
+        # super().d_hash() OK si display_name et help_text dans cls2
63
+        self.assertEqual(new_cls2.d_hash(),em_cls2.d_hash())
64
+        self.assertEqual(new_model.all_classes('testclass1').d_hash(), cls1.d_hash())
65
+        self.assertEqual(new_model.all_groups('testgroup2').d_hash(), grp2.d_hash())
66
+        # Pb de d_hash required
67
+        emmgrp1 = new_model.all_groups('testgroup1')
68
+        for rep in emmgrp1.required_by:
69
+            print(emmgrp1.required_by[rep])
70
+        self.assertEqual(emmgrp1.d_hash(), grp1.d_hash())
71
+        
72
+        self.assertEqual(new_model.all_groups('testgroup1').d_hash(), emmodel.all_groups('testgroup1').d_hash())
73
+
74
+
75
+
76
+        self.assertEqual(new_model.d_hash(), emmodel.d_hash())
77
+
78
+
79
+
80
+

+ 2
- 2
tests/settings/settings_tests.ini View File

@@ -1,3 +1,3 @@
1 1
 [lodel2]
2
-lib_path = /home/yannweb/dev/lodel2/lodel2-git
3
-plugins_path = /home/yannweb/dev/lodel2/lodel2-git/plugins
2
+lib_path = /home/helene/lodel2
3
+plugins_path = /home/helene/lodel2/plugins

+ 2
- 2
tests/settings/settings_tests_conf.d/settings.ini View File

@@ -1,3 +1,3 @@
1 1
 [lodel2]
2
-lib_path = /home/yannweb/dev/lodel2/lodel2-git
3
-plugins_path = /home/yannweb/dev/lodel2/lodel2-git/plugins
2
+lib_path = /home/helene/lodel2
3
+plugins_path = /home/helene/lodel2/plugins

+ 8
- 5
tests/settings/test_settings.py View File

@@ -16,14 +16,17 @@ class SettingsTestCase(unittest.TestCase):
16 16
             Settings('tests/settings/settings_tests_conf.d')
17 17
         
18 18
     def test_set(self):
19
-        loader = SettingsLoader('globconf.d')
20
-        Settings.set('lodel2.editorialmodel.emfile','test ok', dummy_validator, loader)
21
-        Settings.set('lodel2.editorialmodel.editormode','test ok', dummy_validator, loader)
19
+        Settings.set('lodel2.editorialmodel.emfile','test ok', dummy_validator)
20
+        Settings.set('lodel2.editorialmodel.editormode','test ok', dummy_validator)
22 21
         loader = SettingsLoader('globconf.d')
23 22
         option = loader.getoption('lodel2.editorialmodel','emfile', dummy_validator)
24 23
         self.assertEqual(option , 'test ok')
25 24
         option = loader.getoption('lodel2.editorialmodel','editormode', dummy_validator)
26 25
         self.assertEqual(option, 'test ok')
27
-        Settings.set('lodel2.editorialmodel.emfile','examples/em_test.pickle', dummy_validator, loader)
28
-        Settings.set('lodel2.editorialmodel.editormode','True', dummy_validator, loader)
26
+        Settings.set('lodel2.editorialmodel.emfile','examples/em_test.pickle', dummy_validator)
27
+        Settings.set('lodel2.editorialmodel.editormode','True', dummy_validator)
28
+        
29
+    def test_conf(self):
30
+        pass
31
+        
29 32
 

Loading…
Cancel
Save