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. intended functionality.
* Add plugin list and the ability to load/unload them from the preferences * Add plugin list and the ability to load/unload them from the preferences
dialog. 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 * Have the UI request a list of activated plugins on start-up so it nows which
plugins to load. plugins to load.
* Figure out easy way for user-made plugins to add i18n support. * 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 # Append the handler to the list in the handlers dictionary
self.handlers[alert_type].append(handler) 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): def deregister_handler(self, handler):
"""De-registers the 'handler' function from all alert types.""" """De-registers the 'handler' function from all alert types."""

View File

@ -71,7 +71,8 @@ DEFAULT_PREFS = {
"max_download_speed": -1.0, "max_download_speed": -1.0,
"max_upload_slots_global": -1, "max_upload_slots_global": -1,
"max_connections_per_torrent": -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): class Core(dbus.service.Object):

View File

@ -33,13 +33,10 @@
"""PluginManager for Core""" """PluginManager for Core"""
import os.path import deluge.pluginmanagerbase
import pkg_resources
from deluge.log import LOG as log from deluge.log import LOG as log
class PluginManager: class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
"""PluginManager handles the loading of plugins and provides plugins with """PluginManager handles the loading of plugins and provides plugins with
functions to access parts of the core.""" functions to access parts of the core."""
@ -52,34 +49,10 @@ class PluginManager:
self.status_fields = {} self.status_fields = {}
# This will load any .eggs in the plugins folder inside the main # Call the PluginManagerBase constructor
# deluge egg.. Need to scan the local plugin folder too. deluge.pluginmanagerbase.PluginManagerBase.__init__(
self, "core.conf", "deluge.plugin.core")
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]
def register_status_field(self, field, function): def register_status_field(self, field, function):
"""Register a new status field. This can be used in the same way the """Register a new status field. This can be used in the same way the
client requests other status information from core.""" 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_height": 480,
"window_pane_position": -1, "window_pane_position": -1,
"tray_download_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0], "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: class GtkUI:

View File

@ -31,39 +31,16 @@
# this exception statement from your version. If you delete this exception # this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here. # statement from all source files in the program, then also delete it here.
import os.path import deluge.pluginmanagerbase
import pkg_resources
from deluge.log import LOG as log from deluge.log import LOG as log
class PluginManager: class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
def __init__(self, gtkui): def __init__(self, gtkui):
self._gtkui = gtkui self._gtkui = gtkui
# This will load any .eggs in the plugins folder inside the main deluge.pluginmanagerbase.PluginManagerBase.__init__(
# deluge egg.. Need to scan the local plugin folder too. self, "gtkui.conf", "deluge.plugin.ui.gtk")
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]
def get_torrentview(self): def get_torrentview(self):
"""Returns a reference to the torrentview component""" """Returns a reference to the torrentview component"""