Преглед изворни кода

Doxygen documentation enhancement

Created groups (they can be found under the "Modules" menu -_- )
Created new pages : on LeAPI EditorialModel Plugins etc
Yann Weber пре 7 година
родитељ
комит
6e4fdde5f6

+ 50
- 1
lodel/editorial_model/__init__.py Прегледај датотеку

@@ -1 +1,50 @@
1
-__author__ = 'roland'
1
+##@defgroup lodel2_em Editorial Model
2
+#@brief Data organisation description
3
+
4
+##@package lodel.editorial_model
5
+#@brief Editorial model package
6
+#
7
+#The editorial model defines objects with fields. This objects will be later
8
+#manipulated via @ref lodel.leapi "LeAPI"
9
+
10
+##@page lodel2_em_page Editorial Model
11
+#@ingroup lodel2_em
12
+#
13
+#@section lodel2_em_what What is an editorial model ?
14
+#
15
+#The editorial model is a kind of entity-relationship model describing
16
+#editorial objects.
17
+#
18
+#@warning The lodel.editorial_model package does not contains code executed by
19
+#instances. The editorial model is used to generate python code named 
20
+#@ref lodel2_leapi "LeAPI" and the package contains Classes that made easy
21
+#the Em manipulation
22
+#
23
+# @subsection lodel2_em_class EmClass
24
+#
25
+#An editorial object is named @ref components.EmClass "EmClass" for "Editorial
26
+# Model Class". A class is characterized by a uniq name a 
27
+#@ref lodel2_datasources "Datasource", a group, an optionnal parent EmClass and
28
+#the @ref components.EmField "EmFields" it contains.
29
+#
30
+#@par Example
31
+#<code>An "Article" is an EmClass with "article" as name, the EmClass "Text" as
32
+#parent etc...</code>
33
+#
34
+# @subsection lodel2_em_field EmField
35
+#
36
+#@ref components.EmClass "EmClasses" contains 
37
+#@ref components.EmField "EmFields". An EmField as a name (uniq in the EmClass)
38
+# and is associated to a @ref lodel2_datahandlers "DataHandler" specification.
39
+#
40
+# @subsection lodel2_em_group EmGroup
41
+#
42
+#@ref components.EmClass "EmClasses" and @ref components.EmField "EmFields"
43
+#are in @ref components.EmGroup "EmGroups". EmGroups represent a consistent
44
+#EditorialModel part that can be activated or deactivated.
45
+#
46
+#@par Example
47
+#<pre>EmGroup "authors" contains the EmClass authors and all its EmField
48
+# + "written_by" EmField (a reference field on "Author" EmClass) in the EmClass
49
+#"Text"</pre>
50
+#

+ 8
- 0
lodel/editorial_model/components.py Прегледај датотеку

@@ -1,5 +1,9 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3
+##@package lodel.editorial_model.components
4
+#@brief Defines all @ref lodel2_em "EM" components
5
+#@ingroup lodel2_em
6
+
3 7
 import itertools
4 8
 import warnings
5 9
 import copy
@@ -14,6 +18,7 @@ from lodel.leapi.leobject import CLASS_ID_FIELDNAME
14 18
 ##@brief Abstract class to represent editorial model components
15 19
 # @see EmClass EmField
16 20
 # @todo forbid '.' in uid
21
+#@ingroup lodel2_em
17 22
 class EmComponent(object):
18 23
     
19 24
     ##@brief Instanciate an EmComponent
@@ -46,6 +51,7 @@ class EmComponent(object):
46 51
 
47 52
 
48 53
 ##@brief Handles editorial model objects classes
54
+#@ingroup lodel2_em
49 55
 class EmClass(EmComponent):
50 56
     
51 57
     ##@brief Instanciate a new EmClass
@@ -206,6 +212,7 @@ class EmClass(EmComponent):
206 212
 
207 213
 
208 214
 ##@brief Handles editorial model classes fields
215
+#@ingroup lodel2_em
209 216
 class EmField(EmComponent):
210 217
 
211 218
     ##@brief Instanciate a new EmField
@@ -259,6 +266,7 @@ class EmField(EmComponent):
259 266
         ).digest(), byteorder='big')
260 267
 
261 268
 ##@brief Handles functionnal group of EmComponents
269
+#@ingroup lodel2_em
262 270
 class EmGroup(object):
263 271
         
264 272
     ##@brief Create a new EmGroup

+ 1
- 0
lodel/editorial_model/model.py Прегледај датотеку

@@ -13,6 +13,7 @@ from lodel.editorial_model.exceptions import *
13 13
 from lodel.editorial_model.components import EmClass, EmField, EmGroup
14 14
 
15 15
 ##@brief Describe an editorial model
16
+#@ingroup lodel2_em
16 17
 class EditorialModel(object):
17 18
     
18 19
     ##@brief Create a new editorial model

+ 208
- 1
lodel/leapi/__init__.py Прегледај датотеку

