diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index c0e5f9bd..dc1f6b94 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -32,7 +32,7 @@ from sleekxmpp.xmlstream.matcher import MatchXPath from sleekxmpp.xmlstream.handler import Callback from sleekxmpp.features import * -from sleekxmpp.plugins import PluginManager, register_plugin +from sleekxmpp.plugins import PluginManager, register_plugin, load_plugin log = logging.getLogger(__name__) @@ -218,34 +218,7 @@ class BaseXMPP(XMLStream): pconfig = self.plugin_config.get(plugin, {}) if not self.plugin.registered(plugin): - # Use old-style plugin - try: - #Import the given module that contains the plugin. - if not module: - try: - module = sleekxmpp.plugins - module = __import__( - str("%s.%s" % (module.__name__, plugin)), - globals(), locals(), [str(plugin)]) - except ImportError: - module = sleekxmpp.features - module = __import__( - str("%s.%s" % (module.__name__, plugin)), - globals(), locals(), [str(plugin)]) - if isinstance(module, str): - # We probably want to load a module from outside - # the sleekxmpp package, so leave out the globals(). - module = __import__(module, fromlist=[plugin]) - - plugin_class = getattr(module, plugin) - - if not hasattr(plugin_class, 'name'): - plugin_class.name = plugin - register_plugin(plugin_class, name=plugin) - except: - log.exception("Unable to load plugin: %s", plugin) - return - + load_plugin(plugin, module) self.plugin.enable(plugin, pconfig) def register_plugins(self): diff --git a/sleekxmpp/plugins/__init__.py b/sleekxmpp/plugins/__init__.py index 4fb41919..8f8f851a 100644 --- a/sleekxmpp/plugins/__init__.py +++ b/sleekxmpp/plugins/__init__.py @@ -6,8 +6,9 @@ See the file LICENSE for copying permission. """ -from sleekxmpp.plugins.base import PluginManager, PluginNotFound, \ - BasePlugin, register_plugin +from sleekxmpp.plugins.base import PluginManager, PluginNotFound, BasePlugin +from sleekxmpp.plugins.base import register_plugin, load_plugin + __all__ = [ # Non-standard diff --git a/sleekxmpp/plugins/base.py b/sleekxmpp/plugins/base.py index 447ffba7..bc0504ea 100644 --- a/sleekxmpp/plugins/base.py +++ b/sleekxmpp/plugins/base.py @@ -33,6 +33,10 @@ PLUGIN_DEPENDENTS = {} REGISTRY_LOCK = threading.RLock() +class PluginNotFound(Exception): + """Raised if an unknown plugin is accessed.""" + + def register_plugin(impl, name=None): """Add a new plugin implementation to the registry. @@ -56,8 +60,40 @@ def register_plugin(impl, name=None): PLUGIN_DEPENDENTS[dep].add(name) -class PluginNotFound(Exception): - """Raised if an unknown plugin is accessed.""" +def load_plugin(name, module=None): + """Find and import a plugin module so that it can be registered. + + This function is called to import plugins that have selected for + enabling, but no matching registered plugin has been found. + + :param str name: The name of the plugin. It is expected that + plugins are in packages matching their name, + even though the plugin class name does not + have to match. + :param str module: The name of the base module to search + for the plugin. + """ + try: + if not module: + try: + module = 'sleekxmpp.plugins.%s' % name + mod = __import__(module, fromlist=[str(name)]) + except: + module = 'sleekxmpp.features.%s' % name + mod = __import__(module, fromlist=[str(name)]) + else: + mod = __import__(module, fromlist=[str(name)]) + + # Add older style plugins to the registry. + if hasattr(mod, name): + plugin = getattr(mod, name) + if not hasattr(plugin, 'name'): + plugin.name = name + register_plugin(plugin, name) + else: + log.debug("%s does not have %s", mod, name) + except: + log.exception("Unable to load plugin: %s", name) class PluginManager(object): @@ -105,6 +141,9 @@ class PluginManager(object): if name not in self._enabled: enabled.add(name) self._enabled.add(name) + if not self.registered(name): + load_plugin(name) + plugin_class = PLUGIN_REGISTRY.get(name, None) if not plugin_class: raise PluginNotFound(name)