Browse Source

Updated comments (and deleting space between ## and @brief )

Yann Weber 8 years ago
parent
commit
c5971d9590

+ 4
- 1
Makefile View File

3
 all: tests doc dyncode
3
 all: tests doc dyncode
4
 
4
 
5
 # generate doxygen documentation
5
 # generate doxygen documentation
6
-doc: cleandoc
6
+doc: cleandoc doc_graphviz
7
 	doxygen
7
 	doxygen
8
 
8
 
9
+doc_graphviz:
10
+	cd doc/img/graphviz; make
11
+
9
 # Test em update ( examples/em_test.pickle )
12
 # Test em update ( examples/em_test.pickle )
10
 em_test:
13
 em_test:
11
 	python3 em_test.py
14
 	python3 em_test.py

+ 50
- 6
em_test.py View File

142
                     display_name = {'eng': 'Title', 'fre': 'Titre'},
142
                     display_name = {'eng': 'Title', 'fre': 'Titre'},
143
                     group = editorial_group,
143
                     group = editorial_group,
144
                     data_handler = 'varchar',
144
                     data_handler = 'varchar',
145
-)
145
+                    nullable = True,)
146
 text.new_field(    'subtitle',
146
 text.new_field(    'subtitle',
147
                     display_name = {
147
                     display_name = {
148
                         'eng': 'Subtitle',
148
                         'eng': 'Subtitle',
150
                     },
150
                     },
151
                     group = editorial_group,
151
                     group = editorial_group,
152
                     data_handler = 'varchar',
152
                     data_handler = 'varchar',
153
-)
153
+                    nullable = True)
154
 
154
 
155
 # Classe collection
155
 # Classe collection
156
 collection = em.new_class(  'collection',
156
 collection = em.new_class(  'collection',
157
                             display_name = 'Collection',
157
                             display_name = 'Collection',
158
                             group = editorial_group,
158
                             group = editorial_group,
159
-                            abstract = True,
160
-                            parents = entitie,
161
-)
159
+                            abstract = False,
160
+                            parents = entitie)
162
 collection.new_field(   'title',
161
 collection.new_field(   'title',
163
                         display_name = 'Title',
162
                         display_name = 'Title',
164
                         group = editorial_group,
163
                         group = editorial_group,
165
-                        abstract = True,
166
                         data_handler = 'varchar'
164
                         data_handler = 'varchar'
167
 )
165
 )
166
+collection.new_field(   'publications',
167
+                        display_name = 'Publications',
168
+                        group = editorial_group,
169
+                        data_handler = 'list',
170
+                        back_reference = ('publication', 'collection'))
171
+
172
+# Classe publication
173
+pulication = em.new_class(  'publication',
174
+                            display_name = 'Publication',
175
+                            group = editorial_group,
176
+                            abstract = False,
177
+                            parents = entitie,)
178
+publication.new_field(  'collection',
179
+                        display_name = 'Collection',
180
+                        group = editorial_group,
181
+                        data_handler = 'link',
182
+                        back_reference = ('collection', 'publications'))
183
+
184
+#########################
185
+#   Texte definition    #
186
+#########################
187
+
188
+section = em.new_class(    'section',
189
+                            display_name = 'Section',
190
+                            group = editorial_group,
191
+                            abstract = False,
192
+                            parents = text)
193
+
194
+subsection = em.new_class(  'subsection',
195
+                            display_name = 'Subsection',
196
+                            group = editorial_group,
197
+                            abstract = False,
198
+                            parents = section)
199
+
200
+section.new_field(  'childs',
201
+                    display_name = 'Next section',
202
+                    group = editorial_group,
203
+                    data_hander = 'hierarch',
204
+                    allowed_class = [subsection],
205
+                    back_reference = ('subsection', 'parent'))
206
+
207
+subsection.new_field(   'parent',
208
+                        display_name = 'Parent',
209
+                        group = editorial_group,
210
+                        data_handler = 'link',
211
+                        allowed_class = [section])
168
 
212
 
169
 #####################
213
 #####################
170
 # Persons & authors #
214
 # Persons & authors #

+ 1
- 1
lodel/datasource/mongodb/datasource.py View File

24
         self.connection = MongoClient(connection_string)
24
         self.connection = MongoClient(connection_string)
25
         self.database = self.connection[connection_args['dbname']]
25
         self.database = self.connection[connection_args['dbname']]
26
 
26
 
27
-    ## @brief Inserts a list of records in a given collection
27
+    ##@brief Inserts a list of records in a given collection
28
     #
28
     #
29
     # @param collection_name str : name of the MongoDB collection in which we will insert the records
29
     # @param collection_name str : name of the MongoDB collection in which we will insert the records
30
     # @param datas list : list of dictionaries corresponding to the records
30
     # @param datas list : list of dictionaries corresponding to the records

+ 36
- 36
lodel/editorial_model/components.py View File

9
 
9
 
10
 from lodel.editorial_model.exceptions import *
10
 from lodel.editorial_model.exceptions import *
11
 
11
 
12
-## @brief Abstract class to represent editorial model components
12
+##@brief Abstract class to represent editorial model components
13
 # @see EmClass EmField
13
 # @see EmClass EmField
14
 # @todo forbid '.' in uid
14
 # @todo forbid '.' in uid
15
 class EmComponent(object):
15
 class EmComponent(object):
16
     
16
     
17
-    ## @brief Instanciate an EmComponent
17
+    ##@brief Instanciate an EmComponent
18
     # @param uid str : uniq identifier
18
     # @param uid str : uniq identifier
19
     # @param display_name MlString|str|dict : component display_name
19
     # @param display_name MlString|str|dict : component display_name
20
     # @param help_text MlString|str|dict : help_text
20
     # @param help_text MlString|str|dict : help_text
43
         return int.from_bytes(m.digest(), byteorder='big')
43
         return int.from_bytes(m.digest(), byteorder='big')
44
 
44
 
45
 
45
 
46
-## @brief Handles editorial model objects classes
46
+##@brief Handles editorial model objects classes
47
 class EmClass(EmComponent):
47
 class EmClass(EmComponent):
48
     
48
     
49
-    ## @brief Instanciate a new EmClass
49
+    ##@brief Instanciate a new EmClass
50
     # @param uid str : uniq identifier
50
     # @param uid str : uniq identifier
51
     # @param display_name MlString|str|dict : component display_name
51
     # @param display_name MlString|str|dict : component display_name
52
     # @param abstract bool : set the class as asbtract if True
52
     # @param abstract bool : set the class as asbtract if True
68
         else:
68
         else:
69
             parents = list()
69
             parents = list()
70
         self.parents = parents
70
         self.parents = parents
71
-        ## @brief Stores EmFields instances indexed by field uid
71
+        ##@brief Stores EmFields instances indexed by field uid
72
         self.__fields = dict() 
72
         self.__fields = dict() 
73
     
73
     
74
-    ## @brief Property that represent a dict of all fields (the EmField defined in this class and all its parents)
74
+    ##@brief Property that represent a dict of all fields (the EmField defined in this class and all its parents)
75
     @property
75
     @property
76
     def __all_fields(self):
76
     def __all_fields(self):
77
         res = dict()
77
         res = dict()
80
         res.update(self.__fields)
80
         res.update(self.__fields)
81
         return res
81
         return res
82
 
82
 
83
-    ## @brief Return the list of all dependencies
83
+    ##@brief Return the list of all dependencies
84
     #
84
     #
85
     # Reccursive parents listing
85
     # Reccursive parents listing
86
     @property
86
     @property
93
             res |= parent.parents_recc
93
             res |= parent.parents_recc
94
         return res
94
         return res
95
 
95
 
96
-    ## @brief EmField getter
96
+    ##@brief EmField getter
97
     # @param uid None | str : If None returns an iterator on EmField instances else return an EmField instance
97
     # @param uid None | str : If None returns an iterator on EmField instances else return an EmField instance
98
     # @param no_parents bool : If True returns only fields defined is this class and not the one defined in parents classes
98
     # @param no_parents bool : If True returns only fields defined is this class and not the one defined in parents classes
99
     # @return A list on EmFields instances (if uid is None) else return an EmField instance
99
     # @return A list on EmFields instances (if uid is None) else return an EmField instance
104
         except KeyError:
104
         except KeyError:
105
             raise EditorialModelError("No such EmField '%s'" % uid)
105
             raise EditorialModelError("No such EmField '%s'" % uid)
106
 
106
 
107
-    ## @brief Add a field to the EmClass
107
+    ##@brief Add a field to the EmClass
108
     # @param emfield EmField : an EmField instance
108
     # @param emfield EmField : an EmField instance
109
     # @warning do not add an EmField allready in another class !
109
     # @warning do not add an EmField allready in another class !
110
     # @throw EditorialModelException if an EmField with same uid allready in this EmClass (overwritting allowed from parents)
110
     # @throw EditorialModelException if an EmField with same uid allready in this EmClass (overwritting allowed from parents)
121
         emfield._emclass = self
121
         emfield._emclass = self
122
         return emfield
122
         return emfield
123
     
123
     
124
-    ## @brief Create a new EmField and add it to the EmClass
124
+    ##@brief Create a new EmField and add it to the EmClass
125
     # @param data_handler str : A DataHandler name
125
     # @param data_handler str : A DataHandler name
126
     # @param uid str : the EmField uniq id
126
     # @param uid str : the EmField uniq id
127
     # @param **field_kwargs :  EmField constructor parameters ( see @ref EmField.__init__() ) 
127
     # @param **field_kwargs :  EmField constructor parameters ( see @ref EmField.__init__() ) 
152
         return "<class %s EmClass uid=%s>" % (abstract, repr(self.uid) )
152
         return "<class %s EmClass uid=%s>" % (abstract, repr(self.uid) )
153
 
153
 
154
 
154
 
155
-## @brief Handles editorial model classes fields
155
+##@brief Handles editorial model classes fields
156
 class EmField(EmComponent):
156
 class EmField(EmComponent):
157
 
157
 
158
-    ## @brief Instanciate a new EmField
158
+    ##@brief Instanciate a new EmField
159
     # @param uid str : uniq identifier
159
     # @param uid str : uniq identifier
160
     # @param display_name MlString|str|dict : field display_name
160
     # @param display_name MlString|str|dict : field display_name
161
     # @param data_handler str : A DataHandler name
161
     # @param data_handler str : A DataHandler name
165
     def __init__(self, uid, data_handler, display_name = None, help_text = None, group = None, **handler_kwargs):
165
     def __init__(self, uid, data_handler, display_name = None, help_text = None, group = None, **handler_kwargs):
166
         from lodel.leapi.datahandlers.base_classes import DataHandler
166
         from lodel.leapi.datahandlers.base_classes import DataHandler
167
         super().__init__(uid, display_name, help_text, group)
167
         super().__init__(uid, display_name, help_text, group)
168
-        ## @brief The data handler name
168
+        ##@brief The data handler name
169
         self.data_handler_name = data_handler
169
         self.data_handler_name = data_handler
170
-        ## @brief The data handler class
170
+        ##@brief The data handler class
171
         self.data_handler_cls = DataHandler.from_name(data_handler)
171
         self.data_handler_cls = DataHandler.from_name(data_handler)
172
-        ## @brief The data handler instance associated with this EmField
172
+        ##@brief The data handler instance associated with this EmField
173
         self.data_handler_instance = self.data_handler_cls(**handler_kwargs)
173
         self.data_handler_instance = self.data_handler_cls(**handler_kwargs)
174
-        ## @brief Stores data handler instanciation options
174
+        ##@brief Stores data handler instanciation options
175
         self.data_handler_options = handler_kwargs
175
         self.data_handler_options = handler_kwargs
176
-        ## @brief Stores the emclass that contains this field (set by EmClass.add_field() method)
176
+        ##@brief Stores the emclass that contains this field (set by EmClass.add_field() method)
177
         self._emclass = None
177
         self._emclass = None
178
 
178
 
179
-    ## @brief Returns data_handler_name attribute
179
+    ##@brief Returns data_handler_name attribute
180
     def get_data_handler_name(self):
180
     def get_data_handler_name(self):
181
         return copy.copy(self.data_handler_name)
181
         return copy.copy(self.data_handler_name)
182
         
182
         
183
-    ## @brief Returns data_handler_cls attribute
183
+    ##@brief Returns data_handler_cls attribute
184
     def get_data_handler_cls(self):
184
     def get_data_handler_cls(self):
185
         return copy.copy(selfdata_handler_cls)
185
         return copy.copy(selfdata_handler_cls)
186
     
186
     
195
                                 'utf-8')
195
                                 'utf-8')
196
         ).digest(), byteorder='big')
196
         ).digest(), byteorder='big')
197
 
197
 
198
-## @brief Handles functionnal group of EmComponents
198
+##@brief Handles functionnal group of EmComponents
199
 class EmGroup(object):
199
 class EmGroup(object):
200
         
200
         
201
-    ## @brief Create a new EmGroup
201
+    ##@brief Create a new EmGroup
202
     # @note you should NEVER call the constructor yourself. Use Model.add_group instead
202
     # @note you should NEVER call the constructor yourself. Use Model.add_group instead
203
     # @param uid str : Uniq identifier
203
     # @param uid str : Uniq identifier
204
     # @param depends list : A list of EmGroup dependencies
204
     # @param depends list : A list of EmGroup dependencies
206
     # @param help_text MlString|str : 
206
     # @param help_text MlString|str : 
207
     def __init__(self, uid, depends = None, display_name = None, help_text = None):
207
     def __init__(self, uid, depends = None, display_name = None, help_text = None):