@@ -1 +1,208 @@
1
-__author__ = 'roland'
1
+##@defgroup lodel2_leapi LeAPI
2
+#@brief Lodel2 Editorial API
3
+#
4
+#Provide access to datas via objects as defined in the Editorial Model
5
+
6
+##@package lodel.leapi
7
+#@brief Lodel2 Editorial API
8
+#
9
+# Defines an API to access to objects as described by 
10
+#@ref lodel.editorial_model "Editorial Model"
11
+
12
+##@page lodel2_leapi_page LeAPI
13
+#@ingroup lodel2_leapi
14
+#
15
+# @section lodel2_leapi_base LeAPI (Lodel Editorial API)
16
+#
17
+# LeAPI is an API that provide access to datas as defined in an 
18
+#@ref lodel2_em "Editorial Model".
19
+#
20
+#@subsection lodel2_leapi_gen LeAPI dynamic code & LeFactory
21
+#
22
+#LeAPI python code is programmaticaly generated by 
23
+#@ref lodel.leapi.lefactory "LeFactory". LeFactory generates 
24
+#@ref lodel.leapi.leobject.LeObject "LeObject" child classes.
25
+#
26
+#@par Example
27
+#<pre>
28
+#
29
+#    from lodel.leapi.leobject import LeObject
30
+#    from lodel.leapi.datahandlers.base_classes import DataField
31
+#    from lodel.plugin.hooks import LodelHook
32
+#
33
+#    class Abstract_Object(LeObject):
34
+#        _abstract = True
35
+#        _fields = None
36
+#        _uid = []
37
+#        _ro_datasource = None
38
+#        _rw_datasource = None
39
+#        _datasource_name = 'default'
40
+#        _child_classes = None
41
+#
42
+#
43
+#    class User(LeObject):
44
+#        _abstract = False
45
+#        _fields = None
46
+#        _uid = ['id']
47
+#        _ro_datasource = None
48
+#        _rw_datasource = None
49
+#        _datasource_name = 'default'
50
+#        _child_classes = None
51
+#
52
+#
53
+#    class Object(Abstract_Object):
54
+#        _abstract = True
55
+#        _fields = None
56
+#        _uid = ['lodel_id']
57
+#        _ro_datasource = None
58
+#        _rw_datasource = None
59
+#        _datasource_name = 'default'
60
+#        _child_classes = None
61
+#
62
+#
63
+#    class Entry(Object):
64
+#        _abstract = True
65
+#        _fields = None
66
+#        _uid = ['lodel_id']
67
+#        _ro_datasource = None
68
+#        _rw_datasource = None
69
+#        _datasource_name = 'default'
70
+#        _child_classes = None
71
+#
72
+#
73
+#    class Entitie(Object):
74
+#        _abstract = True
75
+#        _fields = None
76
+#        _uid = ['lodel_id']
77
+#        _ro_datasource = None
78
+#        _rw_datasource = None
79
+#        _datasource_name = 'default'
80
+#        _child_classes = None
81
+#
82
+#
83
+#    class Person(Object):
84
+#        _abstract = False
85
+#        _fields = None
86
+#        _uid = ['lodel_id']
87
+#        _ro_datasource = None
88
+#        _rw_datasource = None
89
+#        _datasource_name = 'default'
90
+#        _child_classes = None
91
+#
92
+#    class Text(Entitie):
93
+#        _abstract = True
94
+#        _fields = None
95
+#        _uid = ['lodel_id']
96
+#        _ro_datasource = None
97
+#        _rw_datasource = None
98
+#        _datasource_name = 'default'
99
+#        _child_classes = None
100
+#
101
+#
102
+#    class Publication(Entitie):
103
+#        _abstract = False
104
+#        _fields = None
105
+#        _uid = ['lodel_id']
106
+#        _ro_datasource = None
107
+#        _rw_datasource = None
108
+#        _datasource_name = 'default'
109
+#        _child_classes = None
110
+#
111
+#    Abstract_Object._set__fields({})
112
+#    Abstract_Object._child_classes = (Section, Text, Object, Entry, Collection, Text_Person, Entitie, Indextheme, Person, Indexabs, Publication, Subsection,)
113
+#    User._set__fields({
114
+#            'firstname': DataField.from_name('varchar')(**{ 'internal': False }), 
115
+#            'lastname': DataField.from_name('varchar')(**{ 'internal': False }), 
116
+#            'classname': DataField.from_name('LeobjectSubclassIdentifier')(**{ 'internal': True }), 
117
+#            'login': DataField.from_name('varchar')(**{ 'internal': True, 'uniq': True }), 
118
+#            'id': DataField.from_name('uniqid')(**{ 'internal': True }), 
119
+#            'password': DataField.from_name('password')(**{ 'internal': False })})
120
+#    User._child_classes = tuple()
121
+#    Object._set__fields({
122
+#            'date_update': DataField.from_name('datetime')(**{ 'now_on_update': True, 'internal': True }), 
123
+#            'lodel_id': DataField.from_name('uniqid')(**{ 'internal': True }), 
124
+#            'help_text': DataField.from_name('text')(**{ 'internal': True }), 
125
+#            'date_create': DataField.from_name('datetime')(**{ 'internal': True, 'now_on_create': True })})
126
+#    Object._child_classes = (Section, Text, Entry, Collection, Text_Person, Entitie, Indextheme, Person, Indexabs, Publication, Subsection,)
127
+#    Entry._set__fields({
128
+#            'date_update': DataField.from_name('datetime')(**{ 'now_on_update': True, 'internal': True }), 
129
+#            'lodel_id': DataField.from_name('uniqid')(**{ 'internal': True }), 
130
+#            'help_text': DataField.from_name('text')(**{ 'internal': True }), 
131
+#            'date_create': DataField.from_name('datetime')(**{ 'internal': True, 'now_on_create': True })})
132
+#    Entry._child_classes = tuple()
133
+#    Entitie._set__fields({
134
+#            'date_update': DataField.from_name('datetime')(**{ 'now_on_update': True, 'internal': True }), 
135
+#            'lodel_id': DataField.from_name('uniqid')(**{ 'internal': True }), 
136
+#            'help_text': DataField.from_name('text')(**{ 'internal': True }), 
137
+#            'date_create': DataField.from_name('datetime')(**{ 'internal': True, 'now_on_create': True })})
138
+#    Entitie._child_classes = (Section, Text, Text_Person, Collection, Publication, Subsection,)
139
+#    Person._set__fields({
140
+#            'date_update': DataField.from_name('datetime')(**{ 'now_on_update': True, 'internal': True }), 
141
+#            'firstname': DataField.from_name('varchar')(**{  }), 
142
+#            'lodel_id': DataField.from_name('uniqid')(**{ 'internal': True }), 
143
+#            'linked_texts': DataField.from_name('list')(**{ 'nullable': True, 'default': None, 'allowed_classes': [Text], 'back_reference': (Text, 'linked_persons') }), 
144
+#            'help_text': DataField.from_name('text')(**{ 'internal': True }), 
145
+#            'lastname': DataField.from_name('varchar')(**{  }), 
146
+#            'fullname': DataField.from_name('Concat')(**{ 'field_list': ['firstname', 'lastname'], 'immutable': True }), 
147
+#            'classname': DataField.from_name('LeobjectSubclassIdentifier')(**{ 'internal': True }), 
148
+#            'alias': DataField.from_name('set')(**{ 'nullable': True, 'default': None, 'allowed_classes': [Person] }), 
149
+#            'date_create': DataField.from_name('datetime')(**{ 'internal': True, 'now_on_create': True })})
150
+#    Person._child_classes = tuple()
151
+#    Text._set__fields({
152
+#            'date_update': DataField.from_name('datetime')(**{ 'now_on_update': True, 'internal': True }), 
153
+#            'subtitle': DataField.from_name('varchar')(**{ 'nullable': True, 'default': None }), 
154
+#            'lodel_id': DataField.from_name('uniqid')(**{ 'internal': True }), 
155
+#            'help_text': DataField.from_name('text')(**{ 'internal': True }), 
156
+#            'linked_persons': DataField.from_name('list')(**{ 'nullable': True, 'default': None, 'allowed_classes': [Person], 'back_reference': (Person, 'linked_texts') }), 
157
+#            'indexes': DataField.from_name('list')(**{ 'nullable': True, 'default': None, 'allowed_classes': [Indexabs], 'back_reference': (Indexabs, 'texts') }), 
158
+#            'title': DataField.from_name('varchar')(**{ 'nullable': True }), 
159
+#            'date_create': DataField.from_name('datetime')(**{ 'internal': True, 'now_on_create': True })})
160
+#    Text._child_classes = (Section, Subsection,)
161
+#    Publication._set__fields({
162
+#            'date_update': DataField.from_name('datetime')(**{ 'now_on_update': True, 'internal': True }), 
163
+#            'classname': DataField.from_name('LeobjectSubclassIdentifier')(**{ 'internal': True }), 
164
+#            'lodel_id': DataField.from_name('uniqid')(**{ 'internal': True }), 
165
+#            'collection': DataField.from_name('link')(**{ 'back_reference': (Collection, 'publications') }), 
166
+#            'help_text': DataField.from_name('text')(**{ 'internal': True }), 
167
+#            'date_create': DataField.from_name('datetime')(**{ 'internal': True, 'now_on_create': True })})
168
+#    Publication._child_classes = tuple()
169
+#
170
+#    #List of dynamically generated classes
171
+#    dynclasses = [Abstract_Object, User, Object, Entry, Entitie, Person, Indexabs, Text, Publication, Collection, Indextheme, Text_Person, Section, Subsection]
172
+#    #Dict of dynamically generated classes indexed by name
173
+#    dynclasses_dict = {'Abstract_Object': Abstract_Object, 'User': User, 'Object': Object, 'Entry': Entry, 'Entitie': Entitie, 'Person': Person, 'Indexabs': Indexabs, 'Text': Text, 'Publication': Publication, 'Collection': Collection, 'Indextheme': Indextheme, 'Text_Person': Text_Person, 'Section': Section, 'Subsection': Subsection}
174
+#
175
+#
176
+#    ##@brief Return a dynamically generated class given it's name
177
+#    #@param name str : The dynamic class name
178
+#    #@return False or a child class of LeObject
179
+#    def name2class(name):
180
+#        if name not in dynclasses_dict:
181
+#            return False
182
+#        return dynclasses_dict[name]
183
+#
184
+#
185
+#    ##@brief Return a dynamically generated class given it's name
186
+#    #@note Case insensitive version of name2class
187
+#    #@param name str
188
+#    #@retrun False or a child class of LeObject
189
+#    def lowername2class(name):
190
+#        name = name.lower()
191
+#        new_dict = {k.lower():v for k,v in dynclasses_dict.items()}
192
+#        if name not in new_dict:
193
+#            return False
194
+#        return new_dict[name]
195
+#
196
+#
197
+#    ##@brief Trigger dynclasses datasources initialisation
198
+#    @LodelHook("lodel2_plugins_loaded")
199
+#    def lodel2_dyncode_datasources_init(self, caller, payload):
200
+#        for cls in dynclasses:
201
+#            cls._init_datasources()
202
+#        from lodel.plugin.hooks import LodelHook
203
+#        LodelHook.call_hook("lodel2_dyncode_loaded", __name__, dynclasses)
204
+#
205
+#
206
+#
207
+#</pre>
208
+#

