Queue plugin update.

Plugin system updates.
This commit is contained in:
Andrew Resch 2007-11-03 07:24:45 +00:00
parent c11e61355b
commit eacc6dd08f
12 changed files with 291 additions and 147 deletions

View File

@ -59,6 +59,14 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
log.debug("Registering status field %s with PluginManager", field) log.debug("Registering status field %s with PluginManager", field)
self.status_fields[field] = function self.status_fields[field] = function
def deregister_status_field(self, field):
"""Deregisters a status field"""
log.debug("Deregistering status field %s with PluginManager", field)
try:
del self.status_fields[field]
except:
log.warning("Unable to deregister status field %s", field)
def get_status(self, torrent_id, fields): def get_status(self, torrent_id, fields):
"""Return the value of status fields for the selected torrent_id.""" """Return the value of status fields for the selected torrent_id."""
status = {} status = {}
@ -76,7 +84,14 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
self.hooks[hook].append(function) self.hooks[hook].append(function)
except KeyError: except KeyError:
log.warning("Plugin attempting to register invalid hook.") log.warning("Plugin attempting to register invalid hook.")
def deregister_hook(self, hook, function):
"""Deregisters a hook function"""
try:
self.hooks[hook].remove(function)
except:
log.warning("Unable to deregister hook %s", hook)
def run_post_torrent_add(self, torrent_id): def run_post_torrent_add(self, torrent_id):
"""This hook is run after a torrent has been added to the session.""" """This hook is run after a torrent has been added to the session."""
log.debug("run_post_torrent_add") log.debug("run_post_torrent_add")

View File

@ -108,6 +108,7 @@ class PluginManagerBase:
entry_point = egg.get_entry_info(self.entry_name, name) entry_point = egg.get_entry_info(self.entry_name, name)
cls = entry_point.load() cls = entry_point.load()
instance = cls(self) instance = cls(self)
instance.enable()
plugin_name = plugin_name.replace("-", " ") plugin_name = plugin_name.replace("-", " ")
self.plugins[plugin_name] = instance self.plugins[plugin_name] = instance
if plugin_name not in self.config["enabled_plugins"]: if plugin_name not in self.config["enabled_plugins"]:
@ -116,11 +117,10 @@ class PluginManagerBase:
def disable_plugin(self, name): def disable_plugin(self, name):
"""Disables a plugin""" """Disables a plugin"""
self.plugins[name].disable()
try: try:
self.plugins[name].disable()
del self.plugins[name] del self.plugins[name]
self.config["enabled_plugins"].remove(plugin_name) self.config["enabled_plugins"].remove(name)
except KeyError: except KeyError:
log.warning("Plugin %s is not enabled..", name) log.warning("Plugin %s is not enabled..", name)

View File

@ -1,9 +1,51 @@
#
# init.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.
from deluge.log import LOG as log
class PluginBase: class PluginBase:
def __init__(self): def __init__(self):
pass self.plugin = None
def enable(self): def enable(self):
pass try:
self.plugin.enable()
except Exception, e:
log.warning("Unable to enable plugin: %s", e)
def disable(self): def disable(self):
pass try:
self.plugin.disable()
except Exception, e:
log.warning("Unable to disable plugin: %s", e)

View File

@ -31,20 +31,24 @@
# 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.
from core import Core
from gtkui import GtkUI
from deluge.log import LOG as log from deluge.log import LOG as log
class CorePlugin: from deluge.plugins.init import PluginBase
def __init__(self, plugin_manager):
# Load the Core portion of the plugin
self.core = Core(plugin_manager)
def disable(self):
pass
class GtkUIPlugin: class CorePlugin(PluginBase):
def __init__(self, plugin_manager): def __init__(self, plugin_api):
# Load the Core portion of the plugin
try:
from core import Core
self.plugin = Core(plugin_api)
except Exception, e:
log.debug("Did not load a Core plugin: %s", e)
class GtkUIPlugin(PluginBase):
def __init__(self, plugin_api):
# Load the GtkUI portion of the plugin # Load the GtkUI portion of the plugin
self.gtkui = GtkUI(plugin_manager) try:
from gtkui import GtkUI
self.plugin = GtkUI(plugin_api)
except Exception, e:
log.debug("Did not load a GtkUI plugin: %s", e)

View File