208
         self.uid = uid
208
         self.uid = uid
209
-        ## @brief Stores the list of groups that depends on this EmGroup indexed by uid
209
+        ##@brief Stores the list of groups that depends on this EmGroup indexed by uid
210
         self.required_by = dict()
210
         self.required_by = dict()
211
-        ## @brief Stores the list of dependencies (EmGroup) indexed by uid
211
+        ##@brief Stores the list of dependencies (EmGroup) indexed by uid
212
         self.require = dict()
212
         self.require = dict()
213
-        ## @brief Stores the list of EmComponent instances contained in this group
213
+        ##@brief Stores the list of EmComponent instances contained in this group
214
         self.__components = set()
214
         self.__components = set()
215
 
215
 
216
         self.display_name = None if display_name is None else MlString(display_name)
216
         self.display_name = None if display_name is None else MlString(display_name)
221
                     raise ValueError("EmGroup expected in depends argument but %s found" % grp)
221
                     raise ValueError("EmGroup expected in depends argument but %s found" % grp)
222
                 self.add_dependencie(grp)
222
                 self.add_dependencie(grp)
223
     
223
     
224
-    ## @brief Returns EmGroup dependencie
224
+    ##@brief Returns EmGroup dependencie
225
     # @param recursive bool : if True return all dependencies and their dependencies
225
     # @param recursive bool : if True return all dependencies and their dependencies
226
     # @return a dict of EmGroup identified by uid
226
     # @return a dict of EmGroup identified by uid
227
     def dependencies(self, recursive = False):
227
     def dependencies(self, recursive = False):
237
                     res[new_dep.uid] = new_dep
237
                     res[new_dep.uid] = new_dep
238
         return res
238
         return res
239
     
239
     
240
-    ## @brief Returns EmGroup applicants
240
+    ##@brief Returns EmGroup applicants
241
     # @param recursive bool : if True return all dependencies and their dependencies
241
     # @param recursive bool : if True return all dependencies and their dependencies
242
     # @returns a dict of EmGroup identified by uid
242
     # @returns a dict of EmGroup identified by uid
243
     def applicants(self, recursive = False):
243
     def applicants(self, recursive = False):
253
                     res[new_app.uid] = new_app
253
                     res[new_app.uid] = new_app
254
         return res
254
         return res
255
     
255
     
256
-	## @brief Returns EmGroup components
256
+	##@brief Returns EmGroup components
257
     # @returns a copy of the set of components
257
     # @returns a copy of the set of components
258
     def components(self):
258
     def components(self):
259
         return (self.__components).copy()
259
         return (self.__components).copy()
260
 
260
 
261
-    ## @brief Returns EmGroup display_name
261
+    ##@brief Returns EmGroup display_name
262
     #  @param lang str | None : If None return default lang translation
262
     #  @param lang str | None : If None return default lang translation
263
     #  @returns None if display_name is None, a str for display_name else
263
     #  @returns None if display_name is None, a str for display_name else
264
     def get_display_name(self, lang=None):
264
     def get_display_name(self, lang=None):
266
         if name is None : return None
266
         if name is None : return None
267
         return name.get(lang);
267
         return name.get(lang);
268
 
268
 
269
-    ## @brief Returns EmGroup help_text
269
+    ##@brief Returns EmGroup help_text
270
     #  @param lang str | None : If None return default lang translation
270
     #  @param lang str | None : If None return default lang translation
271
     #  @returns None if display_name is None, a str for display_name else
271
     #  @returns None if display_name is None, a str for display_name else
272
     def get_help_text(self, lang=None):
272
     def get_help_text(self, lang=None):
274
         if help is None : return None
274
         if help is None : return None
275
         return help.get(lang);
275
         return help.get(lang);
276
     
276
     
277
-    ## @brief Add components in a group
277
+    ##@brief Add components in a group
278
     # @param components list : EmComponent instances list
278
     # @param components list : EmComponent instances list
279
     def add_components(self, components):
279
     def add_components(self, components):
280
         for component in components:
280
         for component in components:
285
                 raise EditorialModelError("Expecting components to be a list of EmComponent, but %s found in the list" % type(component))
285
                 raise EditorialModelError("Expecting components to be a list of EmComponent, but %s found in the list" % type(component))
286
         self.__components |= set(components)
286
         self.__components |= set(components)
287
 
287
 
288
-    ## @brief Add a dependencie
288
+    ##@brief Add a dependencie
289
     # @param em_group EmGroup|iterable : an EmGroup instance or list of instance
289
     # @param em_group EmGroup|iterable : an EmGroup instance or list of instance
290
     def add_dependencie(self, grp):
290
     def add_dependencie(self, grp):
291
         try:
291
         try:
301
         self.require[grp.uid] = grp
301
         self.require[grp.uid] = grp
302
         grp.required_by[self.uid] = self
302
         grp.required_by[self.uid] = self
303
         
303
         
304
-    ## @brief Add a applicant
304
+    ##@brief Add a applicant
305
     # @param em_group EmGroup|iterable : an EmGroup instance or list of instance
305
     # @param em_group EmGroup|iterable : an EmGroup instance or list of instance
306
     def add_applicant(self, grp):
306
     def add_applicant(self, grp):
307
         try:
307
         try:
317
         self.required_by[grp.uid] = grp
317
         self.required_by[grp.uid] = grp
318
         grp.require[self.uid] = self
318
         grp.require[self.uid] = self
319
     
319
     
320
-    ## @brief Search for circular dependencie
320
+    ##@brief Search for circular dependencie
321
     # @return True if circular dep found else False
321
     # @return True if circular dep found else False
322
     def __circular_dependencie(self, new_dep):
322
     def __circular_dependencie(self, new_dep):
323
         return self.uid in new_dep.dependencies(True)
323
         return self.uid in new_dep.dependencies(True)
324
     
324
     
325
-    ## @brief Search for circular applicant
325
+    ##@brief Search for circular applicant
326
     # @return True if circular app found else False
326
     # @return True if circular app found else False
327
     def __circular_applicant(self, new_app):
327
     def __circular_applicant(self, new_app):
328
         return self.uid in new_app.applicants(True)
328
         return self.uid in new_app.applicants(True)
329
 
329
 
330
-    ## @brief Fancy string representation of an EmGroup
330
+    ##@brief Fancy string representation of an EmGroup
331
     # @return a string
331
     # @return a string
332
     def __str__(self):
332
     def __str__(self):
333
         if self.display_name is None:
333
         if self.display_name is None:
353
                                 byteorder = 'big'
353
                                 byteorder = 'big'
354
         )
354
         )
355
     
355
     
356
-    ## @brief Complete string representation of an EmGroup
356
+    ##@brief Complete string representation of an EmGroup
357
     # @return a string
357
     # @return a string
358
     def __repr__(self):
358
     def __repr__(self):
359
         return "<class EmGroup '%s' depends : [%s]>" % (self.uid, ', '.join([duid for duid in self.dependencies(False)]) )
359
         return "<class EmGroup '%s' depends : [%s]>" % (self.uid, ', '.join([duid for duid in self.dependencies(False)]) )

+ 15
- 15
lodel/editorial_model/model.py View File

8
 from lodel.editorial_model.exceptions import *
8
 from lodel.editorial_model.exceptions import *
9
 from lodel.editorial_model.components import EmClass, EmField, EmGroup
9
 from lodel.editorial_model.components import EmClass, EmField, EmGroup
10
 
10
 
11
-## @brief Describe an editorial model
11
+##@brief Describe an editorial model
12
 class EditorialModel(object):
12
 class EditorialModel(object):
13
     
13
     
14
-    ## @brief Create a new editorial model
14
+    ##@brief Create a new editorial model
15
     # @param name MlString|str|dict : the editorial model name
15
     # @param name MlString|str|dict : the editorial model name
16
     # @param description MlString|str|dict : the editorial model description
16
     # @param description MlString|str|dict : the editorial model description
17
     def __init__(self, name, description = None):
17
     def __init__(self, name, description = None):
18
         self.name = MlString(name)
18
         self.name = MlString(name)
19
         self.description = MlString(description)
19
         self.description = MlString(description)
20
-        ## @brief Stores all groups indexed by id
20
+        ##@brief Stores all groups indexed by id
21
         self.__groups = dict()
21
         self.__groups = dict()
22
-        ## @brief Stores all classes indexed by id
22
+        ##@brief Stores all classes indexed by id
23
         self.__classes = dict()
23
         self.__classes = dict()
24
     
24
     
25
-    ## @brief EmClass accessor
25
+    ##@brief EmClass accessor
26
     # @param uid None | str : give this argument to get a specific EmClass
26
     # @param uid None | str : give this argument to get a specific EmClass
27
     # @return if uid is given returns an EmClass else returns an EmClass iterator
27
     # @return if uid is given returns an EmClass else returns an EmClass iterator
28
     def classes(self, uid = None):
28
     def classes(self, uid = None):
31
         except KeyError:
31
         except KeyError:
32
             raise EditorialModelException("EmClass not found : '%s'" % uid)
32
             raise EditorialModelException("EmClass not found : '%s'" % uid)
33
 
33
 
34
-    ## @brief EmGroup getter
34
+    ##@brief EmGroup getter
35
     # @param uid None | str : give this argument to get a specific EmGroup
35
     # @param uid None | str : give this argument to get a specific EmGroup
36
     # @return if uid is given returns an EmGroup else returns an EmGroup iterator
36
     # @return if uid is given returns an EmGroup else returns an EmGroup iterator
37
     def groups(self, uid = None):
37
     def groups(self, uid = None):
40
         except KeyError:
40
         except KeyError:
41
             raise EditorialModelException("EmGroup not found : '%s'" % uid)
41
             raise EditorialModelException("EmGroup not found : '%s'" % uid)
42
     
42
     
43
-    ## @brief EmField getter
43
+    ##@brief EmField getter
44
     # @param uid str : An EmField uid represented by "CLASSUID.FIELDUID"
44
     # @param uid str : An EmField uid represented by "CLASSUID.FIELDUID"
45
     # @return Fals or an EmField instance
45
     # @return Fals or an EmField instance
46
     #
46
     #
61
             pass
61
             pass
62
         return False
62
         return False
63
 
63
 
64
-    ## @brief Add a class to the editorial model
64
+    ##@brief Add a class to the editorial model
65
     # @param emclass EmClass : the EmClass instance to add
65
     # @param emclass EmClass : the EmClass instance to add
66
     # @return emclass
66
     # @return emclass
67
     def add_class(self, emclass):
67
     def add_class(self, emclass):
72
         self.__classes[emclass.uid] = emclass
72
         self.__classes[emclass.uid] = emclass
73
         return emclass
73
         return emclass
74
 
74
 
75
-    ## @brief Add a group to the editorial model
75
+    ##@brief Add a group to the editorial model
76
     # @param emgroup EmGroup : the EmGroup instance to add
76
     # @param emgroup EmGroup : the EmGroup instance to add
77
     # @return emgroup
77
     # @return emgroup
78
     def add_group(self, emgroup):
78
     def add_group(self, emgroup):
83
         self.__groups[emgroup.uid] = emgroup
83
         self.__groups[emgroup.uid] = emgroup
84
         return emgroup
84
         return emgroup
85
 
85
 
86
-    ## @brief Add a new EmClass to the editorial model
86
+    ##@brief Add a new EmClass to the editorial model
87
     # @param uid str : EmClass uid
87
     # @param uid str : EmClass uid
88
     # @param **kwargs : EmClass constructor options ( see @ref lodel.editorial_model.component.EmClass.__init__() )
88
     # @param **kwargs : EmClass constructor options ( see @ref lodel.editorial_model.component.EmClass.__init__() )
89
     def new_class(self, uid, **kwargs):
89
     def new_class(self, uid, **kwargs):
90
         return self.add_class(EmClass(uid, **kwargs))
90
         return self.add_class(EmClass(uid, **kwargs))
91
     
91
     
92
-    ## @brief Add a new EmGroup to the editorial model
92
+    ##@brief Add a new EmGroup to the editorial model
93
     # @param uid str : EmGroup uid
93
     # @param uid str : EmGroup uid
94
     # @param *kwargs : EmGroup constructor keywords arguments (see @ref lodel.editorial_model.component.EmGroup.__init__() )
94
     # @param *kwargs : EmGroup constructor keywords arguments (see @ref lodel.editorial_model.component.EmGroup.__init__() )
95
     def new_group(self, uid, **kwargs):
95
     def new_group(self, uid, **kwargs):
103
             translator = self.translator_from_name(translator)
103
             translator = self.translator_from_name(translator)
104
         return translator.save(self, **translator_kwargs)
104
         return translator.save(self, **translator_kwargs)
105
     
105
     
106
-    ## @brief Load a model
106
+    ##@brief Load a model
107
     # @param translator module : The translator module to use
107
     # @param translator module : The translator module to use
108
     # @param **translator_args
108
     # @param **translator_args
109
     @classmethod
109
     @classmethod
112
             translator = cls.translator_from_name(translator)
112
             translator = cls.translator_from_name(translator)
113
         return translator.load(**translator_kwargs)
113
         return translator.load(**translator_kwargs)
114
 
114
 
115
-    ## @brief Return a translator module given a translator name
115
+    ##@brief Return a translator module given a translator name
116
     # @param translator_name str : The translator name
116
     # @param translator_name str : The translator name
117
     # @return the translator python module
117
     # @return the translator python module
118
     # @throw NameError if the translator does not exists
118
     # @throw NameError if the translator does not exists
126
         return mod
126
         return mod
127
         
127
         
128
     
128
     