+ 91
- 38
lodel/plugin/__init__.py Прегледај датотеку

@@ -1,43 +1,96 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3
-## @page howto_writeplugin Write a plugin howto
4
-#
5
-# @section howto_writeplugin_basicstruct Plugin basic structure
6
-# A plugins is a python package that have to contains 3 files :
7
-#- <code>__init__.py</code>
8
-#- <code>main.py</code> ( defined in @ref lodel.plugin.plugins.MAIN_FILENAME )
9
-#- <code>confspec.py</code> ( defined in
10
-#@ref lodel.plugin.plugins.CONFSPEC_FILENAME )
11
-#
12
-# There is an example plugin in @ref plugins/dummy
13
-#
14
-# @subsection howto_writreplugin_confspec Plugin configuration specification
15
-# First of all a good practice is to preffix all plugin specific configuration
16
-# key with <code>lodel2.plugin.PLUGIN_NAME</code>.
17
-#
18
-# A configuration specification is a dict containing dict containing
19
-# tupe(DEFAULT_VALUE, VALIDATOR). The first level dict keys are sections, and
20
-# the dictionnary contained in it contains conf keys. More information on 
21
-# validators : @ref lodel.settings.validator
22
-# 
23
-# @subsubsection howto_writreplugin_confspec_example Example :
24
-#
25
-#A confspec that matches this peace of configuration file
26
-#<pre>
27
-#[lodel2.plugin.fooplugin]
28
-#hello = ...
29
-#foo = ...
30
-#bar = ...
31
-#</pre>
32
-#would be
33
-#<pre>
34
-#{
35
-#   'lodel2.plugin.fooplugin': {
36
-#                                   'foo': ...,
37
-#                                   'bar': ...,
38
-#                                   'hello': ..., } }
39
-#</pre>
40
-# 
3
+##@defgroup lodel2_plugins Plugins
4
+#
5
+#Groups all stuff that concerns plugins
6
+
7
+## @page plugin_doc Lodel2 plugin documentation
8
+#@ingroup lodel2_plugins
9
+# @section plugin_doc_type Plugin types
10
+#
11
+# Plugins are organized into types. A type specify a behavior. For the moment
12
+# Lodel2 has 4 plugin types :
13
+# - **datasource** : A datasource connector plugin expose CRUD operation on a
14
+#particular datasource
15
+# - **ui** : A user interface plugin provide an interface to lodel2. For the
16
+#moment two ui are implemented
17
+#  - interactive python : the default interface, provides access to LeApi 
18
+#through interactive python interpreter
19
+#  - webui : a plugin providing a web interface to lodel2
20
+# - **session_handler** : A session handler plugin expose functions that handles
21
+#user sessions.
22
+# - **extensions** : An extension plugin can define 2 kinds of objects :
23
+#  - hooks using @ref lodel.plugin.hooks.LodelHook decorator
24
+#  - custom LeApi obect methods using @ref lodel.plugin.plugins.CustomMethod 
25
+#decorator
26
+#
27
+# @subsection Lodel2 scripts
28
+#
29
+# In instances an utility is provided : @ref install.lodel_admin . This 
30
+# utility can be runned as a CLI script 
31
+#<code>usage: lodel_admin.py [-h] [-L] [ACTION] [OPTIONS [OPTIONS ...]]</code>
32
+#
33
+# Each actions is a "lodel2 script". Thoses scripts are parts of plugins.
34
+# @ref lodel2_script "More informations on lodel2 scripting utilities"
35
+#
36
+# @section plugin_doc_struct Common plugin structure
37
+#
38
+# All plugin types has to provide mandatories information in order to be 
39
+# loaded :
40
+#
41
+# - A plugin name
42
+# - A plugin version
43
+# - A confspec indicating where to find the wanted plugin list (for example 
44
+#datasources plugins list are indicated in lodel2.datasource_connectors 
45
+#configuration key see @ref datasource_plugin.DatasourcePlugin::_plist_confspecs ). In
46
+#fact settings MUST begin by loading wanted plugin list in order to build
47
+#a "full" confspec
48
+# - A confspec indicating the plugins allowed settings (will be merged with
49
+#lodel2 confspecs)
50
+# - A loader module filename. This module is imported once settings are
51
+#fully bootstraped and loader. It triggers the module "startup".
52
+#
53
+# In order to provide this informations the develloper can use the plugin's
54
+#package <code>__init__.py</code> file. Some informations are stored in 
55
+#variables in this file. Available variables are documented in 
56
+#@ref plugin_init_specs . Here a list of basics variables :
57
+# - the plugin's name @ref plugins.PLUGIN_NAME_VARNAME
58
+# - the plugin's version @ref plugins.PLUGIN_VERSION_VARNAME
59
+# - the plugin's loader filename @ref plugins.LOADER_FILENAME_VARNAME
60
+# - the plugin's confspec filename @ref plugins.CONFSPEC_FILENAME_VARNAME (
61
+#set this variable only if you want your confspecs to be in a separated file,
62
+#else you can put the confspecs directly in a CONFSPEC variable in the
63
+#<code>__init__.py</code> file see @ref plugins.CONFSPEC_VARNAME )
64
+# - the plugin's type @ref plugins.PLUGIN_TYPE_VARNAME (if not set use 
65
+# @ref plugins.DEFAULT_PLUGIN_TYPE )
66
+# - the plugin's dependencies list @ref plugins.PLUGIN_DEPS_VARNAME
67
+#
68
+# This was the variable specification of the <code>__init__.py</code> file.
69
+#plugins can provide (in the same file) an _activate function ( 
70
+#<code>def _activate(): returns bool</code>) that return True if the plugin
71
+#is activable else False
72
+#
73
+#An example dummy plugin exists in @ref plugins.dummy
74
+#
75
+#@section plugin_doc_childclasses Plugin types implementation
76
+#
77
+# Concretely a plugin type is a child class of @ref plugins.Plugin . Plugin 
78
+# type registration is done automatically using a metaclass for 
79
+# @ref plugins.Plugin : @ref plugins.MetaPlugType . Doing this way
80
+# plugin's type list is automatically generated.
81
+#@note Plugin type handling is not fully automatic because child classes files
82
+#are not automaticaaly imported. We have to add an import instruction into 
83
+#@ref plugin file in order to trigger the registration
84
+#
85
+#The Plugin child class must set the _plist_confspecs class attribute.
86
+#
87
+#More informations :
88
+# - @ref lodel.plugin.datasource_plugin.DatasourcePlugin "DatasourcePlugin"
89
+#  - @ref lodel2_datasources "datasources"
90
+# - @ref lodel.plugin.extensions.Extension "Extensions"
91
+# - @ref lodel.plugin.interface.InterfacePlugin "InterfacePlugin"
92
+# - @ref lodel.plugin.sessionhandler.SessionHandlerPlugin "SessionHandlerPlugin"
93
+#
41 94
 
