Add PluginManagerBase class.

Only load plugins that are in the 'enabled_plugins' key in the config 
files.
This commit is contained in:
Andrew Resch 2007-10-04 00:43:41 +00:00
parent 838ef287da
commit 06e148c2ed
7 changed files with 119 additions and 65 deletions

2
TODO
View File

@ -4,8 +4,6 @@
intended functionality.
* Add plugin list and the ability to load/unload them from the preferences
dialog.
* Have core keep track of which plugins are activated or not, so it only loads
those on start-up.
* Have the UI request a list of activated plugins on start-up so it nows which
plugins to load.
* Figure out easy way for user-made plugins to add i18n support.

View File

@ -61,7 +61,7 @@ class AlertManager:
# Append the handler to the list in the handlers dictionary
self.handlers[alert_type].append(handler)
log.debug("Registered handler %s for alert %s", handler, alert_type)
log.debug("Registered handler for alert %s", alert_type)
def deregister_handler(self, handler):
"""De-registers the 'handler' function from all alert types."""

View File

@ -71,7 +71,8 @@ DEFAULT_PREFS = {
"max_download_speed": -1.0,
"max_upload_slots_global": -1,
"max_connections_per_torrent": -1,
"max_upload_slots_per_torrent": -1
"max_upload_slots_per_torrent": -1,
"enabled_plugins": ["Queue"]
}
class Core(dbus.service.Object):

View File

@ -33,13 +33,10 @@
"""PluginManager for Core"""
import os.path
import pkg_resources
import deluge.pluginmanagerbase
from deluge.log import LOG as log
class PluginManager:
class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
"""PluginManager handles the loading of plugins and provides plugins with
functions to access parts of the core."""
@ -52,34 +49,10 @@ class PluginManager:
self.status_fields = {}
# This will load any .eggs in the plugins folder inside the main
# deluge egg.. Need to scan the local plugin folder too.
plugin_dir = os.path.join(os.path.dirname(__file__), "..", "plugins")
pkg_resources.working_set.add_entry(plugin_dir)
pkg_env = pkg_resources.Environment([plugin_dir])
self.plugins = {}
for name in pkg_env:
egg = pkg_env[name][0]
egg.activate()
for name in egg.get_entry_map("deluge.plugin.core"):
entry_point = egg.get_entry_info("deluge.plugin.core", name)
cls = entry_point.load()
instance = cls(self)
self.plugins[name] = instance
log.info("Load plugin %s", name)
def shutdown(self):
log.debug("PluginManager shutting down..")
for plugin in self.plugins.values():
plugin.core.shutdown()
del self.plugins
def __getitem__(self, key):
return self.plugins[key]
# Call the PluginManagerBase constructor
deluge.pluginmanagerbase.PluginManagerBase.__init__(
self, "core.conf", "deluge.plugin.core")
def register_status_field(self, field, function):
"""Register a new status field. This can be used in the same way the
client requests other status information from core."""

104
deluge/pluginmanagerbase.py Normal file
View File

@ -0,0 +1,104 @@
#
# pluginmanagerbase.py
#
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@gmail.com>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
"""PluginManagerBase"""
import os.path
import pkg_resources
import deluge.common
from deluge.configmanager import ConfigManager
from deluge.log import LOG as log
class PluginManagerBase:
"""PluginManagerBase is a base class for PluginManagers to inherit"""
def __init__(self, config_file, entry_name):
log.debug("Plugin manager init..")
self.config = ConfigManager(config_file)
# This is the entry we want to load..
self.entry_name = entry_name
# Loaded plugins
self.plugins = {}
# Scan the plugin folders for plugins
self.scan_for_plugins()
# Load plugins that are enabled in the config.
for name in self.config["enabled_plugins"]:
self.load_plugin(name)
def shutdown(self):
log.debug("PluginManager shutting down..")
for plugin in self.plugins.values():
plugin.core.shutdown()
del self.plugins
def __getitem__(self, key):
return self.plugins[key]
def get_available_plugins(self):
"""Returns a list of the available plugins (name, version)"""
return self.available_plugins
def scan_for_plugins(self):
"""Scans for available plugins"""
plugin_dir = os.path.join(os.path.dirname(__file__), "plugins")
user_plugin_dir = os.path.join(deluge.common.get_config_dir("plugins"))
pkg_resources.working_set.add_entry(plugin_dir)
pkg_resources.working_set.add_entry(user_plugin_dir)
self.pkg_env = pkg_resources.Environment([plugin_dir, user_plugin_dir])
self.available_plugins = []
for name in self.pkg_env:
pkg_name = str(self.pkg_env[name][0]).split()[0]
pkg_version = str(self.pkg_env[name][0]).split()[1]
log.debug("Found plugin: %s %s", pkg_name, pkg_version)
self.available_plugins.append(pkg_name)
def load_plugin(self, name, version=None):
"""Loads a plugin with optional version"""
egg = self.pkg_env[name][0]
egg.activate()
for name in egg.get_entry_map(self.entry_name):
entry_point = egg.get_entry_info(self.entry_name, name)
cls = entry_point.load()
instance = cls(self)
self.plugins[name] = instance
log.info("Load plugin %s", name)

View File

@ -66,7 +66,8 @@ DEFAULT_PREFS = {
"window_height": 480,
"window_pane_position": -1,
"tray_download_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
"tray_upload_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0]
"tray_upload_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
"enabled_plugins": ["Queue"]
}
class GtkUI:

View File

@ -31,39 +31,16 @@
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
import os.path
import pkg_resources
import deluge.pluginmanagerbase
from deluge.log import LOG as log
class PluginManager:
class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
def __init__(self, gtkui):
self._gtkui = gtkui
# This will load any .eggs in the plugins folder inside the main
# deluge egg.. Need to scan the local plugin folder too.
plugin_dir = os.path.join(os.path.dirname(__file__), "../..", "plugins")
pkg_resources.working_set.add_entry(plugin_dir)
pkg_env = pkg_resources.Environment([plugin_dir])
self.plugins = {}
for name in pkg_env:
egg = pkg_env[name][0]
egg.activate()
modules = []
for name in egg.get_entry_map("deluge.plugin.ui.gtk"):
entry_point = egg.get_entry_info("deluge.plugin.ui.gtk", name)
cls = entry_point.load()
instance = cls(self)
self.plugins[name] = instance
log.info("Loaded plugin %s", name)
def __getitem__(self, key):
return self.plugins[key]
deluge.pluginmanagerbase.PluginManagerBase.__init__(
self, "gtkui.conf", "deluge.plugin.ui.gtk")
def get_torrentview(self):
"""Returns a reference to the torrentview component"""