129
-    ## @brief Private getter for __groups or __classes
129
+    ##@brief Private getter for __groups or __classes
130
     # @see classes() groups()
130
     # @see classes() groups()
131
     def __elt_getter(self, elts, uid):
131
     def __elt_getter(self, elts, uid):
132
         return list(elts.values()) if uid is None else elts[uid]
132
         return list(elts.values()) if uid is None else elts[uid]
133
     
133
     
134
-    ## @brief Lodel hash
134
+    ##@brief Lodel hash
135
     def d_hash(self):
135
     def d_hash(self):
136
         payload = "%s%s" % (
136
         payload = "%s%s" % (
137
                             self.name,
137
                             self.name,

+ 2
- 2
lodel/editorial_model/translator/picklefile.py View File

3
 import pickle
3
 import pickle
4
 from pickle import Pickler
4
 from pickle import Pickler
5
 
5
 
6
-## @brief Save a model in a file
6
+##@brief Save a model in a file
7
 # @param model EditorialModel : the model to save
7
 # @param model EditorialModel : the model to save
8
 # @param filename str|None : if None return the model as pickle bytes
8
 # @param filename str|None : if None return the model as pickle bytes
9
 # @return None if filename is a string, else returns bytes representation of model
9
 # @return None if filename is a string, else returns bytes representation of model
12
         pickle.dump(model, ffd)
12
         pickle.dump(model, ffd)
13
     return filename
13
     return filename
14
 
14
 
15
-## @brief Load a model from a file
15
+##@brief Load a model from a file
16
 # @param filename str : the filename to use to load the model
16
 # @param filename str : the filename to use to load the model
17
 def load(filename):
17
 def load(filename):
18
     with open(filename, 'rb') as ffd:
18
     with open(filename, 'rb') as ffd:

+ 21
- 21
lodel/leapi/datahandlers/base_classes.py View File

13
 class FieldValidationError(Exception):
13
 class FieldValidationError(Exception):
14
     pass
14
     pass
15
 
15
 
16
-## @brief Base class for all data handlers
16
+##@brief Base class for all data handlers
17
 class DataHandler(object):
17
 class DataHandler(object):
18
     
18
     
19
     __HANDLERS_MODULES = ('datas_base', 'datas', 'references')
19
     __HANDLERS_MODULES = ('datas_base', 'datas', 'references')
20
-    ## @brief Stores the DataHandler childs classes indexed by name
20
+    ##@brief Stores the DataHandler childs classes indexed by name
21
     __base_handlers = None
21
     __base_handlers = None
22
-    ## @brief Stores custom datahandlers classes indexed by name
22
+    ##@brief Stores custom datahandlers classes indexed by name
23
     # @todo do it ! (like plugins, register handlers... blablabla)
23
     # @todo do it ! (like plugins, register handlers... blablabla)
24
     __custom_handlers = dict()
24
     __custom_handlers = dict()
25
 
25
 
26
     help_text = 'Generic Field Data Handler'
26
     help_text = 'Generic Field Data Handler'
27
 
27
 
28
-    ## @brief List fields that will be exposed to the construct_data_method
28
+    ##@brief List fields that will be exposed to the construct_data_method
29
     _construct_datas_deps = []
29
     _construct_datas_deps = []
30
 
30
 
31
-    ## @brief constructor
31
+    ##@brief constructor
32
     # @param internal False | str : define whether or not a field is internal
32
     # @param internal False | str : define whether or not a field is internal
33
     # @param immutable bool : indicates if the fieldtype has to be defined in child classes of LeObject or if it is
33
     # @param immutable bool : indicates if the fieldtype has to be defined in child classes of LeObject or if it is
34
     #                         designed globally and immutable
34
     #                         designed globally and immutable
65
     def is_primary_key(self):
65
     def is_primary_key(self):
66
         return self.primary_key
66
         return self.primary_key
67
 
67
 
68
-    ## @brief checks if a fieldtype is internal
68
+    ##@brief checks if a fieldtype is internal
69
     # @return bool
69
     # @return bool
70
     def is_internal(self):
70
     def is_internal(self):
71
         return self.internal is not False
71
         return self.internal is not False
72
 
72
 
73
-    ## @brief calls the data_field defined _check_data_value() method
73
+    ##@brief calls the data_field defined _check_data_value() method
74
     # @return tuple (value, error|None)
74
     # @return tuple (value, error|None)
75
     def check_data_value(self, value):
75
     def check_data_value(self, value):
76
         if value is None:
76
         if value is None:
80
             return None, None
80
             return None, None
81
         return self._check_data_value(value)
81
         return self._check_data_value(value)
82
 
82
 
83
-    ## @brief checks if this class can override the given data handler
83
+    ##@brief checks if this class can override the given data handler
84
     # @param data_handler DataHandler
84
     # @param data_handler DataHandler
85
     # @return bool
85
     # @return bool
86
     def can_override(self, data_handler):
86
     def can_override(self, data_handler):
88
             return False
88
             return False
89
         return True
89
         return True
90
 
90
 
91
-    ## @brief Build field value
91
+    ##@brief Build field value
92
     # @param emcomponent EmComponent : An EmComponent child class instance
92
     # @param emcomponent EmComponent : An EmComponent child class instance
93
     # @param fname str : The field name
93
     # @param fname str : The field name
94
     # @param datas dict : dict storing fields values (from the component)
94
     # @param datas dict : dict storing fields values (from the component)
110
 
110
 
111
         return RuntimeError("Unable to construct data for field %s", fname)
111
         return RuntimeError("Unable to construct data for field %s", fname)
112
 
112
 
113
-    ## @brief Check datas consistency
113
+    ##@brief Check datas consistency
114
     # @param emcomponent EmComponent : An EmComponent child class instance
114
     # @param emcomponent EmComponent : An EmComponent child class instance
115
     # @param fname : the field name
115
     # @param fname : the field name
116
     # @param datas dict : dict storing fields values
116
     # @param datas dict : dict storing fields values
119
     def check_data_consistency(self, emcomponent, fname, datas):
119
     def check_data_consistency(self, emcomponent, fname, datas):
120
         return True
120
         return True
121
 
121
 
122
-    ## @brief This method is use by plugins to register new data handlers
122
+    ##@brief This method is use by plugins to register new data handlers
123
     @classmethod
123
     @classmethod
124
     def register_new_handler(cls, name, data_handler):
124
     def register_new_handler(cls, name, data_handler):
125
         if not inspect.isclass(data_handler):
125
         if not inspect.isclass(data_handler):
140
                         cls.__base_handlers[name.lower()] = obj
140
                         cls.__base_handlers[name.lower()] = obj
141
         return copy.copy(cls.__base_handlers)
141
         return copy.copy(cls.__base_handlers)
142
 
142
 
143
-    ## @brief given a field type name, returns the associated python class
143
+    ##@brief given a field type name, returns the associated python class
144
     # @param fieldtype_name str : A field type name (not case sensitive)
144
     # @param fieldtype_name str : A field type name (not case sensitive)
145
     # @return DataField child class
145
     # @return DataField child class
146
     # @todo implements custom handlers fetch
146
     # @todo implements custom handlers fetch
152
             raise NameError("No data handlers named '%s'" % (name,))
152
             raise NameError("No data handlers named '%s'" % (name,))
153
         return cls.__base_handlers[name]
153
         return cls.__base_handlers[name]
154
  
154
  
155
-    ## @brief Return the module name to import in order to use the datahandler
155
+    ##@brief Return the module name to import in order to use the datahandler
156
     # @param data_handler_name str : Data handler name
156
     # @param data_handler_name str : Data handler name
157
     # @return a str
157
     # @return a str
158
     @classmethod
158
     @classmethod
164
                                                     class_name = handler_class.__name__
164
                                                     class_name = handler_class.__name__
165
         )
165
         )
166
             
166
             
167
-    ## @brief __hash__ implementation for fieldtypes
167
+    ##@brief __hash__ implementation for fieldtypes
168
     def __hash__(self):
168
     def __hash__(self):
169
         hash_dats = [self.__class__.__module__]
169
         hash_dats = [self.__class__.__module__]
170
         for kdic in sorted([k for k in self.__dict__.keys() if not k.startswith('_')]):
170
         for kdic in sorted([k for k in self.__dict__.keys() if not k.startswith('_')]):
171
             hash_dats.append((kdic, getattr(self, kdic)))
171
             hash_dats.append((kdic, getattr(self, kdic)))
172
         return hash(tuple(hash_dats))
172
         return hash(tuple(hash_dats))
173
 
173
 
174
-## @brief Base class for datas data handler (by opposition with references)
174
+##@brief Base class for datas data handler (by opposition with references)
175
 class DataField(DataHandler):
175
 class DataField(DataHandler):
176
     pass
176
     pass
177
 
177
 
178
-## @brief Abstract class for all references
178
+##@brief Abstract class for all references
179
 #
179
 #
180
 # References are fields that stores a reference to another
180
 # References are fields that stores a reference to another
181
 # editorial object
181
 # editorial object
182
 class Reference(DataHandler):
182
 class Reference(DataHandler):
183
 
183
 
184
-    ## @brief Instanciation
184
+    ##@brief Instanciation
185
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
185
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
186
     # @param back_reference tuple | None : tuple containing (LeObject child class, fieldname)
186
     # @param back_reference tuple | None : tuple containing (LeObject child class, fieldname)
187
     # @param internal bool : if False, the field is not internal
187
     # @param internal bool : if False, the field is not internal
200
     def back_reference(self):
200
     def back_reference(self):
201
         return copy.copy(self.__back_reference)
201
         return copy.copy(self.__back_reference)
202
 
202
 
203
-    ## @brief Set the back reference for this field.
203
+    ##@brief Set the back reference for this field.
204
     def _set_back_reference(self, back_reference):
204
     def _set_back_reference(self, back_reference):
205
         self.__back_reference = back_reference
205
         self.__back_reference = back_reference
206
         
206
         
207
 
207
 
208
-    ## @brief Check value
208
+    ##@brief Check value
209
     # @param value *
209
     # @param value *
210
     # @return tuple(value, exception)
210
     # @return tuple(value, exception)
211
     # @todo implement the check when we have LeObject to check value
211
     # @todo implement the check when we have LeObject to check value
222
         return value
222
         return value
223
 
223
 
224
 
224
 
225
-## @brief This class represent a data_handler for single reference to another object
225
+##@brief This class represent a data_handler for single reference to another object
226
 #
226
 #
227
 # The fields using this data handlers are like "foreign key" on another object
227
 # The fields using this data handlers are like "foreign key" on another object
228
 class SingleRef(Reference):
228
 class SingleRef(Reference):
238
         return val, expt
238
         return val, expt
239
 
239
 
240
 
240
 
241
-## @brief This class represent a data_handler for multiple references to another object
241
+##@brief This class represent a data_handler for multiple references to another object
242
 #
242
 #
243
 # The fields using this data handlers are like SingleRef but can store multiple references in one field
243
 # The fields using this data handlers are like SingleRef but can store multiple references in one field
244
 # @note SQL implementation could be tricky
244
 # @note SQL implementation could be tricky

+ 6
- 6
lodel/leapi/datahandlers/datas.py View File

2
 
2
 
3
 from lodel.leapi.datahandlers.datas_base import *
3
 from lodel.leapi.datahandlers.datas_base import *
4
 
4
 
5
-## @brief Data field designed to handle formated strings
5
+##@brief Data field designed to handle formated strings
6
 class FormatString(Varchar):
6
 class FormatString(Varchar):
7
 
7
 
8
     help = 'Automatic string field, designed to use the str % operator to build its content'
8
     help = 'Automatic string field, designed to use the str % operator to build its content'
9
     base_type = 'char'
9
     base_type = 'char'
10
 
10
 
11
-    ## @brief Build its content with a field list and a format string
11
+    ##@brief Build its content with a field list and a format string
12
     # @param format_string str
12
     # @param format_string str
13
     # @param max_length int : the maximum length of the handled value
13
     # @param max_length int : the maximum length of the handled value
14
     # @param field_list list : List of field to use
14
     # @param field_list list : List of field to use
26
             return False
26
             return False
27
         return True
27
         return True
28
 
28
 
29
-## @brief Varchar validated by a regex
29
+##@brief Varchar validated by a regex
30
 class Regex(Varchar):
30
 class Regex(Varchar):
31
 
31
 
32
     help = 'String field validated with a regex. Takes two options : max_length and regex'
32
     help = 'String field validated with a regex. Takes two options : max_length and regex'
33
     base_type = 'char'
33
     base_type = 'char'
34
 
34
 
35
-    ## @brief A string field validated by a regex
35
+    ##@brief A string field validated by a regex
36
     # @param regex str : a regex string (passed as argument to re.compile())
36
     # @param regex str : a regex string (passed as argument to re.compile())
37
     # @param max_length int : the max length for this field (default : 10)
37
     # @param max_length int : the max length for this field (default : 10)
38
     # @param **kwargs
38
     # @param **kwargs
57
             return False
57
             return False
58
         return True
58
         return True
59
 
59
 
60
-## @brief Handles uniq ID
60
+##@brief Handles uniq ID
61
 class UniqID(Integer):
61
 class UniqID(Integer):
62
 
62
 
63
     help = 'Fieldtype designed to handle editorial model UID'
63
     help = 'Fieldtype designed to handle editorial model UID'
64
     base_type = 'int'
64
     base_type = 'int'
65
 
65
 
66
-    ## @brief A uid field
66
+    ##@brief A uid field
67
     # @param **kwargs
67
     # @param **kwargs
68
     def __init__(self, **kwargs):