42 95
 from .hooks import LodelHook
43 96
 from .plugins import Plugin, CustomMethod

+ 1
- 0
lodel/plugin/core_hooks.py Прегледај датотеку

@@ -6,6 +6,7 @@ from lodel import logger
6 6
 
7 7
 ##@package lodel.plugin.core_hooks
8 8
 #@brief Lodel2 internal hooks declaration
9
+#@ingroup lodel2_plugins
9 10
 
10 11
 ##@brief Bootstrap hook to check datasources configuration
11 12
 @LodelHook('lodel2_bootstraped')

+ 9
- 1
lodel/plugin/core_scripts.py Прегледај датотеку

@@ -1,8 +1,16 @@
1 1
 import lodel.plugin.scripts as lodel_script
2 2
 
3
+##@package lodel.plugin.core_scripts
4
+#@brief Lodel2 internal scripts declaration
5
+#@ingroup lodel2_plugins
6
+#@ingroup lodel2_script
7
+
8
+
3 9
 ##@brief Implements lodel_admin.py discover-plugin action
10
+#@ingroup lodel2_plugins
11
+#@ingroup lodel2_script
4 12
 #
5
-#In depth directory scan to find plugins.
13
+#In depth directory scan to find plugins in order to build a plugin list.
6 14
 class DiscoverPlugin(lodel_script.LodelScript):
