Browse Source

Enable factory in Plugin

- now plugin is able to instanciate using the good child class
- the discover cache now contains plugin's type
Yann Weber 8 years ago
parent
commit
34c1784907

+ 6
- 4
lodel/plugin/datasource_plugin.py View File

12
     
12
     
13
     def __init__(self, name):
13
     def __init__(self, name):
14
         super().__init__(name)
14
         super().__init__(name)
15
-        self.__datasource_cls = self.loader_module().Datasource
15
+        self.__datasource_cls = None
16
 
16
 
17
-    def datasource(self):
18
-        return self.__datasource
17
+    def datasource_cls(self):
18
+        if self.__datasource_cls is None:
19
+            self.__datasource_cls = self.loader_module().Datasource
20
+        return self.__datasource_cls
19
 
21
 
20
     def migration_handler(self):
22
     def migration_handler(self):
21
         return self.loader_module().migration_handler_class()
23
         return self.loader_module().migration_handler_class()
111
     #@throw PluginTypeError if ds_name is not the name of a DatasourcePlugin
113
     #@throw PluginTypeError if ds_name is not the name of a DatasourcePlugin
112
     @classmethod
114
     @classmethod
113
     def get_datasource(cls, ds_plugin_name):
115
     def get_datasource(cls, ds_plugin_name):
114
-        return cls.get(ds_plugin_name).datasource()
116
+        return cls.get(ds_plugin_name).datasource_cls()
115
 
117
 
116
     @classmethod
118
     @classmethod
117
     def get_migration_handler(cls, ds_plugin_name):
119
     def get_migration_handler(cls, ds_plugin_name):

+ 38
- 9
lodel/plugin/plugins.py View File

27
 ##@brief Plugin init filename
27
 ##@brief Plugin init filename
28
 INIT_FILENAME = '__init__.py' # Loaded with settings
28
 INIT_FILENAME = '__init__.py' # Loaded with settings
29
 PLUGIN_NAME_VARNAME = '__plugin_name__'
29
 PLUGIN_NAME_VARNAME = '__plugin_name__'
30
-PLUGIN_TYPE_VARNAME = '__type__'
30
+PLUGIN_TYPE_VARNAME = '__plugin_type__'
31
 PLUGIN_VERSION_VARNAME = '__version__'
31
 PLUGIN_VERSION_VARNAME = '__version__'
32
 CONFSPEC_FILENAME_VARNAME = '__confspec__'
32
 CONFSPEC_FILENAME_VARNAME = '__confspec__'
33
 CONFSPEC_VARNAME = 'CONFSPEC'
33
 CONFSPEC_VARNAME = 'CONFSPEC'
42
 MANDATORY_VARNAMES = [PLUGIN_NAME_VARNAME, LOADER_FILENAME_VARNAME, 
42
 MANDATORY_VARNAMES = [PLUGIN_NAME_VARNAME, LOADER_FILENAME_VARNAME, 
43
     PLUGIN_VERSION_VARNAME]
43
     PLUGIN_VERSION_VARNAME]
44
 
44
 
45
-EXTENSIONS = 'default'
46
-PLUGINS_TYPES = [EXTENSIONS, 'datasource', 'session_handler', 'ui']
45
+DEFAULT_PLUGIN_TYPE = 'extension'
46
+PLUGINS_TYPES = [DEFAULT_PLUGIN_TYPE, 'datasource', 'session_handler', 'ui']
47
 
47
 
48
 
48
 
49
 ##@brief Describe and handle version numbers
49
 ##@brief Describe and handle version numbers
249
         try:
249
         try:
250
             self.__type = getattr(self.module, PLUGIN_TYPE_VARNAME)
250
             self.__type = getattr(self.module, PLUGIN_TYPE_VARNAME)
251
         except AttributeError:
251
         except AttributeError:
252
-            self.__type = EXTENSIONS
252
+            self.__type = DEFAULT_PLUGIN_TYPE
253
         self.__type = str(self.__type).lower()
253
         self.__type = str(self.__type).lower()
254
         if self.__type not in PLUGINS_TYPES:
254
         if self.__type not in PLUGINS_TYPES:
255
             raise PluginError("Unknown plugin type '%s'" % self.__type)
255
             raise PluginError("Unknown plugin type '%s'" % self.__type)
427
     def confspecs(self):
427
     def confspecs(self):
428
         return copy.copy(self.__confspecs)
428
         return copy.copy(self.__confspecs)
429
 
429
 
430
+    ##@brief Attempt to read plugin discover cache
431
+    #@note If no cache yet make a discover with default plugin directory
432
+    #@return a dict (see @ref _discover() )
433
+    @classmethod
434
+    def plugin_cache(cls):
435
+        if not os.path.isfile(DISCOVER_CACHE_FILENAME):
436
+            cls.discover()
437
+        with open(DISCOVER_CACHE_FILENAME) as pdcache_fd:
438
+            res = json.load(pdcache_fd)
439
+        return res
440
+
430
     ##@brief Register a new plugin