68
     def __init__(self, **kwargs):
69
         kwargs['internal'] = 'automatic'
69
         kwargs['internal'] = 'automatic'

+ 11
- 11
lodel/leapi/datahandlers/datas_base.py View File

3
 
3
 
4
 from lodel.leapi.datahandlers.base_classes import DataField
4
 from lodel.leapi.datahandlers.base_classes import DataField
5
 
5
 
6
-## @brief Data field designed to handle boolean values
6
+##@brief Data field designed to handle boolean values
7
 class Boolean(DataField):
7
 class Boolean(DataField):
8
 
8
 
9
     help = 'A basic boolean field'
9
     help = 'A basic boolean field'
10
     base_type = 'bool'
10
     base_type = 'bool'
11
 
11
 
12
-    ## @brief A boolean field
12
+    ##@brief A boolean field
13
     def __init__(self, **kwargs):
13
     def __init__(self, **kwargs):
14
         if 'check_data_value' not in kwargs:
14
         if 'check_data_value' not in kwargs:
15
             kwargs['check_data_value'] = self.check_value
15
             kwargs['check_data_value'] = self.check_value
23
             error = TypeError("The value '%s' is not, and will never, be a boolean" % value)
23
             error = TypeError("The value '%s' is not, and will never, be a boolean" % value)
24
         return value, error
24
         return value, error
25
 
25
 
26
-## @brief Data field designed to handle integer values
26
+##@brief Data field designed to handle integer values
27
 class Integer(DataField):
27
 class Integer(DataField):
28
 
28
 
29
     help = 'Basic integer field'
29
     help = 'Basic integer field'
40
             error = TypeError("The value '%s' is not, and will never, be an integer" % value)
40
             error = TypeError("The value '%s' is not, and will never, be an integer" % value)
41
         return value, error
41
         return value, error
42
 
42
 
43
-## @brief Data field designed to handle string
43
+##@brief Data field designed to handle string
44
 class Varchar(DataField):
44
 class Varchar(DataField):
45
 
45
 
46
     help = 'Basic string (varchar) field. Default size is 64 characters'
46
     help = 'Basic string (varchar) field. Default size is 64 characters'
47
     base_type = 'char'
47
     base_type = 'char'
48
 
48
 
49
-    ## @brief A string field
49
+    ##@brief A string field
50
     # @brief max_length int: The maximum length of this field
50
     # @brief max_length int: The maximum length of this field
51
     def __init__(self, max_length=64, **kwargs):
51
     def __init__(self, max_length=64, **kwargs):
52
         self.max_length = int(max_length)
52
         self.max_length = int(max_length)
53
         super().__init__(**kwargs)
53
         super().__init__(**kwargs)
54
 
54
 
55
-    ## @brief checks if this class can override the given data handler
55
+    ##@brief checks if this class can override the given data handler
56
     # @param data_handler DataHandler
56
     # @param data_handler DataHandler
57
     # @return bool
57
     # @return bool
58
     def can_override(self, data_handler):
58
     def can_override(self, data_handler):
62
             return False
62
             return False
63
         return True
63
         return True
64
 
64
 
65
-## @brief Data field designed to handle date & time 
65
+##@brief Data field designed to handle date & time 
66
 class DateTime(DataField):
66
 class DateTime(DataField):
67
 
67
 
68
     help = 'A datetime field. Take two boolean options now_on_update and now_on_create'
68
     help = 'A datetime field. Take two boolean options now_on_update and now_on_create'
69
     base_type = 'datetime'
69
     base_type = 'datetime'
70
 
70
 
71
-    ## @brief A datetime field
71
+    ##@brief A datetime field
72
     # @param now_on_update bool : If true, the date is set to NOW on update
72
     # @param now_on_update bool : If true, the date is set to NOW on update
73
     # @param now_on_create bool : If true, the date is set to NEW on creation
73
     # @param now_on_create bool : If true, the date is set to NEW on creation
74
     # @param **kwargs
74
     # @param **kwargs
77
         self.now_on_create = now_on_create
77
         self.now_on_create = now_on_create
78
         super().__init__(**kwargs)
78
         super().__init__(**kwargs)
79
 
79
 
80
-## @brief Data field designed to handle long string
80
+##@brief Data field designed to handle long string
81
 class Text(DataField):
81
 class Text(DataField):
82
     help = 'A text field (big string)'
82
     help = 'A text field (big string)'
83
     base_type = 'text'
83
     base_type = 'text'
85
     def __init__(self, **kwargs):
85
     def __init__(self, **kwargs):
86
         super(self.__class__, self).__init__(ftype='text', **kwargs)
86
         super(self.__class__, self).__init__(ftype='text', **kwargs)
87
 
87
 
88
-## @brief Data field designed to handle Files
88
+##@brief Data field designed to handle Files
89
 class File(DataField):
89
 class File(DataField):
90
 
90
 
91
     base_type = 'file'
91
     base_type = 'file'
92
 
92
 
93
-    ## @brief a file field
93
+    ##@brief a file field
94
     # @param upload_path str : None by default
94
     # @param upload_path str : None by default
95
     # @param **kwargs
95
     # @param **kwargs
96
     def __init__(self, upload_path=None, **kwargs):
96
     def __init__(self, upload_path=None, **kwargs):

+ 11
- 11
lodel/leapi/datahandlers/references.py View File

3
 
3
 
4
 class Link(SingleRef): pass
4
 class Link(SingleRef): pass
5
 
5
 
6
-## @brief Child class of MultipleRef where references are represented in the form of a python list
6
+##@brief Child class of MultipleRef where references are represented in the form of a python list
7
 class List(MultipleRef):
7
 class List(MultipleRef):
8
 
8
 
9
-    ## @brief instanciates a list reference
9
+    ##@brief instanciates a list reference
10
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
10
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
11
     # @param internal bool
11
     # @param internal bool
12
     # @param kwargs
12
     # @param kwargs
13
     def __init__(self, max_length = None, **kwargs):
13
     def __init__(self, max_length = None, **kwargs):
14
         super().__init__(**kwargs)
14
         super().__init__(**kwargs)
15
 
15
 
16
-    ## @brief Check value
16
+    ##@brief Check value
17
     # @param value *
17
     # @param value *
18
     # @return tuple(value, exception)
18
     # @return tuple(value, exception)
19
     def _check_data_value(self, value):
19
     def _check_data_value(self, value):
24
         return val, expt
24
         return val, expt
25
 
25
 
26
 
26
 
27
-## @brief Child class of MultipleRef where references are represented in the form of a python set
27
+##@brief Child class of MultipleRef where references are represented in the form of a python set
28
 class Set(MultipleRef):
28
 class Set(MultipleRef):
29
 
29
 
30
-    ## @brief instanciates a set reference
30
+    ##@brief instanciates a set reference
31
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
31
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
32
     # @param internal bool : if False, the field is not internal
32
     # @param internal bool : if False, the field is not internal
33
     # @param kwargs : Other named arguments
33
     # @param kwargs : Other named arguments
34
     def __init__(self, **kwargs):
34
     def __init__(self, **kwargs):
35
         super().__init__(**kwargs)
35
         super().__init__(**kwargs)
36
 
36
 
37
-    ## @brief Check value
37
+    ##@brief Check value
38
     # @param value *
38
     # @param value *
39
     # @return tuple(value, exception)
39
     # @return tuple(value, exception)
40
     def _check_data_value(self, value):
40
     def _check_data_value(self, value):
45
         return val, expt
45
         return val, expt
46
 
46
 
47
 
47
 
48
-## @brief Child class of MultipleRef where references are represented in the form of a python dict
48
+##@brief Child class of MultipleRef where references are represented in the form of a python dict
49
 class Map(MultipleRef):
49
 class Map(MultipleRef):
50
 
50
 
51
-    ## @brief instanciates a dict reference
51
+    ##@brief instanciates a dict reference
52
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
52
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
53
     # @param internal bool : if False, the field is not internal
53
     # @param internal bool : if False, the field is not internal
54
     # @param kwargs : Other named arguments
54
     # @param kwargs : Other named arguments
55
     def __init__(self, **kwargs):
55
     def __init__(self, **kwargs):
56
         super().__init__(**kwargs)
56
         super().__init__(**kwargs)
57
 
57
 
58
-    ## @brief Check value
58
+    ##@brief Check value
59
     # @param value *
59
     # @param value *
60
     # @return tuple(value, exception)
60
     # @return tuple(value, exception)
61
     def _check_data_value(self, value):
61
     def _check_data_value(self, value):
66
                 None if isinstance(expt, Exception) else value,
66
                 None if isinstance(expt, Exception) else value,
67
                 expt)
67
                 expt)
68
 
68
 
69
-## @brief This Reference class is designed to handler hierarchy with some constraint
69
+##@brief This Reference class is designed to handler hierarchy with some constraint
70
 class Hierarch(MultipleRef):
70
 class Hierarch(MultipleRef):
71
     
71
     
72
-    ## @brief Instanciate a data handler handling hierarchical relation with constraints
72
+    ##@brief Instanciate a data handler handling hierarchical relation with constraints
73
     # @param back_reference tuple : Here it is mandatory to have a back ref (like a parent field)
73
     # @param back_reference tuple : Here it is mandatory to have a back ref (like a parent field)
74
     # @param max_depth int | None :  limit of depth
74
     # @param max_depth int | None :  limit of depth
75
     # @param max_childs int | Nine : maximum number of childs by nodes
75
     # @param max_childs int | Nine : maximum number of childs by nodes

+ 6
- 6
lodel/leapi/lefactory.py View File

5
 from lodel.leapi.leobject import LeObject
5
 from lodel.leapi.leobject import LeObject
6
 from lodel.leapi.datahandlers.base_classes import DataHandler
6
 from lodel.leapi.datahandlers.base_classes import DataHandler
7
 
7
 
8
-## @brief Generate python module code from a given model
8
+##@brief Generate python module code from a given model
9
 # @param model lodel.editorial_model.model.EditorialModel
9
 # @param model lodel.editorial_model.model.EditorialModel
10
 def dyncode_from_em(model):
10
 def dyncode_from_em(model):
11
     
11
     
31
     )
31
     )
32
     return res_code
32
     return res_code
33
 
33
 
34
-## @brief return A list of EmClass sorted by dependencies
34
+##@brief return A list of EmClass sorted by dependencies
35
 #
35
 #
36
 # The first elts in the list depends on nothing, etc.
36
 # The first elts in the list depends on nothing, etc.
37
 # @return a list of EmClass instances
37
 # @return a list of EmClass instances
41
     ret = sorted(emclass_list, key = functools.cmp_to_key(emclass_deps_cmp))
41
     ret = sorted(emclass_list, key = functools.cmp_to_key(emclass_deps_cmp))
42
     return ret
42
     return ret
43
 
43
 
44
-## @brief Returns a list of EmClass that will be represented as LeObject child classes
44
+##@brief Returns a list of EmClass that will be represented as LeObject child classes
45
 def get_classes(model):
45
 def get_classes(model):
46
     return [ cls for cls in emclass_sorted_by_deps(model.classes()) if not cls.pure_abstract ]
46
     return [ cls for cls in emclass_sorted_by_deps(model.classes()) if not cls.pure_abstract ]
47
 
47
 
48
-## @brief Given an EmField returns the data_handler constructor suitable for dynamic code
48
+##@brief Given an EmField returns the data_handler constructor suitable for dynamic code
49
 def data_handler_constructor(emfield):
49
 def data_handler_constructor(emfield):
50
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
50
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
51
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
51
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
63
                                                         handler_instr = get_handler_class_instr,
63
                                                         handler_instr = get_handler_class_instr,
64
                                                         options = ', '.join(options))
64
                                                         options = ', '.join(options))
65
             
65
             
66
-## @brief Return a python repr of option values
66
+##@brief Return a python repr of option values
67
 def forge_optval(optval):
67
 def forge_optval(optval):
68
     if isinstance(optval, dict):
68
     if isinstance(optval, dict):