7 15
     _action = 'discover-plugin'
8 16
     _description = 'Walk through given folders looking for plugins'

+ 96
- 5
lodel/plugin/datasource_plugin.py Прегледај датотеку

@@ -6,9 +6,14 @@ from lodel.settings.validator import SettingValidator
6 6
 #
7 7
 #A datasource provide data access to LeAPI typically a connector on a DB
8 8
 #or an API
9
+#
10
+#Provide methods to initialize datasource attribute in LeAPI LeObject child
11
+#classes (see @ref leapi.leobject.LeObject._init_datasources() )
12
+#
9 13
 #@note For the moment implementation is done with a retro-compatibilities
10 14
 #priority and not with a convenience priority.
11 15
 #@todo Refactor and rewrite lodel2 datasource handling
16
+#@todo Write abstract classes for Datasource and MigrationHandler !!!
12 17
 class DatasourcePlugin(Plugin):
13 18
     
14 19
     ##@brief Stores confspecs indicating where DatasourcePlugin list is stored
@@ -18,16 +23,23 @@ class DatasourcePlugin(Plugin):
18 23
         'default': None,
19 24
         'validator': SettingValidator('strip', none_is_valid = False) }
20 25
     _type_conf_name = 'datasource'
21
-    
26
+ 
27
+    ##@brief Construct a DatasourcePlugin 
28
+    #@param name str : plugin name
29
+    #@see plugins.Plugin
22 30
     def __init__(self, name):