@ -35,10 +35,12 @@ from torrentqueue import TorrentQueue
from deluge.log import LOG as log from deluge.log import LOG as log
class Core: class Core:
def __init__(self, plugin): def __init__(self, plugin_api):
# Get the pluginmanager reference # Get the plugin_api
self.plugin = plugin self.plugin = plugin_api
log.info("Queue Core plugin initialized..")
def enable(self):
# Instantiate the TorrentQueue object # Instantiate the TorrentQueue object
self.queue = TorrentQueue() self.queue = TorrentQueue()
@ -50,14 +52,21 @@ class Core:
# Register the 'queue' status field # Register the 'queue' status field
self.plugin.register_status_field("queue", self._status_field_queue) self.plugin.register_status_field("queue", self._status_field_queue)
log.info("Queue Core plugin initialized..") log.debug("Queue Core plugin enabled..")
def disable(self): def disable(self):
pass # Save queue state
def shutdown(self):
# Save the queue state
self.queue.save_state() self.queue.save_state()
# Delete the queue
del self.queue
self.queue = None
# De-register hooks
self.plugin.deregister_hook("post_torrent_add", self._post_torrent_add)
self.plugin.deregister_hook("post_torrent_remove",
self._post_torrent_remove)
# De-register status fields
self.plugin.deregister_status_field("queue")
## Hooks for core ## ## Hooks for core ##
def _post_torrent_add(self, torrent_id): def _post_torrent_add(self, torrent_id):

View File