441
     ##@brief Register a new plugin
431
     # 
442
     # 
432
     #@param plugin_name str : The plugin name
443
     #@param plugin_name str : The plugin name
434
     #@throw PluginError
445
     #@throw PluginError
435
     @classmethod
446
     @classmethod
436
     def register(cls, plugin_name):
447
     def register(cls, plugin_name):
448
+        from .datasource_plugin import DatasourcePlugin
437
         if plugin_name in cls._plugin_instances:
449
         if plugin_name in cls._plugin_instances:
438
             msg = "Plugin allready registered with same name %s"
450
             msg = "Plugin allready registered with same name %s"
439
             msg %= plugin_name
451
             msg %= plugin_name
440
             raise PluginError(msg)
452
             raise PluginError(msg)
441
-        plugin = cls(plugin_name)
453
+        #Here we check that previous discover found a plugin with that name
454
+        pdcache = cls.plugin_cache()
455
+        if plugin_name not in pdcache['plugins']:
456
+            raise PluginError("No plugin named %s found" % plugin_name)
457
+        pinfos = pdcache['plugins'][plugin_name]
458
+        ptype = pinfos['type']
459
+        if ptype == 'datasource':
460
+            pcls = DatasourcePlugin
461
+        else:
462
+            pcls = cls
463
+        print(plugin_name, ptype, pcls)
464
+        plugin = pcls(plugin_name)
442
         cls._plugin_instances[plugin_name] = plugin
465
         cls._plugin_instances[plugin_name] = plugin
443
         logger.debug("Plugin %s available." % plugin)
466
         logger.debug("Plugin %s available." % plugin)
444
         return plugin
467
         return plugin
531
         result = dict()
554
         result = dict()
532
         for pinfos in tmp_res:
555
         for pinfos in tmp_res:
533
             pname = pinfos['name']
556
             pname = pinfos['name']
534
-            if (
535
-                    pname in result 
557
+            if (    pname in result 
536
                     and pinfos['version'] > result[pname]['version'])\
558
                     and pinfos['version'] > result[pname]['version'])\
537
                 or pname not in result:
559
                 or pname not in result:
538
                 result[pname] = pinfos
560
                 result[pname] = pinfos
618
                 log_msg %= (attr_name, INIT_FILENAME)
640
                 log_msg %= (attr_name, INIT_FILENAME)
619
                 logger.debug(log_msg)
641
                 logger.debug(log_msg)
620
                 return False
642
                 return False
643
+        #Fetching plugin's version
621
         try:
644
         try:
622
             pversion = getattr(initmod, PLUGIN_VERSION_VARNAME)
645
             pversion = getattr(initmod, PLUGIN_VERSION_VARNAME)
623
-        except PluginError as e:
646
+        except (NameError, AttributeError) as e:
624
             msg = "Invalid plugin version found in %s : %s"
647
             msg = "Invalid plugin version found in %s : %s"
625
             msg %= (path, e)
648
             msg %= (path, e)
626
             raise PluginError(msg)
649
             raise PluginError(msg)
650
+        #Fetching plugin's type
651
+        try:
652
+            ptype = getattr(initmod, PLUGIN_TYPE_VARNAME)
653
+        except (NameError, AttributeError) as e:
654
+            ptype = DEFAULT_PLUGIN_TYPE
627
         pname = getattr(initmod, PLUGIN_NAME_VARNAME)
655
         pname = getattr(initmod, PLUGIN_NAME_VARNAME)
628
         return {'name': pname,
656
         return {'name': pname,
629
             'version': pversion,
657
             'version': pversion,
630
-            'path': path}
658
+            'path': path,
659
+            'type': ptype}
631
     
660
     
632
     ##@brief Import init file from a plugin path
661
     ##@brief Import init file from a plugin path
633
     #@param path str : Directory path
662
     #@param path str : Directory path

+ 1
- 0
plugins/dummy_datasource/__init__.py View File

1
 from lodel.settings.validator import SettingValidator
1
 from lodel.settings.validator import SettingValidator
2
 from .datasource import DummyDatasource as Datasource
2
 from .datasource import DummyDatasource as Datasource
3
 
3
 
4
+__plugin_type__ = 'datasource'
4
 __plugin_name__ = "dummy_datasource"
5
 __plugin_name__ = "dummy_datasource"
5
 __version__ = '0.0.1'
6
 __version__ = '0.0.1'
6
 __loader__ = 'main.py'
7
 __loader__ = 'main.py'

+ 1
- 0
plugins/mongodb_datasource/__init__.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
+__plugin_type__ = 'datasource'
2
 __plugin_name__ = 'mongodb_datasource'
3
 __plugin_name__ = 'mongodb_datasource'
3
 __version__ = '0.0.1'
4
 __version__ = '0.0.1'
4
 __plugin_type__ = 'datasource'
5
 __plugin_type__ = 'datasource'

Loading…
Cancel
Save