23 31
         super().__init__(name)
24 32
         self.__datasource_cls = None
25
-
33
+    
34
+    ##@brief Accessor to the datasource class
35
+    #@return A python datasource class
26 36
     def datasource_cls(self):
27 37
         if self.__datasource_cls is None:
28 38
             self.__datasource_cls = self.loader_module().Datasource
29 39
         return self.__datasource_cls
30
-
40
+    
41
+    ##@brief Accessor to migration handler class
42
+    #@return A python migration handler class
31 43
     def migration_handler_cls(self):
32 44
         return self.loader_module().migration_handler_class()
33 45
 
@@ -139,8 +151,87 @@ but %s is a %s" % (ds_name, pinstance.__class__.__name__))
139 151
     @classmethod
140 152
     def get_datasource(cls, ds_plugin_name):
141 153
         return cls.get(ds_plugin_name).datasource_cls()
142
-
154
+    
155
+    ##@brief Given a plugin name returns a migration handler class
156
+    #@param ds_plugin_name str : a datasource plugin name
143 157
     @classmethod
144 158
     def get_migration_handler(cls, ds_plugin_name):
145 159
         return cls.get(ds_plugin_name).migration_handler_cls()
146
- 
160
+
161
+##@page lodel2_datasources Lodel2 datasources
162
+#
163
+#@par lodel2_datasources_intro Intro
164
+# A single lodel2 website can interact with multiple datasources. This page
165
+# aims to describe configuration & organisation of datasources in lodel2.
166
+# Each object is attached to a datasource. This association is done in the
167
+# editorial model, the datasource is identified by a name.
168
+#
169
+#@par Datasources declaration
170
+# To define a datasource you have to write something like this in confs file :
171
+#<pre>
172
+#[lodel2.datasources.DATASOURCE_NAME]
173
+#identifier = DATASOURCE_FAMILY.SOURCE_NAME
174
+#</pre>
175
+# See below for DATASOURCE_FAMILY & SOURCE_NAME
176
+#
177
+#@par Datasources plugins
178
+# Each datasource family is a plugin ( 
179
+#@ref plugin_doc "More informations on plugins" ). For example mysql or a 
180
+#mongodb plugins. Here is the CONFSPEC variable templates for datasources 
181
+#plugin
182
+#<pre>
183
+#CONFSPEC = {
184
+#                'lodel2.datasource.example.*' : {
185
+#                    'conf1' : VALIDATOR_OPTS,
186
+#                    'conf2' : VALIDATOR_OPTS,
187
+#                    ...
188
+#                }
189
+#}
190
+#</pre>
191
+#MySQL example
192
+#<pre>
193
+#CONFSPEC = {
194
+#                'lodel2.datasource.mysql.*' : {
195
+#                    'host': (   'localhost',
196
+#                                SettingValidator('host')),
197
+#                    'db_name': (    'lodel',
198
+#                                    SettingValidator('string')),
199
+#                    'username': (   None,
200
+#                                    SettingValidator('string')),
201
+#                    'password': (   None,
202
+#                                    SettingValidator('string')),
203
+#                }
204
+#}
205
+#</pre>
206
+#
207
+#@par Configuration example
208
+#<pre>
209
+# [lodel2.datasources.main]
210
+# identifier = mysql.Core
211
+# [lodel2.datasources.revues_write]
212
+# identifier = mysql.Revues
213
+# [lodel2.datasources.revues_read]
214
+# identifier = mysql.Revues
215
+# [lodel2.datasources.annuaire_persons]
216
+# identifier = persons_web_api.example
217
+# ;
218
+# ; Then, in the editorial model you are able to use "main", "revues_write", 
219
+# ; etc as datasource
220
+# ;
221
+# ; Here comes the datasources declarations
222
+# [lodel2.datasource.mysql.Core]
223
+# host = db.core.labocleo.org
224
+# db_name = core
225
+# username = foo
226
+# password = bar
227
+# ;
228
+# [lodel2.datasource.mysql.Revues]
229
+# host = revues.org
230
+# db_name = RO
231
+# username = foo
232
+# password = bar
233
+# ;
234
+# [lodel2.datasource.persons_web_api.example]
235
+# host = foo.bar
236
+# username = cleo
237
+#</pre>