@ -33,40 +33,29 @@
import pkg_resources import pkg_resources
import gtk.glade import gtk.glade
import gettext
import locale
from deluge.log import LOG as log from deluge.log import LOG as log
import ui
class GtkUI: class GtkUI(ui.UI):
def __init__(self, plugin_manager): def __init__(self, plugin_api):
# Initialize gettext log.debug("Calling UI init")
locale.setlocale(locale.LC_MESSAGES, '') # Call UI constructor
locale.bindtextdomain("deluge", ui.UI.__init__(self, plugin_api)
pkg_resources.resource_filename(
"deluge", "i18n"))
locale.textdomain("deluge")
gettext.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
gettext.textdomain("deluge")
gettext.install("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
log.debug("Queue GtkUI plugin initalized..") log.debug("Queue GtkUI plugin initalized..")
self.plugin = plugin_manager
def load_interface(self):
# Get the queue menu from the glade file # Get the queue menu from the glade file
menu_glade = gtk.glade.XML(pkg_resources.resource_filename("queue", menu_glade = gtk.glade.XML(pkg_resources.resource_filename("queue",
"glade/queuemenu.glade")) "glade/queuemenu.glade"))
menu_glade.signal_autoconnect({ menu_glade.signal_autoconnect({
"on_menuitem_queuetop_activate": \ "on_menuitem_queuetop_activate": \
self.on_menuitem_queuetop_activate, self.on_queuetop_activate,
"on_menuitem_queueup_activate": self.on_menuitem_queueup_activate, "on_menuitem_queueup_activate": self.on_queueup_activate,
"on_menuitem_queuedown_activate": \ "on_menuitem_queuedown_activate": \
self.on_menuitem_queuedown_activate, self.on_queuedown_activate,
"on_menuitem_queuebottom_activate": \ "on_menuitem_queuebottom_activate": \
self.on_menuitem_queuebottom_activate self.on_queuebottom_activate
}) })
menu = menu_glade.get_widget("menu_queue") menu = menu_glade.get_widget("menu_queue")
@ -76,93 +65,45 @@ class GtkUI:
# self.torrent_queue_changed_signal) # self.torrent_queue_changed_signal)
# Get the torrentview component from the plugin manager # Get the torrentview component from the plugin manager
self.torrentview = self.plugin.get_torrentview() #self.torrentview = self.plugin.get_torrentview()
# Add the '#' column at the first position # Add the '#' column at the first position
self.torrentview.add_text_column("#", #self.torrentview.add_text_column("#",
self.plugin.add_torrentview_text_column("#",
col_type=int, col_type=int,
position=0, position=0,
status_field=["queue"]) status_field=["queue"])
# Update the new column right away # Update the new column right away
self.torrentview.update(["#"]) self.update_interface()
# Add a toolbar buttons # Add a toolbar buttons
self.plugin.get_toolbar().add_separator() self.toolbar_sep = self.plugin.add_toolbar_separator()
self.plugin.get_toolbar().add_toolbutton(stock="gtk-go-up", self.toolbutton_up = self.plugin.add_toolbar_button(
stock="gtk-go-up",
label=_("Queue Up"), label=_("Queue Up"),
tooltip=_("Queue selected torrents up"), tooltip=_("Queue selected torrents up"),
callback=self.on_toolbutton_queueup_clicked) callback=self.on_queueup_activate)
self.plugin.get_toolbar().add_toolbutton(stock="gtk-go-down", self.toolbutton_down = self.plugin.add_toolbar_button(
stock="gtk-go-down",
label=_("Queue Down"), label=_("Queue Down"),
tooltip=_("Queue selected torrents down"), tooltip=_("Queue selected torrents down"),
callback=self.on_toolbutton_queuedown_clicked) callback=self.on_queuedown_activate)
# Add the queue menu to the torrent menu # Add the queue menu to the torrent menu
queue_menuitem = gtk.ImageMenuItem("Queue") self.queue_menuitem = gtk.ImageMenuItem("Queue")
queue_image = gtk.Image() queue_image = gtk.Image()
queue_image.set_from_stock(gtk.STOCK_SORT_ASCENDING, gtk.ICON_SIZE_MENU) queue_image.set_from_stock(gtk.STOCK_SORT_ASCENDING, gtk.ICON_SIZE_MENU)
queue_menuitem.set_image(queue_image) self.queue_menuitem.set_image(queue_image)
queue_menuitem.set_submenu(menu) self.queue_menuitem.set_submenu(menu)
queue_menuitem.show_all() self.queue_menuitem.show_all()
self.plugin.get_torrentmenu().append(queue_menuitem) self.plugin.add_torrentmenu_menu(self.queue_menuitem)
## Menu callbacks ##
def on_menuitem_queuetop_activate(self, data=None):
log.debug("on_menuitem_queuetop_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_top(torrent_id)
return
def on_menuitem_queueup_activate(self, data=None):
log.debug("on_menuitem_queueup_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_up(torrent_id)
return
def on_menuitem_queuedown_activate(self, data=None):
log.debug("on_menuitem_queuedown_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_down(torrent_id)
return
def on_menuitem_queuebottom_activate(self, data=None):
log.debug("on_menuitem_queuebottom_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_bottom(torrent_id)
return
## Toolbutton callbacks ##
def on_toolbutton_queuedown_clicked(self, widget):
log.debug("on_toolbutton_queuedown_clicked")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_down(torrent_id)
return
def on_toolbutton_queueup_clicked(self, widget):
log.debug("on_toolbutton_queueup_clicked")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_up(torrent_id)
return
## Signals ## def unload_interface(self):
def torrent_queue_changed_signal(self): self.plugin.remove_torrentmenu_menu(self.queue_menuitem)
"""This function is called whenever we receive a 'torrent_queue_changed' self.plugin.remove_toolbar_button(self.toolbar_sep)
signal from the core plugin. self.plugin.remove_toolbar_button(self.toolbutton_up)
""" self.plugin.remove_toolbar_button(self.toolbutton_down)
log.debug("torrent_queue_changed signal received..") self.plugin.remove_torrentview_column("#")
# We only need to update the queue column
self.torrentview.update(["#"]) def update_interface(self):
return self.plugin.update_torrent_view(["#"])

View File

@ -0,0 +1,116 @@
#
# ui.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.
import gettext
import locale
import pkg_resources
from deluge.log import LOG as log
class UI:
def __init__(self, plugin_api):
self.plugin = plugin_api
# Initialize gettext
locale.setlocale(locale.LC_MESSAGES, '')
locale.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
locale.textdomain("deluge")
gettext.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
gettext.textdomain("deluge")
gettext.install("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
def enable(self):
log.debug("Enabling UI plugin")
# Load the interface and connect the callbacks
self.load_interface()
def disable(self):
self.unload_interface()
def load_interface(self):
pass
def unload_interface(self):
pass
def update_interface(self):
pass
## Menu callbacks ##
def on_queuetop_activate(self, data=None):
log.debug("on_menuitem_queuetop_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_top(torrent_id)
return
def on_queueup_activate(self, data=None):
log.debug("on_menuitem_queueup_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_up(torrent_id)
return
def on_queuedown_activate(self, data=None):
log.debug("on_menuitem_queuedown_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_down(torrent_id)
return
def on_queuebottom_activate(self, data=None):
log.debug("on_menuitem_queuebottom_activate")
# Get the selected torrents
torrent_ids = self.plugin.get_selected_torrents()
for torrent_id in torrent_ids:
self.core.queue_bottom(torrent_id)
return
## Signals ##
def torrent_queue_changed_signal(self):
"""This function is called whenever we receive a 'torrent_queue_changed'
signal from the core plugin.
"""
log.debug("torrent_queue_changed signal received..")
# We only need to update the queue column
# self.torrentview.update(["#"])
self.update_interface()
return

View File

@ -46,7 +46,7 @@ setup(
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
Queue = queue:CorePlugin Queue = queue:CorePlugin
[deluge.plugin.ui.gtk] [deluge.plugin.gtkui]
Queue = queue:GtkUIPlugin Queue = queue:GtkUIPlugin
""" """
) )

View File

@ -36,19 +36,19 @@ from deluge.log import LOG as log
from deluge.plugins.init import PluginBase from deluge.plugins.init import PluginBase
class CorePlugin(PluginBase): class CorePlugin(PluginBase):
def __init__(self, plugin_manager): def __init__(self, plugin_api):
# Load the Core portion of the plugin # Load the Core portion of the plugin
try: try:
from core import Core from core import Core
self.core = Core() self.plugin = Core(plugin_api)
except: except:
pass pass
class GtkUIPlugin(PluginBase): class GtkUIPlugin(PluginBase):
def __init__(self, plugin_manager): def __init__(self, plugin_api):
# Load the GtkUI portion of the plugin # Load the GtkUI portion of the plugin
try: try:
from gtkui import GtkUI from gtkui import GtkUI
self.gtkui = GtkUI() self.plugin = GtkUI()
except: except:
pass pass

View File

@ -34,7 +34,7 @@
from deluge.log import LOG as log from deluge.log import LOG as log
class Core: class Core:
def __init__(self): def __init__(self, plugin_api):
pass pass
def enable(self): def enable(self):

View File

@ -53,23 +53,33 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase,
deluge.pluginmanagerbase.PluginManagerBase.__init__( deluge.pluginmanagerbase.PluginManagerBase.__init__(
self, "gtkui.conf", "deluge.plugin.gtkui") self, "gtkui.conf", "deluge.plugin.gtkui")
def get_torrentview(self):
"""Returns a reference to the torrentview component"""
return component.get("TorrentView")
def get_toolbar(self): ## Plugin functions.. will likely move to own class..
"""Returns a reference to the toolbar component"""
return component.get("ToolBar")
def get_menubar(self):
"""Returns a reference to the menubar component"""
return component.get("MenuBar")
def get_torrentmenu(self):
"""Returns a reference to the torrentmenu component"""
return component.get("MenuBar").torrentmenu
def add_torrentview_text_column(self, *args, **kwargs):
return component.get("TorrentView").add_text_column(*args, **kwargs)
def remove_torrentview_column(self, *args):
return component.get("TorrentView").remove_column(*args)
def add_toolbar_separator(self):
return component.get("ToolBar").add_separator()
def add_toolbar_button(self, *args, **kwargs):
return component.get("ToolBar").add_toolbutton(*args, **kwargs)
def remove_toolbar_button(self, *args):
return component.get("ToolBar").remove(*args)
def add_torrentmenu_menu(self, *args):
return component.get("MenuBar").torrentmenu.append(*args)
def remove_torrentmenu_menu(self, *args):
return component.get("MenuBar").torrentmenu.remove(*args)
def update_torrent_view(self, *args):
return component.get("TorrentView").update(*args)
def get_selected_torrents(self): def get_selected_torrents(self):
"""Returns a list of the selected torrent_ids""" """Returns a list of the selected torrent_ids"""
return component.get("TorrentView").get_selected_torrents() return component.get("TorrentView").get_selected_torrents()

View File

@ -108,7 +108,7 @@ class ToolBar(component.Component):
# Show the new toolbutton # Show the new toolbutton
toolbutton.show() toolbutton.show()
return return toolbutton
def add_separator(self, position=None): def add_separator(self, position=None):
"""Adds a separator toolitem""" """Adds a separator toolitem"""
@ -118,8 +118,15 @@ class ToolBar(component.Component):
else: else:
# Append the separator # Append the separator
self.toolbar.insert(sep, -1) self.toolbar.insert(sep, -1)
return
sep.show()
return sep
def remove(self, widget):
"""Removes a widget from the toolbar"""
self.toolbar.remove(widget)
### Callbacks ### ### Callbacks ###
def on_toolbutton_add_clicked(self, data): def on_toolbutton_add_clicked(self, data):
log.debug("on_toolbutton_add_clicked") log.debug("on_toolbutton_add_clicked")