summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLance Stout <lancestout@gmail.com>2012-03-12 09:43:24 -0700
committerLance Stout <lancestout@gmail.com>2012-03-12 19:32:20 -0700
commitf8f2b541db2c7d53e96ff972fc3349fa4c1ea05d (patch)
treef39f1ca22371088f72d96503d2fac30fe43cf47a
parent9d645ad5cd06cabc20cd1b0067a2b16a0c1e7814 (diff)
downloadslixmpp-f8f2b541db2c7d53e96ff972fc3349fa4c1ea05d.tar.gz
slixmpp-f8f2b541db2c7d53e96ff972fc3349fa4c1ea05d.tar.bz2
slixmpp-f8f2b541db2c7d53e96ff972fc3349fa4c1ea05d.tar.xz
slixmpp-f8f2b541db2c7d53e96ff972fc3349fa4c1ea05d.zip
Handle loading plugins on demand.
Plugins that are referenced as dependencies, but have not been registered now will be imported. Newer plugins should register themselves automatically, but older style plugins will be explicitly registered after import.
-rw-r--r--sleekxmpp/basexmpp.py31
-rw-r--r--sleekxmpp/plugins/__init__.py5
-rw-r--r--sleekxmpp/plugins/base.py43
3 files changed, 46 insertions, 33 deletions
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)