+ 1
- 0
lodel/plugin/hooks.py Прегледај датотеку

@@ -27,6 +27,7 @@ class DecoratedWrapper(object):
27 27
             self._hook.__name__, self._priority)
28 28
 
29 29
 ##@brief Decorator designed to register hook's callbacks
30
+#@ingroup lodel2_plugins
30 31
 #
31 32
 # @note Decorated functions are expected to take 3 arguments :
32 33
 #  - hook_name : the called hook name

+ 7
- 1
lodel/plugin/plugins.py Прегледај датотеку

@@ -14,6 +14,7 @@ from .exceptions import *
14 14
 from lodel.exceptions import *
15 15
 
16 16
 ## @package lodel.plugins Lodel2 plugins management
17
+#@ingroup lodel2_plugins
17 18
 #
18 19
 # Lodel2 plugins are stored in directories
19 20
 # A typicall lodel2 plugin directory structure looks like :
@@ -21,7 +22,8 @@ from lodel.exceptions import *
21 22
 # - main.py containing hooks registration etc
22 23
 # - confspec.py containing a configuration specification dictionary named CONFSPEC
23 24
 
24
-## @defgroup plugin_init_specs Plugins <code>__init__.py</code> specifications
25
+##@defgroup plugin_init_specs Plugins __init__.py specifications
26
+#@ingroup lodel2_plugins
25 27
 #@{
26 28
 
27 29
 ##@brief The package in which we will load plugins modules
@@ -62,6 +64,7 @@ DEFAULT_PLUGIN_TYPE = 'extension' #Value found in lodel/plugin/extensions.py::Ex
62 64
 ## @}
63 65
 
64 66
 ##@brief Describe and handle version numbers
67
+#@ingroup lodel2_plugins
65 68
 #
66 69
 #A version number can be represented by a string like MAJOR.MINOR.PATCH
67 70
 #or by a list [MAJOR, MINOR,PATCH ].
@@ -172,6 +175,7 @@ to generic PluginVersion comparison function : '%s'" % cmp_fun_name)
172 175
             'revision': self.revision}
173 176
 
174 177
 ##@brief Plugin metaclass that allows to "catch" child class declaration
178
+#@ingroup lodel2_plugins
175 179
 #
176 180
 #Automatic script registration on child class declaration
177 181
 class MetaPlugType(type):
@@ -214,6 +218,7 @@ class MetaPlugType(type):
214 218
         return cls._all_ptypes[ptype_name]
215 219
 
216 220
 ##@brief Handle plugins
221
+#@ingroup lodel2_plugins
217 222
 #
218 223
 # An instance represent a loaded plugin. Class methods allow to load/preload
219 224
 # plugins.
@@ -824,6 +829,7 @@ file : '%s'. Running discover again..." % DISCOVER_CACHE_FILENAME)
824 829
 
825 830
 ##@brief Decorator class designed to allow plugins to add custom methods
826 831
 #to LeObject childs (dyncode objects)
832
+#@ingroup lodel2_plugins
827 833
 #
828 834
 class CustomMethod(object):
829 835
     ##@brief Stores registered custom methods

+ 15
- 0
lodel/plugin/scripts.py Прегледај датотеку

@@ -4,11 +4,22 @@ import sys
4 4
 from lodel import logger
5 5
 from lodel.exceptions import *
6 6
 
7
+##@defgroup lodel2_script Administration scripts
8
+#@ingroup lodel2_plugins
9
+
10
+##@package lodel.plugin.script
11
+#@brief Lodel2 utility for writting administration scripts
12
+#@ingroup lodel2_plugins
13
+#@ingroup lodel2_script
14
+
7 15
 ##@brief Stores registered scripts
16
+#@todo store it in MetaLodelScript
8 17
 __registered_scripts = dict()
9 18
 
10 19
 ##@brief LodelScript metaclass that allows to "catch" child class
11 20
 #declaration
21
+#@ingroup lodel2_script
22
+#@ingroup lodel2_plugins
12 23
 #
13 24
 #Automatic script registration on child class declaration
14 25
 class MetaLodelScript(type):
@@ -48,6 +59,10 @@ action identifier" % name)
48 59
     def __str__(self):
49 60
         return '%s : %s' % (self._action, self._description)