69
         return '{' + (', '.join( [ '%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
69
         return '{' + (', '.join( [ '%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
81
     else:
81
     else:
82
         return repr(optval)
82
         return repr(optval)
83
 
83
 
84
-## @brief Generate dyncode from an EmClass
84
+##@brief Generate dyncode from an EmClass
85
 # @param model EditorialModel : 
85
 # @param model EditorialModel : 
86
 # @param emclass EmClass : EmClass instance
86
 # @param emclass EmClass : EmClass instance
87
 # @return a tuple with emclass python code, a set containing modules name to import, and a list of python instruction to bootstrap dynamic code, in this order
87
 # @return a tuple with emclass python code, a set containing modules name to import, and a list of python instruction to bootstrap dynamic code, in this order

+ 23
- 23
lodel/leapi/leobject.py View File

3
 import importlib
3
 import importlib
4
 
4
 
5
 class LeApiErrors(Exception):
5
 class LeApiErrors(Exception):
6
-    ## @brief Instanciate a new exceptions handling multiple exceptions
6
+    ##@brief Instanciate a new exceptions handling multiple exceptions
7
     # @param msg str : Exception message
7
     # @param msg str : Exception message
8
     # @param exceptions dict : A list of data check Exception with concerned field (or stuff) as key
8
     # @param exceptions dict : A list of data check Exception with concerned field (or stuff) as key
9
     def __init__(self, msg = "Unknow error", exceptions = None):
9
     def __init__(self, msg = "Unknow error", exceptions = None):
25
         return msg
25
         return msg
26
 
26
 
27
 
27
 
28
-## @brief When an error concern a query
28
+##@brief When an error concern a query
29
 class LeApiQueryError(LeApiErrors):
29
 class LeApiQueryError(LeApiErrors):
30
     pass
30
     pass
31
 
31
 
32
 
32
 
33
-## @brief When an error concerns a datas
33
+##@brief When an error concerns a datas
34
 class LeApiDataCheckError(LeApiErrors):
34
 class LeApiDataCheckError(LeApiErrors):
35
     pass
35
     pass
36
 
36
 
37
 
37
 
38
-## @brief Wrapper class for LeObject getter & setter
38
+##@brief Wrapper class for LeObject getter & setter
39
 #
39
 #
40
 # This class intend to provide easy & friendly access to LeObject fields values 
40
 # This class intend to provide easy & friendly access to LeObject fields values 
41
 # without name collision problems
41
 # without name collision problems
42
 # @note Wrapped methods are : LeObject.data() & LeObject.set_data()
42
 # @note Wrapped methods are : LeObject.data() & LeObject.set_data()
43
 class LeObjectValues(object):
43
 class LeObjectValues(object):
44
     
44
     
45
-    ## @brief Construct a new LeObjectValues
45
+    ##@brief Construct a new LeObjectValues
46
     # @param set_callback method : The LeObject.set_datas() method of corresponding LeObject class
46
     # @param set_callback method : The LeObject.set_datas() method of corresponding LeObject class
47
     # @param get_callback method : The LeObject.get_datas() method of corresponding LeObject class
47
     # @param get_callback method : The LeObject.get_datas() method of corresponding LeObject class
48
     def __init__(self, fieldnames_callback, set_callback, get_callback):
48
     def __init__(self, fieldnames_callback, set_callback, get_callback):
49
         self.__setter = set_callback
49
         self.__setter = set_callback
50
         self.__getter = get_callback
50
         self.__getter = get_callback
51
     
51
     
52
-    ## @brief Provide read access to datas values
52
+    ##@brief Provide read access to datas values
53
     # @note Read access should be provided for all fields
53
     # @note Read access should be provided for all fields
54
     # @param fname str : Field name
54
     # @param fname str : Field name
55
     def __getattribute__(self, fname):
55
     def __getattribute__(self, fname):
56
         return self.__getter(fname)
56
         return self.__getter(fname)
57
     
57
     
58
-    ## @brief Provide write access to datas values
58
+    ##@brief Provide write access to datas values
59
     # @note Write acces shouldn't be provided for internal or immutable fields
59
     # @note Write acces shouldn't be provided for internal or immutable fields
60
     # @param fname str : Field name
60
     # @param fname str : Field name
61
     # @param fval * : the field value
61
     # @param fval * : the field value
65
 
65
 
66
 class LeObject(object):
66
 class LeObject(object):
67
  
67
  
68
-    ## @brief boolean that tells if an object is abtract or not
68
+    ##@brief boolean that tells if an object is abtract or not
69
     _abstract = None
69
     _abstract = None
70
-    ## @brief A dict that stores DataHandler instances indexed by field name
70
+    ##@brief A dict that stores DataHandler instances indexed by field name
71
     _fields = None
71
     _fields = None
72
-    ## @brief A tuple of fieldname (or a uniq fieldname) representing uid
72
+    ##@brief A tuple of fieldname (or a uniq fieldname) representing uid
73
     _uid = None 
73
     _uid = None 
74
 
74
 
75
-    ## @brief Construct an object representing an Editorial component
75
+    ##@brief Construct an object representing an Editorial component
76
     # @note Can be considered as EmClass instance
76
     # @note Can be considered as EmClass instance
77
     def __init__(self, **kwargs):
77
     def __init__(self, **kwargs):
78
         if self._abstract:
78
         if self._abstract:
79
             raise NotImplementedError("%s is abstract, you cannot instanciate it." % self.__class__.__name__ )
79
             raise NotImplementedError("%s is abstract, you cannot instanciate it." % self.__class__.__name__ )
80
-        ## @brief A dict that stores fieldvalues indexed by fieldname
80
+        ##@brief A dict that stores fieldvalues indexed by fieldname
81
         self.__datas = { fname:None for fname in self._fields }
81
         self.__datas = { fname:None for fname in self._fields }
82
-        ## @brief Store a list of initianilized fields when instanciation not complete else store True
82
+        ##@brief Store a list of initianilized fields when instanciation not complete else store True
83
         self.__initialized = list()
83
         self.__initialized = list()
84
-        ## @brief Datas accessor. Instance of @ref LeObjectValues
84
+        ##@brief Datas accessor. Instance of @ref LeObjectValues
85
         self.d = LeObjectValues(self.fieldnames, self.set_data, self.data)
85
         self.d = LeObjectValues(self.fieldnames, self.set_data, self.data)
86
 
86
 
87
         # Checks that uid is given
87
         # Checks that uid is given
114
     #   Fields datas handling methods   #
114
     #   Fields datas handling methods   #
115
     #-----------------------------------#
115
     #-----------------------------------#
116
 
116
 
117
-    ## @brief @property True if LeObject is initialized else False
117
+    ##@brief @property True if LeObject is initialized else False
118
     @property
118
     @property
119
     def initialized(self):
119
     def initialized(self):
120
         return not isinstance(self.__initialized, list)
120
         return not isinstance(self.__initialized, list)
121
 
121
 
122
-    ## @brief Return a list of fieldnames
122
+    ##@brief Return a list of fieldnames
123
     # @param include_ro bool : if True include read only field names
123
     # @param include_ro bool : if True include read only field names
124
     # @return a list of str
124
     # @return a list of str
125
     @classmethod
125
     @classmethod
133
     def name2objname(cls, name):
133
     def name2objname(cls, name):
134
         return name.title()
134
         return name.title()
135
     
135
     
136
-    ## @brief Return the datahandler asssociated with a LeObject field
136
+    ##@brief Return the datahandler asssociated with a LeObject field
137
     # @param fieldname str : The fieldname
137
     # @param fieldname str : The fieldname
138
     # @return A data handler instance
138
     # @return A data handler instance
139
     @classmethod
139
     @classmethod
142
             raise NameError("No field named '%s' in %s" % (fieldname, cls.__name__))
142
             raise NameError("No field named '%s' in %s" % (fieldname, cls.__name__))
143
         return cls._fields[fieldname]
143
         return cls._fields[fieldname]
144
  
144
  
145
-    ## @brief Return a LeObject child class from a name
145
+    ##@brief Return a LeObject child class from a name
146
     # @warning This method has to be called from dynamically generated LeObjects
146
     # @warning This method has to be called from dynamically generated LeObjects
147
     # @param leobject_name str : LeObject name
147
     # @param leobject_name str : LeObject name
148
     # @return A LeObject child class
148
     # @return A LeObject child class
161
     def is_abstract(cls):
161
     def is_abstract(cls):
162
         return cls._abstract
162
         return cls._abstract
163
 
163
 
164
-    ## @brief Read only access to all datas
164
+    ##@brief Read only access to all datas
165
     # @note for fancy data accessor use @ref LeObject.g attribute @ref LeObjectValues instance
165
     # @note for fancy data accessor use @ref LeObject.g attribute @ref LeObjectValues instance
166
     # @param name str : field name
166
     # @param name str : field name
167
     # @return the Value
167
     # @return the Value
174
             raise RuntimeError("The field %s is not initialized yet (and have no value)" % name)
174
             raise RuntimeError("The field %s is not initialized yet (and have no value)" % name)
175
         return self.__datas[name]
175
         return self.__datas[name]
176
     
176
     
177
-    ## @brief Datas setter
177
+    ##@brief Datas setter
178
     # @note for fancy data accessor use @ref LeObject.g attribute @ref LeObjectValues instance
178
     # @note for fancy data accessor use @ref LeObject.g attribute @ref LeObjectValues instance
179
     # @param fname str : field name
179
     # @param fname str : field name
180
     # @param fval * : field value
180
     # @param fval * : field value
211
             else:
211
             else:
212
                 self.__datas[fname] = val
212
                 self.__datas[fname] = val
213
     
213
     
214
-    ## @brief Update the __initialized attribute according to LeObject internal state
214
+    ##@brief Update the __initialized attribute according to LeObject internal state
215
     #
215
     #
216
     # Check the list of initialized fields and set __initialized to True if all fields initialized
216
     # Check the list of initialized fields and set __initialized to True if all fields initialized
217
     def __set_initialized(self):
217
     def __set_initialized(self):
220
             if set(expected_fields) == set(self.__initialized):
220
             if set(expected_fields) == set(self.__initialized):
221
                 self.__initialized = True
221
                 self.__initialized = True
222
 
222
 
223
-    ## @brief Designed to be called when datas are modified
223
+    ##@brief Designed to be called when datas are modified
224
     #
224
     #
225
     # Make different checks on the LeObject given it's state (fully initialized or not)
225
     # Make different checks on the LeObject given it's state (fully initialized or not)
226
     # @return None if checks succeded else return an exception list
226
     # @return None if checks succeded else return an exception list
267
     #   Other methods    #
267
     #   Other methods    #
268
     #--------------------#
268
     #--------------------#
269
     
269
     
270
-    ## @brief Temporary method to set private fields attribute at dynamic code generation
270
+    ##@brief Temporary method to set private fields attribute at dynamic code generation
271
     #
271
     #
272
     # This method is used in the generated dynamic code to set the _fields attribute
272
     # This method is used in the generated dynamic code to set the _fields attribute
273
     # at the end of the dyncode parse
273
     # at the end of the dyncode parse

+ 23
- 23
lodel/leapi/query.py View File

9
 
9
 
10
 class LeQuery(object):
10
 class LeQuery(object):
11
 
11
 
12
-    ## @brief The datasource object used for this query
12
+    ##@brief The datasource object used for this query
13
     datasource = None
13
     datasource = None
14
 
14
 
15
-    ## @brief The available operators used in query definitions
15
+    ##@brief The available operators used in query definitions
16
     query_operators = ['=', '<=', '>=', '!=', '<', '>', ' in ', ' not in ', ' like ', ' not like ']
16
     query_operators = ['=', '<=', '>=', '!=', '<', '>', ' in ', ' not in ', ' like ', ' not like ']
17
 
17
 
18
-    ## @brief Constructor
18
+    ##@brief Constructor
19
     # @param target_class EmClass : class of the object to query about
19
     # @param target_class EmClass : class of the object to query about
20
     def __init__(self, target_class):
20
     def __init__(self, target_class):
21
         if not issubclass(target_class, LeObject):
21
         if not issubclass(target_class, LeObject):
23
         self.target_class = target_class
23
         self.target_class = target_class
24
 
24
 
25
 
25
 
26
-## @brief Class representing an Insert query
26
+##@brief Class representing an Insert query
27
 class LeInsertQuery(LeQuery):
27
 class LeInsertQuery(LeQuery):
28
 
28
 
29
-    ## @brief Constructor
29
+    ##@brief Constructor
30
     # @param target_class EmClass: class corresponding to the inserted object
30
     # @param target_class EmClass: class corresponding to the inserted object
31
     # @param datas dict : datas to insert
31
     # @param datas dict : datas to insert
32
     def __init__(self, target_class, datas):
32
     def __init__(self, target_class, datas):
33
         super().__init__(target_class)
33
         super().__init__(target_class)
34
         self.datas = datas
34
         self.datas = datas
35
 
35
 
36
-    ## @brief executes the insert query
36
+    ##@brief executes the insert query
37
     # @return bool
37
     # @return bool
38
     # @TODO reactivate the LodelHooks call when this class is implemented
38
     # @TODO reactivate the LodelHooks call when this class is implemented
39
     def execute(self):
39
     def execute(self):
42
         # ret = LodelHook.call_hook('leapi_insert_post', self.target_class, ret)
42
         # ret = LodelHook.call_hook('leapi_insert_post', self.target_class, ret)
43
         return ret
43
         return ret
44
 
44
 
45
-    ## @brief calls the datasource to perform the insert command
45
+    ##@brief calls the datasource to perform the insert command
46
     # @param datas dict : formatted datas corresponding to the insert
46
     # @param datas dict : formatted datas corresponding to the insert
47
     # @return str : the uid of the inserted object
47
     # @return str : the uid of the inserted object
48
     def __insert(self, **datas):
48
     def __insert(self, **datas):
51
         return res
51
         return res
52
 
52
 
53
 
53
 
54
-## @brief Class representing an Abstract Filtered Query
54
+##@brief Class representing an Abstract Filtered Query
55
 class LeFilteredQuery(LeQuery):
55
 class LeFilteredQuery(LeQuery):
56
 
56
 
57
-    ## @brief Constructor
57
+    ##@brief Constructor
58
     # @param target_class EmClass : Object of the query
58
     # @param target_class EmClass : Object of the query
59
     def __init__(self, target_class):
59
     def __init__(self, target_class):
60
         super().__init__(target_class)
60
         super().__init__(target_class)
61
 
61
 
62
-    ## @brief Validates the query filters
62
+    ##@brief Validates the query filters
63
     # @param query_filters list
63
     # @param query_filters list
64
     # @return bool
64
     # @return bool
65
     # @raise LeQueryError if one of the filter is not valid
65
     # @raise LeQueryError if one of the filter is not valid
70
                 raise LeQueryError("The operator %s is not valid." % query_filter[1])
70
                 raise LeQueryError("The operator %s is not valid." % query_filter[1])
71
         return True
71
         return True
72
 
72
 
73
-    ## @brief Checks if a field is relational
73
+    ##@brief Checks if a field is relational
74
     # @param field str : Name of the field
74
     # @param field str : Name of the field
75
     # @return bool
75
     # @return bool
76
     @classmethod
76
     @classmethod
78
         return field.startswith('superior.') or field.startswith('subordinate.')
78
         return field.startswith('superior.') or field.startswith('subordinate.')
79
 
79
 
80
 
80
 
81
-## @brief Class representing a Get Query
81
+##@brief Class representing a Get Query
82
 class LeGetQuery(LeFilteredQuery):
82
 class LeGetQuery(LeFilteredQuery):
83
 
83
 
84
-    ## @brief Constructor
84
+    ##@brief Constructor
85
     # @param target_class EmClass : main class
85
     # @param target_class EmClass : main class
86
     # @param query_filters
86
     # @param query_filters
87
     # @param field_list list
87
     # @param field_list list
101
         self.offset = offset
101
         self.offset = offset
102
         self.instanciate = instanciate
102
         self.instanciate = instanciate
103
 
103
 
104
-    ## @brief executes the query
104
+    ##@brief executes the query
105
     # @return list
105
     # @return list
106
     # @TODO activate LodelHook calls
106
     # @TODO activate LodelHook calls
107
     def execute(self):
107
     def execute(self):
137
         results = self._datasource.select()  # TODO add the correct arguments for the datasource's method call
137
         results = self._datasource.select()  # TODO add the correct arguments for the datasource's method call
138
         return results
138
         return results
139
 
139
 
140
-    ## @brief prepares the field list
140
+    ##@brief prepares the field list
141
     # @return list
141
     # @return list
142
     # @raise LeApiDataCheckError
142
     # @raise LeApiDataCheckError
143
     def __prepare_field_list(self):
143
     def __prepare_field_list(self):
159
 
159
 
160
         return ret_field_list
160
         return ret_field_list
161
 
161
 
162
-    ## @brief prepares a relational field
162
+    ##@brief prepares a relational field
163
     def __prepare_relational_field(self, field):
163
     def __prepare_relational_field(self, field):
164
         # TODO Implement the method
164
         # TODO Implement the method
165
         return field
165
         return field
166
 
166
 
167
-    ## @brief splits the filter string into a tuple (FIELD, OPERATOR, VALUE)
167
+    ##@brief splits the filter string into a tuple (FIELD, OPERATOR, VALUE)
168
     # @param filter str
168
     # @param filter str
169
     # @return tuple
169
     # @return tuple
170
     # @raise ValueError
170
     # @raise ValueError
190
         op_re_piece += ')'
190
         op_re_piece += ')'
191
         self.query_re = re.compile('^\s*(?P<field>(((superior)|(subordinate))\.)?[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>[^<>=!].*)\s*$', flags=re.IGNORECASE)
191
         self.query_re = re.compile('^\s*(?P<field>(((superior)|(subordinate))\.)?[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>[^<>=!].*)\s*$', flags=re.IGNORECASE)
192
 
192
 
193
-    ## @brief checks if a field is in the target class of the query
193
+    ##@brief checks if a field is in the target class of the query
194
     # @param field str
194
     # @param field str
195
     # @return str
195
     # @return str
196
     # @raise ValueError
196
     # @raise ValueError
199
             return ValueError("No such field '%s' in %s" % (field, self.target_class))
199
             return ValueError("No such field '%s' in %s" % (field, self.target_class))
200
         return field
200
         return field
201
 
201
 
202
-    ## @brief Prepares the filters (relational and others)
202
+    ##@brief Prepares the filters (relational and others)
203
     # @return tuple
203
     # @return tuple
204
     def __prepare_filters(self):
204
     def __prepare_filters(self):
205
         filters = list()
205
         filters = list()
234
         datas['target_class'] = self.target_class
234
         datas['target_class'] = self.target_class
235
         return datas
235
         return datas
236
 
236
 
237
-    ## @brief prepares the "order" parameters
237
+    ##@brief prepares the "order" parameters
238
     # @return list
238
     # @return list
239
     def __prepare_order(self):
239
     def __prepare_order(self):
240
         errors = dict()
240
         errors = dict()
269
         # ret = LodelHook.call_hook('leapi_update_post', self.target_object, ret)
269
         # ret = LodelHook.call_hook('leapi_update_post', self.target_object, ret)
270
         return ret
270
         return ret
271
 
271
 
272
-    ## @brief calls the datasource's update method and the corresponding hooks
272
+    ##@brief calls the datasource's update method and the corresponding hooks
273
     # @return bool
273
     # @return bool
274
     # @TODO change the behavior in case of error in the update process
274
     # @TODO change the behavior in case of error in the update process
275
     def __update(self):
275
     def __update(self):
280
         else:
280
         else:
281
             return False
281
             return False
282
 
282
 
283
-    ## @brief prepares the query_filters to be used as argument for the datasource's update method
283
+    ##@brief prepares the query_filters to be used as argument for the datasource's update method
284
     def __prepare(self):
284
     def __prepare(self):
285
         datas = dict()
285
         datas = dict()
286
         if LeFilteredQuery.validate_query_filters(self.query_filters):
286
         if LeFilteredQuery.validate_query_filters(self.query_filters):
304
         # ret = LodelHook.call('leapi_delete_post', self.target_object, ret)
304
         # ret = LodelHook.call('leapi_delete_post', self.target_object, ret)
305
         return ret
305
         return ret
306
 
306
 
307
-    ## @brief calls the datasource's delete method
307
+    ##@brief calls the datasource's delete method
308
     # @return bool
308
     # @return bool
309
     # @TODO change the behavior in case of error in the update process
309
     # @TODO change the behavior in case of error in the update process
310
     def __delete(self):
310
     def __delete(self):

+ 4
- 4
lodel/logger.py View File

23
     for name, logging_opt in Settings.logging.items():
23
     for name, logging_opt in Settings.logging.items():
24
         add_handler(name, logging_opt)
24
         add_handler(name, logging_opt)
25
 
25
 
26
-## @brief Add an handler, identified by a name, to a given logger 
26
+##@brief Add an handler, identified by a name, to a given logger 
27
 #
27
 #
28
 # logging_opt is a dict with logger option. Allowed keys are : 
28
 # logging_opt is a dict with logger option. Allowed keys are : 
29
 # - filename : take a filepath as value and cause the use of a logging.handlers.RotatingFileHandler
29
 # - filename : take a filepath as value and cause the use of a logging.handlers.RotatingFileHandler
67
     logger.addHandler(handler)
67
     logger.addHandler(handler)
68
     
68
     
69
 
69
 
70
-## @brief Remove an handler generated from configuration (runtime logger configuration)
70
+##@brief Remove an handler generated from configuration (runtime logger configuration)
71
 # @param name str : handler name
71
 # @param name str : handler name
72
 def remove_handler(name):
72
 def remove_handler(name):
73
     if name in handlers:
73
     if name in handlers:
74
         logger.removeHandler(handlers[name])
74
         logger.removeHandler(handlers[name])
75
     # else: can we do anything ?
75
     # else: can we do anything ?
76
 
76
 
77
-## @brief Utility function that disable unconditionnaly handlers that implies console output
77
+##@brief Utility function that disable unconditionnaly handlers that implies console output
78
 # @note In fact, this function disables handlers generated from settings wich are instances of logging.StreamHandler
78
 # @note In fact, this function disables handlers generated from settings wich are instances of logging.StreamHandler
79
 def remove_console_handlers():
79
 def remove_console_handlers():
80
     for name, handler in handlers.items():
80
     for name, handler in handlers.items():
84
 
84
 
85
 # Utility functions
85
 # Utility functions
86
 
86
 
87
-## @brief Generic logging function
87
+##@brief Generic logging function
88
 # @param lvl int : Log severity
88
 # @param lvl int : Log severity
89
 # @param msg str : log message
89
 # @param msg str : log message
90
 # @param *args : additional positionnal arguments
90
 # @param *args : additional positionnal arguments

+ 10
- 10
lodel/plugin/hooks.py View File

4
 import copy
4
 import copy
5
 from importlib.machinery import SourceFileLoader
5
 from importlib.machinery import SourceFileLoader
6
 
6
 
7
-## @brief Class designed to handle a hook's callback with a priority
7
+##@brief Class designed to handle a hook's callback with a priority
8
 class DecoratedWrapper(object):
8
 class DecoratedWrapper(object):
9
-    ## @brief Constructor
9
+    ##@brief Constructor
10
     # @param hook function : the function to wrap
10
     # @param hook function : the function to wrap
11
     # @param priority int : the callbacl priority
11
     # @param priority int : the callbacl priority
12
     def __init__(self, hook, priority):
12
     def __init__(self, hook, priority):
13
         self._priority = priority
13
         self._priority = priority
14
         self._hook = hook
14
         self._hook = hook
15
     
15
     
16
-    ## @brief Call the callback
16
+    ##@brief Call the callback
17
     # @param hook_name str : The name of the called hook
17
     # @param hook_name str : The name of the called hook
18
     # @param caller * : The caller (depends on the hook)
18
     # @param caller * : The caller (depends on the hook)
19
     # @param payload * : Datas that depends on the hook
19
     # @param payload * : Datas that depends on the hook
21
     def __call__(self, hook_name, caller, payload):
21
     def __call__(self, hook_name, caller, payload):
22
         return self._hook(hook_name, caller, payload)
22
         return self._hook(hook_name, caller, payload)
23
 
23
 
24
-## @brief Decorator designed to register hook's callbacks
24
+##@brief Decorator designed to register hook's callbacks
25
 #
25
 #
26
 # @note Decorated functions are expected to take 3 arguments :
26
 # @note Decorated functions are expected to take 3 arguments :
27
 #  - hook_name : the called hook name
27
 #  - hook_name : the called hook name
29
 #  - payload : datas depending on the hook
29
 #  - payload : datas depending on the hook
30
 class LodelHook(object):
30
 class LodelHook(object):
31
     
31
     
32
-    ## @brief Stores all hooks (DecoratedWrapper instances)
32
+    ##@brief Stores all hooks (DecoratedWrapper instances)
33
     _hooks = dict()
33
     _hooks = dict()
34
     
34
     
35
-    ## @brief Decorator constructor
35
+    ##@brief Decorator constructor
36
     # @param hook_name str : the name of the hook to register to
36
     # @param hook_name str : the name of the hook to register to
37
     # @param priority int : the hook priority
37
     # @param priority int : the hook priority
38
     def __init__(self, hook_name, priority = None):
38
     def __init__(self, hook_name, priority = None):
39
         self._hook_name = hook_name
39
         self._hook_name = hook_name
40
         self._priority = 0xFFFF if priority is None else priority
40
         self._priority = 0xFFFF if priority is None else priority
41
     
41
     
42
-    ## @brief called just after __init__
42
+    ##@brief called just after __init__
43
     # @param hook function : the decorated function
43
     # @param hook function : the decorated function
44
     # @return the hook argument
44
     # @return the hook argument
45
     def __call__(self, hook):
45
     def __call__(self, hook):
50
         self._hooks[self._hook_name] = sorted(self._hooks[self._hook_name], key = lambda h: h._priority)
50
         self._hooks[self._hook_name] = sorted(self._hooks[self._hook_name], key = lambda h: h._priority)
51
         return hook
51
         return hook
52
 
52
 
53
-    ## @brief Call hooks
53
+    ##@brief Call hooks
54
     # @param hook_name str : the hook's name
54
     # @param hook_name str : the hook's name
55
     # @param caller * : the hook caller (depends on the hook)
55
     # @param caller * : the hook caller (depends on the hook)
56
     # @param payload * : datas for the hook
56
     # @param payload * : datas for the hook
63
                 payload = hook(hook_name, caller, payload)
63
                 payload = hook(hook_name, caller, payload)
64
         return payload
64
         return payload
65
     
65
     
66
-    ## @brief Fetch registered hooks
66
+    ##@brief Fetch registered hooks
67
     # @param names list | None : optionnal filter on name
67
     # @param names list | None : optionnal filter on name
68
     # @param cls
68
     # @param cls
69
     # @return a list of functions
69
     # @return a list of functions
76
             res = copy.copy(cls._hooks)
76
             res = copy.copy(cls._hooks)
77
         return { name: [(hook._hook, hook._priority) for hook in hooks] for name, hooks in res.items() }
77
         return { name: [(hook._hook, hook._priority) for hook in hooks] for name, hooks in res.items() }
78
     
78
     
79
-    ## @brief Unregister all hooks
79
+    ##@brief Unregister all hooks
80
     # @param cls
80
     # @param cls
81
     # @warning REALLY NOT a good idea !
81
     # @warning REALLY NOT a good idea !
82
     # @note implemented for testing purpose
82
     # @note implemented for testing purpose

+ 7
- 7
lodel/plugin/plugins.py View File

12
 # - main.py containing hooks registration etc
12
 # - main.py containing hooks registration etc
13
 # - confspec.py containing a configuration specification dictionary named CONFSPEC
13
 # - confspec.py containing a configuration specification dictionary named CONFSPEC
14
 
14
 
15
-## @brief The package in wich we will load plugins modules
15
+##@brief The package in wich we will load plugins modules
16
 VIRTUAL_PACKAGE_NAME = 'lodel.plugins_pkg'
16
 VIRTUAL_PACKAGE_NAME = 'lodel.plugins_pkg'
17
 CONFSPEC_FILENAME = 'confspec.py'
17
 CONFSPEC_FILENAME = 'confspec.py'
18
 MAIN_FILENAME = 'main.py'
18
 MAIN_FILENAME = 'main.py'
23
 
23
 
24
 class Plugins(object):
24
 class Plugins(object):
25
     
25
     
26
-    ## @brief Stores plugin directories paths
26
+    ##@brief Stores plugin directories paths
27
     _plugin_directories = None
27
     _plugin_directories = None
28
-    ## @brief Optimisation cache storage for plugin paths
28
+    ##@brief Optimisation cache storage for plugin paths
29
     _plugin_paths = dict()
29
     _plugin_paths = dict()
30
 
30
 
31
     def __init__(self): # may be useless
31
     def __init__(self): # may be useless
32
         self.started()
32
         self.started()
33
     
33
     
34
-    ## @brief Given a plugin name returns the plugin path
34
+    ##@brief Given a plugin name returns the plugin path
35
     # @param plugin_name str : The plugin name
35
     # @param plugin_name str : The plugin name
36
     # @return the plugin directory path
36
     # @return the plugin directory path
37
     @classmethod
37
     @classmethod
50
                 return plugin_path
50
                 return plugin_path
51
         raise NameError("No plugin named '%s'" % plugin_name)
51
         raise NameError("No plugin named '%s'" % plugin_name)
52
 
52
 
53
-    ## @brief Fetch a confspec given a plugin_name
53
+    ##@brief Fetch a confspec given a plugin_name
54
     # @param plugin_name str : The plugin name
54
     # @param plugin_name str : The plugin name
55
     # @return a dict of conf spec
55
     # @return a dict of conf spec
56
     # @throw PluginError if plugin_name is not valid
56
     # @throw PluginError if plugin_name is not valid
70
             raise PluginError("Failed to load plugin '%s'. It seems that the plugin name is not valid" % plugin_name)
70
             raise PluginError("Failed to load plugin '%s'. It seems that the plugin name is not valid" % plugin_name)
71
         return getattr(confspec_module, CONFSPEC_VARNAME)
71
         return getattr(confspec_module, CONFSPEC_VARNAME)
72
  
72
  
73
-    ## @brief Load a module to register plugin's hooks
73
+    ##@brief Load a module to register plugin's hooks
74
     # @param plugin_name str : The plugin name
74
     # @param plugin_name str : The plugin name
75
     @classmethod
75
     @classmethod
76
     def load_plugin(cls, plugin_name):
76
     def load_plugin(cls, plugin_name):
86
         except ImportError:
86
         except ImportError:
87
             raise PluginError("Failed to load plugin '%s'. It seems that the plugin name is not valid" % plugin_name)
87
             raise PluginError("Failed to load plugin '%s'. It seems that the plugin name is not valid" % plugin_name)
88
         
88
         
89
-    ## @brief Bootstrap the Plugins class
89
+    ##@brief Bootstrap the Plugins class
90
     @classmethod
90
     @classmethod
91
     def bootstrap(cls, plugins_directories):
91
     def bootstrap(cls, plugins_directories):
92
         cls._plugin_directories = plugins_directories
92
         cls._plugin_directories = plugins_directories

+ 28
- 0
lodel/settings/__init__.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 
2
 
3
+## @package lodel.settings Lodel2 settings package
4
+# 
5
+# @par Bootstrap/load/use in lodel instance
6
+# To use Settings in production you have to write a loader that will bootstrap
7
+# the Settings class allowing @ref lodel.settings.__init__.py to expose a copy
8
+# of the lodel.settings.Settings representation of the
9
+# @ref lodel.settings.settings.Settings.__confs . Here is an example of 
10
+# loader file :
11
+# <pre>
12
+# #-*- coding: utf-8 -*-
13
+# from lodel.settings.settings import Settings
14
+# Settings.bootstrap(
15
+#                       conf_file = 'somepath/settings_local.ini',
16
+#                       conf_dir = 'somepath/conf.d')
17
+# </pre>
18
+# Once this file is imported it allows to all lodel2 modules to use settings
19
+# like this :
20
+# <pre>
21
+# from lodel.settings import Settings
22
+# if Settings.debug:
23
+#   print("DEBUG MODE !")
24
+# </pre>
25
+#
26
+
3
 from lodel.settings.settings import Settings as SettingsHandler
27
 from lodel.settings.settings import Settings as SettingsHandler
28
+
29
+##@brief Bootstraped instance
4
 settings = SettingsHandler.bootstrap()
30
 settings = SettingsHandler.bootstrap()
5
 if settings is not None:
31
 if settings is not None:
32
+    ##@brief Exposed variable that represents configurations values in a
33
+    # namedtuple tree
6
     Settings = settings.confs
34
     Settings = settings.confs

+ 30
- 26
lodel/settings/settings.py View File

12
 from lodel.settings.validator import SettingValidator, LODEL2_CONF_SPECS
12
 from lodel.settings.validator import SettingValidator, LODEL2_CONF_SPECS
13
 from lodel.settings.settings_loader import SettingsLoader
13
 from lodel.settings.settings_loader import SettingsLoader
14
 
14
 
15
-## @package lodel.settings Lodel2 settings package
16
-#
17
-# Contains all module that help handling settings
18
-
19
 ## @package lodel.settings.settings Lodel2 settings module
15
 ## @package lodel.settings.settings Lodel2 settings module
20
 #
16
 #
21
 # Handles configuration load/parse/check.
17
 # Handles configuration load/parse/check.
22
 #
18
 #
23
 # @subsection Configuration load process
19
 # @subsection Configuration load process
24
 #
20
 #
25
-# The configuration load process is not trivial. In fact loaded plugins are able to add their own options.
26
-# But the list of plugins to load and the plugins options are in the same file, the instance configuration file.
21
+# The configuration load process is not trivial. In fact loaded plugins are 
22
+# able to add their own options. But the list of plugins to load and the 
23
+# plugins options are in the same file, the instance configuration file.
27
 #
24
 #
28
 # @subsection Configuration specification
25
 # @subsection Configuration specification
29
 #
26
 #
32
 # - value validation/cast (see @ref Lodel.settings.validator.ConfValidator )
29
 # - value validation/cast (see @ref Lodel.settings.validator.ConfValidator )
33
30
34
 
31
 
35
-## @brief A default python system lib path
32
+##@brief A default python system lib path
36
 PYTHON_SYS_LIB_PATH = '/usr/local/lib/python{major}.{minor}/'.format(
33
 PYTHON_SYS_LIB_PATH = '/usr/local/lib/python{major}.{minor}/'.format(
37
 
34
 
38
-                                                                        major = sys.version_info.major,
39
-                                                                        minor = sys.version_info.minor)
40
-## @brief Handles configuration load etc.
35
+                                                major = sys.version_info.major,
36
+                                                minor = sys.version_info.minor)
37
+##@brief Handles configuration load etc.
41
 #
38
 #
42
-# @par Basic usage
39
+# To see howto bootstrap Settings and use it in lodel instance see 
40
+# @ref lodel.settings
41
+# 
42
+# @par Basic instance usage
43
 # For example if a file defines confs like :
43
 # For example if a file defines confs like :
44
 # <pre>
44
 # <pre>
45
 # [super_section]
45
 # [super_section]
49
 # <pre> settings_instance.confs.super_section.super_conf </pre>
49
 # <pre> settings_instance.confs.super_section.super_conf </pre>
50
 #
50
 #
51
 # @par Init sequence
51
 # @par Init sequence
52
-# The initialization sequence is a bit tricky. In fact, plugins adds allowed configuration 
53
-# sections/values, but the list of plugins to load in in... the settings.
52
+# The initialization sequence is a bit tricky. In fact, plugins adds allowed
53
+# configuration sections/values, but the list of plugins to load in in... the 
54
+# settings.
54
 # Here is the conceptual presentation of Settings class initialization stages :
55
 # Here is the conceptual presentation of Settings class initialization stages :
55
 #   -# Preloading (sets values like lodel2 library path or the plugins path)
56
 #   -# Preloading (sets values like lodel2 library path or the plugins path)
56
-#   -# Ask a @ref lodel.settings.setting_loader.SettingsLoader to load all configurations files
57
+#   -# Ask a @ref lodel.settings.setting_loader.SettingsLoader to load all 
58
+#configurations files
57
 #   -# Fetch the list of plugins in the loaded settings
59
 #   -# Fetch the list of plugins in the loaded settings
58
-#   -# Merge plugins settings specification with the global lodel settings specs ( see @ref lodel.plugin )
60
+#   -# Merge plugins settings specification with the global lodel settings 
61
+#specs ( see @ref lodel.plugin )
59
 #   -# Fetch all settings from the merged settings specs
62
 #   -# Fetch all settings from the merged settings specs
60
 #
63
 #
61
 # @par Init sequence in practical
64
 # @par Init sequence in practical
65
 #   -# @ref Settings.__populate_from_specs() (step 5)
68
 #   -# @ref Settings.__populate_from_specs() (step 5)
66
 #   -# And finally @ref Settings.__confs_to_namedtuple()
69
 #   -# And finally @ref Settings.__confs_to_namedtuple()
67
 #
70
 #
68
-# @todo handles default sections for variable sections (sections ending with '.*')
71
+# @todo handles default sections for variable sections (sections ending with 
72
+# '.*')
69
 class Settings(object):
73
 class Settings(object):
70
     
74
     
71
-    ## @brief global conf specsification (default_value + validator)
75
+    ##@brief global conf specsification (default_value + validator)
72
     _conf_preload = {
76
     _conf_preload = {
73
             'lib_path': (   PYTHON_SYS_LIB_PATH+'/lodel2/',
77
             'lib_path': (   PYTHON_SYS_LIB_PATH+'/lodel2/',
74
                             SettingValidator('directory')),
78
                             SettingValidator('directory')),
77
     }
81
     }
78
     instance = None
82
     instance = None
79
     
83
     
80
-    ## @brief Should be called only by the boostrap classmethod
84
+    ##@brief Should be called only by the boostrap classmethod
81
     def __init__(self, conf_file = '/etc/lodel2/lodel2.conf', conf_dir = 'conf.d'):
85
     def __init__(self, conf_file = '/etc/lodel2/lodel2.conf', conf_dir = 'conf.d'):
82
         self.__confs = dict()
86
         self.__confs = dict()
83
         self.__conf_dir = conf_dir
87
         self.__conf_dir = conf_dir
86
         #   and self.__confs['lodel2']['lib_path'] set
90
         #   and self.__confs['lodel2']['lib_path'] set
87
         self.__bootstrap()
91
         self.__bootstrap()
88
     
92
     
89
-    ## @brief Stores as class attribute a Settings instance
93
+    ##@brief Stores as class attribute a Settings instance
90
     @classmethod
94
     @classmethod
91
     def bootstrap(cls, conf_file = None, conf_dir = None):
95
     def bootstrap(cls, conf_file = None, conf_dir = None):
92
         if cls.instance is None:
96
         if cls.instance is None:
96
                 cls.instance = cls(conf_file, conf_dir)
100
                 cls.instance = cls(conf_file, conf_dir)
97
         return cls.instance
101
         return cls.instance
98
 
102
 
99
-    ## @brief Configuration keys accessor
103
+    ##@brief Configuration keys accessor
100
     # @return All confs organised into named tuples
104
     # @return All confs organised into named tuples
101
     @property
105
     @property
102
     def confs(self):
106
     def confs(self):
103
         return copy.copy(self.__confs)
107
         return copy.copy(self.__confs)
104
 
108
 
105
-    ## @brief This method handlers Settings instance bootstraping
109
+    ##@brief This method handlers Settings instance bootstraping
106
     def __bootstrap(self):
110
     def __bootstrap(self):
107
         lodel2_specs = LODEL2_CONF_SPECS
111
         lodel2_specs = LODEL2_CONF_SPECS
108
         plugins_opt_specs = lodel2_specs['lodel2']['plugins']
112
         plugins_opt_specs = lodel2_specs['lodel2']['plugins']
126
         specs = self.__merge_specs(specs)
130
         specs = self.__merge_specs(specs)
127
         self.__populate_from_specs(specs, loader)
131
         self.__populate_from_specs(specs, loader)
128
     
132
     
129
-    ## @brief Produce a configuration specification dict by merging all specifications
133
+    ##@brief Produce a configuration specification dict by merging all specifications
130
     #
134
     #
131
     # Merges global lodel2 conf spec from @ref lodel.settings.validator.LODEL2_CONF_SPECS
135
     # Merges global lodel2 conf spec from @ref lodel.settings.validator.LODEL2_CONF_SPECS
132
     # and configuration specifications from loaded plugins
136
     # and configuration specifications from loaded plugins
144
                     res[section][kname] = copy.copy(spec[section][kname])
148
                     res[section][kname] = copy.copy(spec[section][kname])
145
         return res
149
         return res
146
     
150
     
147
-    ## @brief Populate the Settings instance with options values fecthed with the loader from merged specs
151
+    ##@brief Populate the Settings instance with options values fecthed with the loader from merged specs
148
     #
152
     #
149
     # Populate the __confs attribute
153
     # Populate the __confs attribute
150
     # @param specs dict : Settings specification dictionnary as returned by __merge_specs
154
     # @param specs dict : Settings specification dictionnary as returned by __merge_specs
170
         self.__confs_to_namedtuple()
174
         self.__confs_to_namedtuple()
171
         pass
175
         pass
172
     
176
     
173
-    ## @brief Transform the __confs attribute into imbricated namedtuple
177
+    ##@brief Transform the __confs attribute into imbricated namedtuple
174
     #
178
     #
175
     # For example an option named "foo" in a section named "hello.world" will
179
     # For example an option named "foo" in a section named "hello.world" will
176
     # be acessible with self.__confs.hello.world.foo
180
     # be acessible with self.__confs.hello.world.foo
225
                 path.append( (curname, cur) )
229
                 path.append( (curname, cur) )
226
                 nodename += '.'+curname.title()
230
                 nodename += '.'+curname.title()
227
     
231
     
228
-    ## @brief Forge a named tuple given a conftree node
232
+    ##@brief Forge a named tuple given a conftree node
229
     # @param conftree dict : A conftree node
233
     # @param conftree dict : A conftree node
230
     # @return a named tuple with fieldnames corresponding to conftree keys
234
     # @return a named tuple with fieldnames corresponding to conftree keys
231
     def __tree2namedtuple(self, conftree, name):
235
     def __tree2namedtuple(self, conftree, name):
232
         ResNamedTuple = namedtuple(name, conftree.keys())
236
         ResNamedTuple = namedtuple(name, conftree.keys())
233
         return ResNamedTuple(**conftree)
237
         return ResNamedTuple(**conftree)
234
 
238
 
235
-    ## @brief Load base global configurations keys
239
+    ##@brief Load base global configurations keys
236
     #
240
     #
237
     # Base configurations keys are :
241
     # Base configurations keys are :
238
     # - lodel2 lib path
242
     # - lodel2 lib path

+ 7
- 7
lodel/settings/settings_loader.py View File

7
 from lodel.settings.utils import *
7
 from lodel.settings.utils import *
8
 
8
 
9
    
9
    
10
-## @brief Merges and loads configuration files
10
+##@brief Merges and loads configuration files
11
 class SettingsLoader(object):
11
 class SettingsLoader(object):
12
-    ## @brief Constructor
12
+    ##@brief Constructor
13
     # @param conf_path str : conf.d path
13
     # @param conf_path str : conf.d path
14
     def __init__(self,conf_path):
14
     def __init__(self,conf_path):
15
         self.__conf_path=conf_path
15
         self.__conf_path=conf_path
16
         self.__conf_sv=set()
16
         self.__conf_sv=set()
17
         self.__conf=self.__merge()
17
         self.__conf=self.__merge()
18
     
18
     
19
-    ## @brief Lists and merges files in settings_loader.conf_path
19
+    ##@brief Lists and merges files in settings_loader.conf_path
20
     #
20
     #
21
     # 
21
     # 
22
     # @return dict()
22
     # @return dict()
49
         
49
         
50
         
50
         
51
     
51
     
52
-    ## @brief Returns option if exists default_value else and validates
52
+    ##@brief Returns option if exists default_value else and validates
53
     # @param section str : name of the section
53
     # @param section str : name of the section
54
     # @param keyname str
54
     # @param keyname str
55
     # @param validator callable : takes one argument value and raises validation fail
55
     # @param validator callable : takes one argument value and raises validation fail
70
              return default_value
70
              return default_value
71
                               
71
                               
72
     
72
     
73
-    ## @brief Returns the section to be configured
73
+    ##@brief Returns the section to be configured
74
     # @param section_prefix str
74
     # @param section_prefix str
75
     # @param default_section str
75
     # @param default_section str
76
     # @return the section as dict()
76
     # @return the section as dict()
82
             return conf[default_section]
82
             return conf[default_section]
83
         return [];
83
         return [];
84
     
84
     
85
-    ## @brief Returns the sections which have not been configured
85
+    ##@brief Returns the sections which have not been configured
86
     # @return list of missing options
86
     # @return list of missing options
87
     def getremains(self):
87
     def getremains(self):
88
         return list(self.__conf_sv)
88
         return list(self.__conf_sv)
89
-        
89
+        

+ 8
- 4
lodel/settings/utils.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 
2
 
3
-## @brief Error class for settings errors
3
+## @package lodel.settings.utils Lodel 2 settings utility
4
+#
5
+# For the moment defines exception classes
6
+
7
+##@brief Error class for settings errors
4
 class SettingsError(Exception):
8
 class SettingsError(Exception):
5
     
9
     
6
-    ## @brief Instanciate a new SettingsError
10
+    ##@brief Instanciate a new SettingsError
7
     # @param msg str : Error message
11
     # @param msg str : Error message
8
     # @param key_id str : The key concerned by the error
12
     # @param key_id str : The key concerned by the error
9
     def __init__(self, msg = "Unknown error", key_id = None, filename = None):
13
     def __init__(self, msg = "Unknown error", key_id = None, filename = None):
23
         res += ": %s" % (self.__msg)
27
         res += ": %s" % (self.__msg)
24
         return res
28
         return res
25
 
29
 
26
-## @brief Designed to handles mutliple SettingsError
30
+##@brief Designed to handles mutliple SettingsError
27
 class SettingsErrors(Exception):
31
 class SettingsErrors(Exception):
28
     
32
     
29
-    ## @brief Instanciate an SettingsErrors
33
+    ##@brief Instanciate an SettingsErrors
30
     # @param exceptions list : list of SettingsError instance
34
     # @param exceptions list : list of SettingsError instance
31
     def __init__(self, exceptions):
35
     def __init__(self, exceptions):
32
         for expt in exceptions: 
36
         for expt in exceptions: 

+ 11
- 11
lodel/settings/validator.py View File

13
 class SettingsValidationError(Exception):
13
 class SettingsValidationError(Exception):
14
     pass
14
     pass
15
 
15
 
16
-## @brief Handles settings validators
16
+##@brief Handles settings validators
17
 #
17
 #
18
 # Class instance are callable objects that takes a value argument (the value to validate). It raises
18
 # Class instance are callable objects that takes a value argument (the value to validate). It raises
19
 # a SettingsValidationError if validation fails, else it returns a properly
19
 # a SettingsValidationError if validation fails, else it returns a properly
23
     _validators = dict()
23
     _validators = dict()
24
     _description = dict()
24
     _description = dict()
25
     
25
     
26
-    ## @brief Instanciate a validator
26
+    ##@brief Instanciate a validator
27
     def __init__(self, name, none_is_valid = False):
27
     def __init__(self, name, none_is_valid = False):
28
         if name is not None and name not in self._validators:
28
         if name is not None and name not in self._validators:
29
             raise NameError("No validator named '%s'" % name)
29
             raise NameError("No validator named '%s'" % name)
30
         self.__name = name
30
         self.__name = name
31
 
31
 
32
-    ## @brief Call the validator
32
+    ##@brief Call the validator
33
     # @param value *
33
     # @param value *
34
     # @return properly casted value
34
     # @return properly casted value
35
     # @throw SettingsValidationError
35
     # @throw SettingsValidationError
41
         except Exception as e:
41
         except Exception as e:
42
             raise SettingsValidationError(e)
42
             raise SettingsValidationError(e)
43
     
43
     
44
-    ## @brief Register a new validator
44
+    ##@brief Register a new validator
45
     # @param name str : validator name
45
     # @param name str : validator name
46
     # @param callback callable : the function that will validate a value
46
     # @param callback callable : the function that will validate a value
47
     @classmethod
47
     @classmethod
54
         cls._validators[name] = callback
54
         cls._validators[name] = callback
55
         cls._description[name] = description
55
         cls._description[name] = description
56
     
56
     
57
-    ## @brief Get the validator list associated with description
57
+    ##@brief Get the validator list associated with description
58
     @classmethod
58
     @classmethod
59
     def validators_list(cls):
59
     def validators_list(cls):
60
         return copy.copy(cls._description)
60
         return copy.copy(cls._description)
61
 
61
 
62
-    ## @brief Create and register a list validator
62
+    ##@brief Create and register a list validator
63
     # @param elt_validator callable : The validator that will be used for validate each elt value
63
     # @param elt_validator callable : The validator that will be used for validate each elt value
64
     # @param validator_name str
64
     # @param validator_name str
65
     # @param description None | str
65
     # @param description None | str
80
                                 description)
80
                                 description)
81
         return cls(validator_name)
81
         return cls(validator_name)
82
                 
82
                 
83
-    ## @brief Create and register a regular expression validator
83
+    ##@brief Create and register a regular expression validator
84
     # @param pattern str : regex pattern
84
     # @param pattern str : regex pattern
85
     # @param validator_name str : The validator name
85
     # @param validator_name str : The validator name
86
     # @param description str : Validator description
86
     # @param description str : Validator description
109
             result += "\n"
109
             result += "\n"
110
         return result
110
         return result
111
 
111
 
112
-## @brief Integer value validator callback
112
+##@brief Integer value validator callback
113
 def int_val(value):
113
 def int_val(value):
114
     return int(value)
114
     return int(value)
115
 
115
 
116
-## @brief Output file validator callback
116
+##@brief Output file validator callback
117
 # @return A file object (if filename is '-' return sys.stderr)
117
 # @return A file object (if filename is '-' return sys.stderr)
118
 def file_err_output(value):
118
 def file_err_output(value):
119
     if not isinstance(value, str):
119
     if not isinstance(value, str):
122
         return sys.stderr
122
         return sys.stderr
123
     return value
123
     return value
124
 
124
 
125
-## @brief Boolean value validator callback
125
+##@brief Boolean value validator callback
126
 def boolean_val(value):
126
 def boolean_val(value):
127
     if not (value is True) and not (value is False):
127
     if not (value is True) and not (value is False):
128
         raise SettingsValidationError("A boolean was expected but got '%s' " % value)
128
         raise SettingsValidationError("A boolean was expected but got '%s' " % value)
194
 #   Lodel 2 configuration specification
194
 #   Lodel 2 configuration specification
195
 #
195
 #
196
 
196
 
197
-## @brief Global specifications for lodel2 settings
197
+##@brief Global specifications for lodel2 settings
198
 LODEL2_CONF_SPECS = {
198
 LODEL2_CONF_SPECS = {
199
     'lodel2': {
199
     'lodel2': {
200
         'debug': (  True,
200
         'debug': (  True,

+ 7
- 7
lodel/utils/mlstring.py View File

5
 import json
5
 import json
6
 
6
 
7
 
7
 
8
-## @brief Stores multilangage string
8
+##@brief Stores multilangage string
9
 class MlString(object):
9
 class MlString(object):
10
     
10
     
11
     __default_lang = 'eng'
11
     __default_lang = 'eng'
17
         'esp',
17
         'esp',
18
     ]
18
     ]
19
 
19
 
20
-    ## @brief Create a new MlString instance
20
+    ##@brief Create a new MlString instance
21
     # @param arg str | dict : Can be a json string, a string or a dict
21
     # @param arg str | dict : Can be a json string, a string or a dict
22
     def __init__(self, arg):
22
     def __init__(self, arg):
23
         self.values = dict()
23
         self.values = dict()
33
         else:
33
         else:
34
             raise ValueError('<class str>, <class dict> or <class MlString> expected, but %s found' % type(arg))
34
             raise ValueError('<class str>, <class dict> or <class MlString> expected, but %s found' % type(arg))
35
     
35
     
36
-    ## @brief Return a translation given a lang
36
+    ##@brief Return a translation given a lang
37
     # @param lang str | None : If None return default lang translation
37
     # @param lang str | None : If None return default lang translation
38
     def get(self, lang = None):
38
     def get(self, lang = None):
39
         lang = self.__default_lang if lang is None else lang
39
         lang = self.__default_lang if lang is None else lang
44
         else:
44
         else:
45
             return str(self)
45
             return str(self)
46
 
46
 
47
-    ## @brief Set a translation
47
+    ##@brief Set a translation
48
     # @param lang str : the lang
48
     # @param lang str : the lang
49
     # @param val str | None:  the translation if None delete the translation
49
     # @param val str | None:  the translation if None delete the translation
50
     def set(self, lang, val):
50
     def set(self, lang, val):
57
         else:
57
         else:
58
             self.values[lang] = val
58
             self.values[lang] = val
59
 
59
 
60
-    ## @brief Checks that given lang is valid
60
+    ##@brief Checks that given lang is valid
61
     # @param lang str : the lang
61
     # @param lang str : the lang
62
     @classmethod
62
     @classmethod
63
     def lang_is_valid(cls, lang):
63
     def lang_is_valid(cls, lang):
65
             raise ValueError('Invalid value for lang. Str expected but %s found' % type(lang))
65
             raise ValueError('Invalid value for lang. Str expected but %s found' % type(lang))
66
         return lang in cls.langs
66
         return lang in cls.langs
67
 
67
 
68
-    ## @brief Get or set the default lang
68
+    ##@brief Get or set the default lang
69
     @classmethod
69
     @classmethod
70
     def default_lang(cls, lang = None):
70
     def default_lang(cls, lang = None):
71
         if lang is None:
71
         if lang is None:
74
             raise ValueError('lang "%s" is not valid"' % lang)
74
             raise ValueError('lang "%s" is not valid"' % lang)
75
         cls.__default_lang = lang
75
         cls.__default_lang = lang
76
     
76
     
77
-    ## @brief Return a mlstring loaded from a json string
77
+    ##@brief Return a mlstring loaded from a json string
78
     # @param json_str str : Json string
78
     # @param json_str str : Json string
79
     @classmethod
79
     @classmethod
80
     def from_json(cls, json_str):
80
     def from_json(cls, json_str):

+ 1
- 1
plugins/dummy/main.py View File

2
 
2
 
3
 from lodel.plugin import LodelHook
3
 from lodel.plugin import LodelHook
4
 
4
 
5
-## @brief Hook's callback example
5
+##@brief Hook's callback example
6
 @LodelHook('leapi_get_pre')
6
 @LodelHook('leapi_get_pre')
7
 @LodelHook('leapi_get_post')
7
 @LodelHook('leapi_get_post')
8
 @LodelHook('leapi_update_pre')
8
 @LodelHook('leapi_update_pre')

Loading…
Cancel
Save