50 61
 
62
+
63
+##@brief Class designed to facilitate custom script writting
64
+#@ingroup lodel2_plugins
65
+#@ingroup lodel2_script
51 66
 class LodelScript(object, metaclass=MetaLodelScript):
52 67
     
53 68
     ##@brief A string to identify the action

+ 4
- 8
lodel/plugin/sessionhandler.py Прегледај датотеку

@@ -5,6 +5,7 @@ from lodel.settings.validator import SettingValidator
5 5
 ##@brief SessionHandlerPlugin metaclass designed to implements a wrapper
6 6
 #between SessionHandlerPlugin classmethod and plugin loader functions
7 7
 class SessionPluginWrapper(MetaPlugType):
8
+
8 9
     ##@brief Constant that stores all possible session actions
9 10
     #
10 11
     #Key is the SessionHandlerPlugin method name and value is SessionHandler
@@ -32,15 +33,10 @@ functions, but no session handler initialized")
32 33
         return super().__getattribute__(name)
33 34
 
34 35
 
35
-##@page lodel2_plugins Lodel2 plugins system
36
-#
37
-# @par Plugin structure
38
-#A plugin is  a package (a folder containing, at least, an __init__.py file.
39
-#This file should expose multiple things :
40
-# - a CONFSPEC variable containing configuration specifications
41
-# - an _activate() method that returns True if the plugin can be activated (
42
-# optionnal)
36
+##@brief Singleton class designed to handle session handler plugin
43 37
 #
38
+#@note This class is a singleton because only one session handler can be
39
+#loaded by instance
44 40
 class SessionHandlerPlugin(Plugin, metaclass=SessionPluginWrapper): 
45 41
     ##@brief Stores the singleton instance
46 42
     _instance = None

+ 1
- 75
plugins/dummy_datasource/__init__.py Прегледај датотеку

@@ -13,78 +13,4 @@ CONFSPEC = {
13 13
                     SettingValidator('dummy'))}
14 14
 }
15 15
 
16
-##@page lodel2_datasources Lodel2 datasources
17
-#
18
-#@par lodel2_datasources_intro Intro
19
-# A single lodel2 website can interact with multiple datasources. This page
20
-# aims to describe configuration & organisation of datasources in lodel2.
21
-# Each object is attached to a datasource. This association is done in the
22
-# editorial model, the datasource is identified by a name.
23
-#
24
-#@par Datasources declaration
25
-# To define a datasource you have to write something like this in confs file :
26
-#<pre>
27
-#[lodel2.datasources.DATASOURCE_NAME]
28
-#identifier = DATASOURCE_FAMILY.SOURCE_NAME
29
-#</pre>
30
-# See below for DATASOURCE_FAMILY & SOURCE_NAME
31
-#
32
-#@par Datasources plugins
33
-# Each datasource family is a plugin. For example mysql or a mongodb plugins.
34
-# Here is the CONFSPEC variable templates for datasources plugins
35
-#<pre>
36
-#CONFSPEC = {
37
-#                'lodel2.datasource.example.*' : {
38
-#                    'conf1' : VALIDATOR_OPTS,
39
-#                    'conf2' : VALIDATOR_OPTS,
40
-#                    ...
41
-#                }
42
-#}
43
-#</pre>
44
-#MySQL example
45
-#<pre>
46
-#CONFSPEC = {
47
-#                'lodel2.datasource.mysql.*' : {
48
-#                    'host': (   'localhost',
49
-#                                SettingValidator('host')),
50
-#                    'db_name': (    'lodel',
51
-#                                    SettingValidator('string')),
52
-#                    'username': (   None,
53
-#                                    SettingValidator('string')),
54
-#                    'password': (   None,
55
-#                                    SettingValidator('string')),
56
-#                }
57
-#}
58
-#</pre>
59
-#
60
-#@par Configuration example
61
-#<pre>
62
-# [lodel2.datasources.main]
63
-# identifier = mysql.Core
64
-# [lodel2.datasources.revues_write]
65
-# identifier = mysql.Revues
66
-# [lodel2.datasources.revues_read]
67
-# identifier = mysql.Revues
68
-# [lodel2.datasources.annuaire_persons]
69
-# identifier = persons_web_api.example
70
-# ;
71
-# ; Then, in the editorial model you are able to use "main", "revues_write", 
72
-# ; etc as datasource
73
-# ;
74
-# ; Here comes the datasources declarations
75
-# [lodel2.datasource.mysql.Core]
76
-# host = db.core.labocleo.org
77
-# db_name = core
78
-# username = foo
79
-# password = bar
80
-# ;
81
-# [lodel2.datasource.mysql.Revues]
82
-# host = revues.org
83
-# db_name = RO
84
-# username = foo
85
-# password = bar
86
-# ;
87
-# [lodel2.datasource.persons_web_api.example]
88
-# host = foo.bar
89
-# username = cleo
90
-#</pre>
16
+

Loading…
Откажи
Сачувај