From e52018bfcd660251d94af2878b58ebacf6d82424 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 10 Dec 2010 04:59:05 +0000 Subject: [PATCH 1/7] Dont make code that still uses the old "TorrentAddedEvent" fail, instead log a warning and make it work. --- deluge/core/eventmanager.py | 14 +++++++++++++- deluge/ui/client.py | 37 +++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/deluge/core/eventmanager.py b/deluge/core/eventmanager.py index b4aa1759a..0f616457f 100644 --- a/deluge/core/eventmanager.py +++ b/deluge/core/eventmanager.py @@ -53,7 +53,19 @@ class EventManager(component.Component): if event.name in self.handlers: for handler in self.handlers[event.name]: #log.debug("Running handler %s for event %s with args: %s", event.name, handler, event.args) - handler(*event.args) + try: + handler(*event.args) + except TypeError: + if event.name != "TorrentAddedEvent": + raise + else: + log.warning("TorrentAddedEvent recently got an extra " + "argument, \"from_state\" and the handler " + "\"%s\" is not accepting that extra " + "argument. Correcting for now but this code " + "should be changed.", handler) + handler(event.args[0]) + def register_event_handler(self, event, handler): """ diff --git a/deluge/ui/client.py b/deluge/ui/client.py index 3fbae6e6f..f040244b4 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -140,7 +140,7 @@ class DelugeRPCProtocol(Protocol): while data: # Increase the byte counter self.factory.bytes_recv += len(data) - + dobj = zlib.decompressobj() try: request = rencode.loads(dobj.decompress(data)) @@ -167,9 +167,22 @@ class DelugeRPCProtocol(Protocol): #log.debug("Received RPCEvent: %s", event) # A RPCEvent was received from the daemon so run any handlers # associated with it. + def call_handler(event, handler, args): + try: + handler(*args) + except TypeError: + if event != "TorrentAddedEvent": + raise + else: + log.warning("TorrentAddedEvent recently got an extra " + "argument, \"from_state\" and the handler " + "\"%s\" is not accepting that extra " + "argument. Correcting for now but this code " + "should be changed.", handler) + handler(args[0]) if event in self.factory.event_handlers: for handler in self.factory.event_handlers[event]: - reactor.callLater(0, handler, *request[2]) + reactor.callLater(0, call_handler, event, handler, request[2]) continue request_id = request[1] @@ -213,7 +226,7 @@ class DelugeRPCClientFactory(ClientFactory): def __init__(self, daemon, event_handlers): self.daemon = daemon self.event_handlers = event_handlers - + self.bytes_recv = 0 self.bytes_sent = 0 @@ -329,7 +342,7 @@ class DaemonSSLProxy(DaemonProxy): :param request_id: the request_id of the Deferred to pop :type request_id: int - + """ return self.__deferred.pop(request_id) @@ -343,7 +356,7 @@ class DaemonSSLProxy(DaemonProxy): :param handler: the function to be called when `:param:event` is emitted from the daemon :type handler: function - + """ if event not in self.__factory.event_handlers: # This is a new event to handle, so we need to tell the daemon @@ -422,10 +435,10 @@ class DaemonSSLProxy(DaemonProxy): def get_bytes_recv(self): return self.__factory.bytes_recv - + def get_bytes_sent(self): return self.__factory.bytes_sent - + class DaemonClassicProxy(DaemonProxy): def __init__(self, event_handlers={}): import deluge.core.daemon @@ -466,7 +479,7 @@ class DaemonClassicProxy(DaemonProxy): :param handler: the function to be called when `:param:event` is emitted from the daemon :type handler: function - + """ self.__daemon.core.eventmanager.register_event_handler(event, handler) @@ -571,7 +584,7 @@ class Client(object): :rtype: bool :raises OSError: received from subprocess.call() - + """ try: if deluge.common.windows_check(): @@ -679,7 +692,7 @@ class Client(object): def get_bytes_recv(self): """ Returns the number of bytes received from the daemon. - + :returns: the number of bytes received :rtype: int """ @@ -688,11 +701,11 @@ class Client(object): def get_bytes_sent(self): """ Returns the number of bytes sent to the daemon. - + :returns: the number of bytes sent :rtype: int """ return self._daemon_proxy.get_bytes_sent() - + # This is the object clients will use client = Client() From 860457ff4803e54e52496c4d50cddfeb6ad96efb Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 10 Dec 2010 05:01:31 +0000 Subject: [PATCH 2/7] Update ChangeLog. --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 4f48c9d88..b9d2cf6be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ * #1112: Fix renaming files in add torrent dialog * #1247: Fix deluge-gtk from hanging on shutdown * #995: Rewrote tracker_icons + * Make the distinction between adding to the session new unmanaged torrents and torrents loaded from state. ==== GtkUI ==== * Fix uncaught exception when closing deluge in classic mode From 90d23ce58261e3b0b288501d7aa01c97dc72d21a Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 10 Dec 2010 05:42:19 +0000 Subject: [PATCH 3/7] Revert e52018bfcd660251d94af2878b58ebacf6d82424. Simply fail. It's documented on the ChangeLog. --- deluge/core/eventmanager.py | 14 +------------- deluge/ui/client.py | 15 +-------------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/deluge/core/eventmanager.py b/deluge/core/eventmanager.py index 0f616457f..b4aa1759a 100644 --- a/deluge/core/eventmanager.py +++ b/deluge/core/eventmanager.py @@ -53,19 +53,7 @@ class EventManager(component.Component): if event.name in self.handlers: for handler in self.handlers[event.name]: #log.debug("Running handler %s for event %s with args: %s", event.name, handler, event.args) - try: - handler(*event.args) - except TypeError: - if event.name != "TorrentAddedEvent": - raise - else: - log.warning("TorrentAddedEvent recently got an extra " - "argument, \"from_state\" and the handler " - "\"%s\" is not accepting that extra " - "argument. Correcting for now but this code " - "should be changed.", handler) - handler(event.args[0]) - + handler(*event.args) def register_event_handler(self, event, handler): """ diff --git a/deluge/ui/client.py b/deluge/ui/client.py index f040244b4..d88f6e692 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -167,22 +167,9 @@ class DelugeRPCProtocol(Protocol): #log.debug("Received RPCEvent: %s", event) # A RPCEvent was received from the daemon so run any handlers # associated with it. - def call_handler(event, handler, args): - try: - handler(*args) - except TypeError: - if event != "TorrentAddedEvent": - raise - else: - log.warning("TorrentAddedEvent recently got an extra " - "argument, \"from_state\" and the handler " - "\"%s\" is not accepting that extra " - "argument. Correcting for now but this code " - "should be changed.", handler) - handler(args[0]) if event in self.factory.event_handlers: for handler in self.factory.event_handlers[event]: - reactor.callLater(0, call_handler, event, handler, request[2]) + reactor.callLater(0, handler, *request[2]) continue request_id = request[1] From 0f36a65aafd9770daf4ccad2d21a93d38546b601 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 10 Dec 2010 05:49:38 +0000 Subject: [PATCH 4/7] Update ChangeLog with the backwards incompatible notice. --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b9d2cf6be..45bbb65b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,7 @@ * #1112: Fix renaming files in add torrent dialog * #1247: Fix deluge-gtk from hanging on shutdown * #995: Rewrote tracker_icons - * Make the distinction between adding to the session new unmanaged torrents and torrents loaded from state. + * Make the distinction between adding to the session new unmanaged torrents and torrents loaded from state. This will break backwards compatability. ==== GtkUI ==== * Fix uncaught exception when closing deluge in classic mode From 67ea05921cb904cb2ddf5811cd96534321bfeefa Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 11 Dec 2010 05:11:18 +0000 Subject: [PATCH 5/7] Implemented passing a copy of an event instead of it's arguments to event handlers. Necessary changes to the event handlers on deluge's code were made, plugins still need to be ported to this new style. --- ChangeLog | 2 + deluge/core/eventmanager.py | 2 +- deluge/core/rpcserver.py | 3 +- deluge/event.py | 84 ++++++++++++++++++++++---------- deluge/ui/client.py | 10 ++-- deluge/ui/console/eventlog.py | 50 +++++++++---------- deluge/ui/console/main.py | 10 ++-- deluge/ui/coreconfig.py | 4 +- deluge/ui/gtkui/files_tab.py | 64 ++++++++++++------------ deluge/ui/gtkui/mainwindow.py | 8 +-- deluge/ui/gtkui/menubar.py | 6 +-- deluge/ui/gtkui/pluginmanager.py | 8 +-- deluge/ui/gtkui/statusbar.py | 6 +-- deluge/ui/gtkui/systemtray.py | 6 +-- deluge/ui/gtkui/torrentview.py | 24 ++++----- deluge/ui/sessionproxy.py | 26 +++++----- deluge/ui/web/pluginmanager.py | 38 +++++++-------- 17 files changed, 195 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45bbb65b0..e8ab04cef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ === Deluge 1.3.0 (In Development) === + ==== Core ==== * Implement #1063 option to delete torrent file copy on torrent removal - patch from Ghent * Implement #457 progress bars for folders @@ -8,6 +9,7 @@ * #1247: Fix deluge-gtk from hanging on shutdown * #995: Rewrote tracker_icons * Make the distinction between adding to the session new unmanaged torrents and torrents loaded from state. This will break backwards compatability. + * Pass a copy of an event instead of passing the event arguments to the event handlers. This will break backwards compatability. ==== GtkUI ==== * Fix uncaught exception when closing deluge in classic mode diff --git a/deluge/core/eventmanager.py b/deluge/core/eventmanager.py index b4aa1759a..7687bfc30 100644 --- a/deluge/core/eventmanager.py +++ b/deluge/core/eventmanager.py @@ -53,7 +53,7 @@ class EventManager(component.Component): if event.name in self.handlers: for handler in self.handlers[event.name]: #log.debug("Running handler %s for event %s with args: %s", event.name, handler, event.args) - handler(*event.args) + handler(event.copy()) def register_event_handler(self, event, handler): """ diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py index ef088fe5b..a84ccbf75 100644 --- a/deluge/core/rpcserver.py +++ b/deluge/core/rpcserver.py @@ -485,7 +485,8 @@ class RPCServer(component.Component): # Find sessions interested in this event for session_id, interest in self.factory.interested_events.iteritems(): if event.name in interest: - log.debug("Emit Event: %s %s", event.name, event.args) + log.debug("Emit Event: %s %s", event.name, zip(event.__slots__, + event.args)) # This session is interested so send a RPC_EVENT self.factory.session_protocols[session_id].sendData( (RPC_EVENT, event.name, event.args) diff --git a/deluge/event.py b/deluge/event.py index e2b0f6f8b..c24663fac 100644 --- a/deluge/event.py +++ b/deluge/event.py @@ -2,6 +2,7 @@ # event.py # # Copyright (C) 2009 Andrew Resch +# Copyright (C) 2010 Pedro Algarvio # # Deluge is free software. # @@ -47,6 +48,8 @@ class DelugeEventMetaClass(type): """ This metaclass simply keeps a list of all events classes created. """ + __slots__ = () + def __init__(cls, name, bases, dct): super(DelugeEventMetaClass, cls).__init__(name, bases, dct) if name != "DelugeEvent": @@ -62,23 +65,26 @@ class DelugeEvent(object): :type args: list """ + __slots__ = () __metaclass__ = DelugeEventMetaClass def _get_name(self): return self.__class__.__name__ + name = property(fget=_get_name) def _get_args(self): - if not hasattr(self, "_args"): - return [] - return self._args - - name = property(fget=_get_name) + return [getattr(self, arg) for arg in self.__slots__] args = property(fget=_get_args) + def copy(self): + return self.__class__(*self.args) + class TorrentAddedEvent(DelugeEvent): """ Emitted when a new torrent is successfully added to the session. """ + __slots__ = ('torrent_id', 'from_state') + def __init__(self, torrent_id, from_state): """ :param torrent_id: the torrent_id of the torrent that was added @@ -86,34 +92,41 @@ class TorrentAddedEvent(DelugeEvent): :param from_state: was the torrent loaded from state? Or is it a new torrent. :type from_state: bool """ - self._args = [torrent_id, from_state] + self.torrent_id = torrent_id + self.from_state = from_state class TorrentRemovedEvent(DelugeEvent): """ Emitted when a torrent has been removed from the session. """ + __slots__ = ('torrent_id',) + def __init__(self, torrent_id): """ :param torrent_id: the torrent_id :type torrent_id: string """ - self._args = [torrent_id] + self.torrent_id = torrent_id class PreTorrentRemovedEvent(DelugeEvent): """ Emitted when a torrent is about to be removed from the session. """ + __slots__ = ('torrent_id',) + def __init__(self, torrent_id): """ :param torrent_id: the torrent_id :type torrent_id: string """ - self._args = [torrent_id] + self.torrent_id = torrent_id class TorrentStateChangedEvent(DelugeEvent): """ Emitted when a torrent changes state. """ + __slots__ = ('torrent_id', 'state') + def __init__(self, torrent_id, state): """ :param torrent_id: the torrent_id @@ -121,18 +134,20 @@ class TorrentStateChangedEvent(DelugeEvent): :param state: the new state :type state: string """ - self._args = [torrent_id, state] + self.torrent_id = torrent_id + self.state = state class TorrentQueueChangedEvent(DelugeEvent): """ Emitted when the queue order has changed. """ - pass class TorrentFolderRenamedEvent(DelugeEvent): """ Emitted when a folder within a torrent has been renamed. """ + __slots__ = ('torrent_id', 'old', 'new') + def __init__(self, torrent_id, old, new): """ :param torrent_id: the torrent_id @@ -142,44 +157,54 @@ class TorrentFolderRenamedEvent(DelugeEvent): :param new: the new folder name :type new: string """ - self._args = [torrent_id, old, new] + self.torrent_id = torrent_id + self.old = old + self.new = new class TorrentFileRenamedEvent(DelugeEvent): """ Emitted when a file within a torrent has been renamed. """ - def __init__(self, torrent_id, index, name): + __slots__ = ('torrent_id', 'index', 'filename') + + def __init__(self, torrent_id, index, filename): """ :param torrent_id: the torrent_id :type torrent_id: string :param index: the index of the file :type index: int - :param name: the new filename - :type name: string + :param filename: the new filename + :type filename: string """ - self._args = [torrent_id, index, name] + self.torrent_id = torrent_id + self.index = index + self.filename = filename class TorrentFinishedEvent(DelugeEvent): """ Emitted when a torrent finishes downloading. """ + __slots__ = ('torrent_id',) + def __init__(self, torrent_id): """ :param torrent_id: the torrent_id :type torrent_id: string """ - self._args = [torrent_id] + self.torrent_id = torrent_id class TorrentResumedEvent(DelugeEvent): """ Emitted when a torrent resumes from a paused state. """ + __slots__ = ('torrent_id',) + def __init__(self, torrent_id): """ :param torrent_id: the torrent_id :type torrent_id: string """ - self._args = [torrent_id] + self.torrent_id = torrent_id class TorrentFileCompletedEvent(DelugeEvent): """ @@ -188,6 +213,8 @@ class TorrentFileCompletedEvent(DelugeEvent): This will only work with libtorrent 0.15 or greater. """ + __slots__ = ('torrent_id', 'index') + def __init__(self, torrent_id, index): """ :param torrent_id: the torrent_id @@ -195,68 +222,75 @@ class TorrentFileCompletedEvent(DelugeEvent): :param index: the file index :type index: int """ - self._args = [torrent_id, index] + self.torrent_id = torrent_id + self.index = index class NewVersionAvailableEvent(DelugeEvent): """ Emitted when a more recent version of Deluge is available. """ + __slots__ = ('new_release',) + def __init__(self, new_release): """ :param new_release: the new version that is available :type new_release: string """ - self._args = [new_release] + self.new_release = new_release class SessionStartedEvent(DelugeEvent): """ Emitted when a session has started. This typically only happens once when the daemon is initially started. """ - pass class SessionPausedEvent(DelugeEvent): """ Emitted when the session has been paused. """ - pass class SessionResumedEvent(DelugeEvent): """ Emitted when the session has been resumed. """ - pass class ConfigValueChangedEvent(DelugeEvent): """ Emitted when a config value changes in the Core. """ + __slots__ = ('key', 'value') + def __init__(self, key, value): """ :param key: the key that changed :type key: string :param value: the new value of the `:param:key` """ - self._args = [key, value] + self.key = key + self.value = value class PluginEnabledEvent(DelugeEvent): """ Emitted when a plugin is enabled in the Core. """ + __slots__ = ('name',) + def __init__(self, name): """ :param name: the plugin name :type name: string """ - self._args = [name] + self.name = name class PluginDisabledEvent(DelugeEvent): """ Emitted when a plugin is disabled in the Core. """ + __slots__ = ('name',) + def __init__(self, name): """ :param name: the plugin name :type name: string """ - self._args = [name] + self.name = name diff --git a/deluge/ui/client.py b/deluge/ui/client.py index d88f6e692..1a4506691 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -45,6 +45,7 @@ import zlib import deluge.common import deluge.component as component from deluge.log import LOG as log +from deluge.event import known_events if deluge.common.windows_check(): import win32api @@ -163,13 +164,14 @@ class DelugeRPCProtocol(Protocol): message_type = request[0] if message_type == RPC_EVENT: - event = request[1] + event_name = request[1] #log.debug("Received RPCEvent: %s", event) # A RPCEvent was received from the daemon so run any handlers # associated with it. - if event in self.factory.event_handlers: - for handler in self.factory.event_handlers[event]: - reactor.callLater(0, handler, *request[2]) + if event_name in self.factory.event_handlers: + event = known_events[event_name](*request[2]) + for handler in self.factory.event_handlers[event_name]: + reactor.callLater(0, handler, event.copy()) continue request_id = request[1] diff --git a/deluge/ui/console/eventlog.py b/deluge/ui/console/eventlog.py index 745709e73..2e74c1fe5 100644 --- a/deluge/ui/console/eventlog.py +++ b/deluge/ui/console/eventlog.py @@ -61,53 +61,53 @@ class EventLog(component.Component): client.register_event_handler("PluginEnabledEvent", self.on_plugin_enabled_event) client.register_event_handler("PluginDisabledEvent", self.on_plugin_disabled_event) - def on_torrent_added_event(self, torrent_id, from_state): + def on_torrent_added_event(self, event): def on_torrent_status(status): self.console.write(self.prefix + "TorrentAdded(from_state=%s): {!info!}%s (%s)" % ( - from_state, status["name"], torrent_id) + event.from_state, status["name"], event.torrent_id) ) - client.core.get_torrent_status(torrent_id, ["name"]).addCallback(on_torrent_status) + client.core.get_torrent_status(event.torrent_id, ["name"]).addCallback(on_torrent_status) - def on_torrent_removed_event(self, torrent_id): + def on_torrent_removed_event(self, event): self.console.write(self.prefix + "TorrentRemoved: {!info!}%s (%s)" % - (self.console.get_torrent_name(torrent_id), torrent_id)) + (self.console.get_torrent_name(event.torrent_id), event.torrent_id)) - def on_torrent_state_changed_event(self, torrent_id, state): + def on_torrent_state_changed_event(self, event): # Modify the state string color - if state in colors.state_color: - state = colors.state_color[state] + state + if event.state in colors.state_color: + state = colors.state_color[event.state] + event.state self.console.write(self.prefix + "TorrentStateChanged: %s {!info!}%s (%s)" % - (state, self.console.get_torrent_name(torrent_id), torrent_id)) + (state, self.console.get_torrent_name(event.torrent_id), event.torrent_id)) - def on_torrent_paused_event(self, torrent_id): + def on_torrent_paused_event(self, event): self.console.write(self.prefix + "TorrentPaused: {!info!}%s (%s)" % - (self.console.get_torrent_name(torrent_id), torrent_id)) + (self.console.get_torrent_name(event.torrent_id), event.torrent_id)) - def on_torrent_finished_event(self, torrent_id): + def on_torrent_finished_event(self, event): self.console.write(self.prefix + "TorrentFinished: {!info!}%s (%s)" % - (self.console.get_torrent_name(torrent_id), torrent_id)) + (self.console.get_torrent_name(event.torrent_id), event.torrent_id)) - def on_new_version_available_event(self, version): + def on_new_version_available_event(self, event): self.console.write(self.prefix + "NewVersionAvailable: {!info!}%s" % - (version)) + (event.new_release)) - def on_session_paused_event(self): + def on_session_paused_event(self, event): self.console.write(self.prefix + "SessionPaused") - def on_session_resumed_event(self): + def on_session_resumed_event(self, event): self.console.write(self.prefix + "SessionResumed") - def on_config_value_changed_event(self, key, value): + def on_config_value_changed_event(self, event): color = "{!white,black,bold!}" - if type(value) in colors.type_color: - color = colors.type_color[type(value)] + if type(event.value) in colors.type_color: + color = colors.type_color[type(event.value)] self.console.write(self.prefix + "ConfigValueChanged: {!input!}%s: %s%s" % - (key, color, value)) + (event.key, color, event.value)) - def on_plugin_enabled_event(self, name): - self.console.write(self.prefix + "PluginEnabled: {!info!}%s" % name) + def on_plugin_enabled_event(self, event): + self.console.write(self.prefix + "PluginEnabled: {!info!}%s" % event.name) - def on_plugin_disabled_event(self, name): - self.console.write(self.prefix + "PluginDisabled: {!info!}%s" % name) + def on_plugin_disabled_event(self, event): + self.console.write(self.prefix + "PluginDisabled: {!info!}%s" % event.name) diff --git a/deluge/ui/console/main.py b/deluge/ui/console/main.py index 4afb0fce7..7d5e1a91a 100644 --- a/deluge/ui/console/main.py +++ b/deluge/ui/console/main.py @@ -439,14 +439,14 @@ class ConsoleUI(component.Component): return ret - def on_torrent_added_event(self, torrent_id, from_state): + def on_torrent_added_event(self, event): def on_torrent_status(status): - self.torrents.append((torrent_id, status["name"])) - client.core.get_torrent_status(torrent_id, ["name"]).addCallback(on_torrent_status) + self.torrents.append((event.torrent_id, status["name"])) + client.core.get_torrent_status(event.torrent_id, ["name"]).addCallback(on_torrent_status) - def on_torrent_removed_event(self, torrent_id): + def on_torrent_removed_event(self, event): for index, (tid, name) in enumerate(self.torrents): - if torrent_id == tid: + if event.torrent_id == tid: del self.torrents[index] def on_client_disconnect(self): diff --git a/deluge/ui/coreconfig.py b/deluge/ui/coreconfig.py index c56019729..7028936c1 100644 --- a/deluge/ui/coreconfig.py +++ b/deluge/ui/coreconfig.py @@ -43,8 +43,8 @@ class CoreConfig(component.Component): log.debug("CoreConfig init..") component.Component.__init__(self, "CoreConfig") self.config = {} - def on_configvaluechanged_event(key, value): - self.config[key] = value + def on_configvaluechanged_event(event): + self.config[event.key] = event.value client.register_event_handler("ConfigValueChangedEvent", on_configvaluechanged_event) def start(self): diff --git a/deluge/ui/gtkui/files_tab.py b/deluge/ui/gtkui/files_tab.py index c43d85b1b..9b195a35d 100644 --- a/deluge/ui/gtkui/files_tab.py +++ b/deluge/ui/gtkui/files_tab.py @@ -602,34 +602,34 @@ class FilesTab(Tab): def _on_filename_editing_canceled(self, renderer): self._editing_index = None - def _on_torrentfilerenamed_event(self, torrent_id, index, name): - log.debug("index: %s name: %s", index, name) + def _on_torrentfilerenamed_event(self, event): + log.debug("index: %s name: %s", event.index, event.filename) - if torrent_id not in self.files_list: + if event.torrent_id not in self.files_list: return - old_name = self.files_list[torrent_id][index]["path"] - self.files_list[torrent_id][index]["path"] = name + old_name = self.files_list[event.torrent_id][event.index]["path"] + self.files_list[event.torrent_id][event.index]["path"] = event.filename # We need to update the filename displayed if we're currently viewing # this torrents files. - if torrent_id == self.torrent_id: + if event.torrent_id == self.torrent_id: old_name_len = len(old_name.split("/")) - name_len = len(name.split("/")) + name_len = len(event.filename.split("/")) if old_name_len != name_len: # The parent path list changes depending on which way the file # is moving in the tree if old_name_len < name_len: parent_path = [o for o in old_name.split("/")[:-1]] else: - parent_path = [o for o in name.split("/")[:-1]] + parent_path = [o for o in event.filename.split("/")[:-1]] # Find the iter to the parent folder we need to add a new folder # to. def find_parent(model, path, itr, user_data): if model[itr][0] == parent_path[0] + "/": if len(parent_path) == 1: # This is the parent iter - to_create = name.split("/")[len(old_name.split("/")[:-1]):-1] + to_create = event.filename.split("/")[len(old_name.split("/")[:-1]):-1] parent_iter = itr for tc in to_create: @@ -648,8 +648,8 @@ class FilesTab(Tab): # Find the iter for the file that needs to be moved def get_file_iter(model, path, itr, user_data): - if model[itr][5] == index: - model[itr][0] = name.split("/")[-1] + if model[itr][5] == event.index: + model[itr][0] = event.filename.split("/")[-1] t = self.treestore.append( parent_iter, self.treestore.get(itr, @@ -668,7 +668,7 @@ class FilesTab(Tab): if parent_path: self.treestore.foreach(find_parent, None) else: - new_folders = name.split("/")[:-1] + new_folders = event.filename.split("/")[:-1] parent_iter = None for f in new_folders: parent_iter = self.treestore.append(parent_iter, @@ -682,8 +682,8 @@ class FilesTab(Tab): else: # This is just changing a filename without any folder changes def set_file_name(model, path, itr, user_data): - if model[itr][5] == index: - model[itr][0] = os.path.split(name)[-1] + if model[itr][5] == event.index: + model[itr][0] = os.path.split(event.filename)[-1] return True self.treestore.foreach(set_file_name, None) @@ -729,40 +729,40 @@ class FilesTab(Tab): self.treestore.remove(itr) itr = parent - def _on_torrentfolderrenamed_event(self, torrent_id, old_folder, new_folder): + def _on_torrentfolderrenamed_event(self, event): log.debug("on_torrent_folder_renamed_signal") - log.debug("old_folder: %s new_folder: %s", old_folder, new_folder) + log.debug("old_folder: %s new_folder: %s", event.old, event.new) - if torrent_id not in self.files_list: + if event.torrent_id not in self.files_list: return - if old_folder[-1] != "/": - old_folder += "/" - if new_folder[-1] != "/": - new_folder += "/" + if event.old[-1] != "/": + event.old += "/" + if event.new[-1] != "/": + event.new += "/" - for fd in self.files_list[torrent_id]: - if fd["path"].startswith(old_folder): - fd["path"] = fd["path"].replace(old_folder, new_folder, 1) + for fd in self.files_list[event.torrent_id]: + if fd["path"].startswith(event.old): + fd["path"] = fd["path"].replace(event.old, event.new, 1) - if torrent_id == self.torrent_id: + if event.torrent_id == self.torrent_id: - old_split = old_folder.split("/") + old_split = event.old.split("/") try: old_split.remove("") except: pass - new_split = new_folder.split("/") + new_split = event.new.split("/") try: new_split.remove("") except: pass - old_folder_iter = self.get_iter_at_path(old_folder) + old_folder_iter = self.get_iter_at_path(event.old) old_folder_iter_parent = self.treestore.iter_parent(old_folder_iter) - new_folder_iter = self.get_iter_at_path(new_folder) + new_folder_iter = self.get_iter_at_path(event.new) if len(new_split) == len(old_split): # These are at the same tree depth, so it's a simple rename self.treestore[old_folder_iter][0] = new_split[-1] + "/" @@ -782,9 +782,9 @@ class FilesTab(Tab): # and if so, we delete it self.remove_childless_folders(old_folder_iter_parent) - def _on_torrentremoved_event(self, torrent_id): - if torrent_id in self.files_list: - del self.files_list[torrent_id] + def _on_torrentremoved_event(self, event): + if event.torrent_id in self.files_list: + del self.files_list[event.torrent_id] def _on_drag_data_get_data(self, treeview, context, selection, target_id, etime): paths = self.listview.get_selection().get_selected_rows()[1] diff --git a/deluge/ui/gtkui/mainwindow.py b/deluge/ui/gtkui/mainwindow.py index 344359f5b..0190976e7 100644 --- a/deluge/ui/gtkui/mainwindow.py +++ b/deluge/ui/gtkui/mainwindow.py @@ -245,11 +245,11 @@ class MainWindow(component.Component): else: self.window.set_title("Deluge") - def on_newversionavailable_event(self, new_version): + def on_newversionavailable_event(self, event): if self.config["show_new_releases"]: from deluge.ui.gtkui.new_release_dialog import NewReleaseDialog - reactor.callLater(5.0, NewReleaseDialog().show, new_version) + reactor.callLater(5.0, NewReleaseDialog().show, event.new_release) - def on_torrentfinished_event(self, torrent_id): + def on_torrentfinished_event(self, event): from deluge.ui.gtkui.notification import Notification - Notification().notify(torrent_id) + Notification().notify(event.torrent_id) diff --git a/deluge/ui/gtkui/menubar.py b/deluge/ui/gtkui/menubar.py index 1a9026965..8a4cb8c0a 100644 --- a/deluge/ui/gtkui/menubar.py +++ b/deluge/ui/gtkui/menubar.py @@ -228,11 +228,11 @@ class MenuBar(component.Component): return sep ### Callbacks ### - def on_torrentstatechanged_event(self, torrent_id, state): - if state == "Paused": + def on_torrentstatechanged_event(self, event): + if event.state == "Paused": self.update_menu() - def on_torrentresumed_event(self, torrent_id): + def on_torrentresumed_event(self, event): self.update_menu() def on_sessionpaused_event(self): diff --git a/deluge/ui/gtkui/pluginmanager.py b/deluge/ui/gtkui/pluginmanager.py index 8d0126461..1ab6dc07b 100644 --- a/deluge/ui/gtkui/pluginmanager.py +++ b/deluge/ui/gtkui/pluginmanager.py @@ -89,11 +89,11 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase, for plugin in enabled_plugins: self.enable_plugin(plugin) - def _on_plugin_enabled_event(self, name): - self.enable_plugin(name) + def _on_plugin_enabled_event(self, event): + self.enable_plugin(event.name) - def _on_plugin_disabled_event(self, name): - self.disable_plugin(name) + def _on_plugin_disabled_event(self, event): + self.disable_plugin(event.name) ## Hook functions def run_on_show_prefs(self): diff --git a/deluge/ui/gtkui/statusbar.py b/deluge/ui/gtkui/statusbar.py index a95e78b61..ff350aeab 100644 --- a/deluge/ui/gtkui/statusbar.py +++ b/deluge/ui/gtkui/statusbar.py @@ -286,14 +286,14 @@ class StatusBar(component.Component): client.core.get_session_status(keys).addCallback(self._on_get_session_status) client.core.get_free_space().addCallback(self._on_get_free_space) - def on_configvaluechanged_event(self, key, value): + def on_configvaluechanged_event(self, event): """ This is called when we receive a ConfigValueChangedEvent from the core. """ - if key in self.config_value_changed_dict.keys(): - self.config_value_changed_dict[key](value) + if event.key in self.config_value_changed_dict.keys(): + self.config_value_changed_dict[event.key](event.value) def _on_max_connections_global(self, max_connections): self.max_connections = max_connections diff --git a/deluge/ui/gtkui/systemtray.py b/deluge/ui/gtkui/systemtray.py index 807852399..a9eaffbeb 100644 --- a/deluge/ui/gtkui/systemtray.py +++ b/deluge/ui/gtkui/systemtray.py @@ -173,12 +173,12 @@ class SystemTray(component.Component): "payload_upload_rate", "payload_download_rate"]).addCallback(self._on_get_session_status) - def config_value_changed(self, key, value): + def config_value_changed(self, event): """This is called when we received a config_value_changed signal from the core.""" - if key in self.config_value_changed_dict.keys(): - self.config_value_changed_dict[key](value) + if event.key in self.config_value_changed_dict.keys(): + self.config_value_changed_dict[event.key](event.value) def _on_max_download_speed(self, max_download_speed): if self.max_download_speed != max_download_speed: diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py index 637e5a510..f0573d98a 100644 --- a/deluge/ui/gtkui/torrentview.py +++ b/deluge/ui/gtkui/torrentview.py @@ -512,31 +512,31 @@ class TorrentView(listview.ListView, component.Component): def on_drag_drop(self, widget, drag_context, x, y, timestamp): widget.stop_emission("drag-drop") - def on_torrentadded_event(self, torrent_id, from_state): - self.add_row(torrent_id) - self.mark_dirty(torrent_id) + def on_torrentadded_event(self, event): + self.add_row(event.torrent_id) + self.mark_dirty(event.torrent_id) - def on_torrentremoved_event(self, torrent_id): - self.remove_row(torrent_id) + def on_torrentremoved_event(self, event): + self.remove_row(event.torrent_id) - def on_torrentstatechanged_event(self, torrent_id, state): + def on_torrentstatechanged_event(self, event): # Update the torrents state for row in self.liststore: - if not torrent_id == row[self.columns["torrent_id"].column_indices[0]]: + if not event.torrent_id == row[self.columns["torrent_id"].column_indices[0]]: continue - row[self.get_column_index(_("Progress"))[1]] = state + row[self.get_column_index(_("Progress"))[1]] = event.state - self.mark_dirty(torrent_id) + self.mark_dirty(event.torrent_id) - def on_sessionpaused_event(self): + def on_sessionpaused_event(self, event): self.mark_dirty() self.update() - def on_sessionresumed_event(self): + def on_sessionresumed_event(self, event): self.mark_dirty() self.update() - def on_torrentqueuechanged_event(self): + def on_torrentqueuechanged_event(self, event): self.mark_dirty() self.update() diff --git a/deluge/ui/sessionproxy.py b/deluge/ui/sessionproxy.py index 37f804566..9519edfd1 100644 --- a/deluge/ui/sessionproxy.py +++ b/deluge/ui/sessionproxy.py @@ -234,21 +234,21 @@ class SessionProxy(component.Component): d = client.core.get_torrents_status(filter_dict, keys, True) return d.addCallback(on_status, None, keys) - def on_torrent_state_changed(self, torrent_id, state): - if torrent_id in self.torrents: - self.torrents[torrent_id][1]["state"] = state - self.cache_times[torrent_id]["state"] = time.time() + def on_torrent_state_changed(self, event): + if event.torrent_id in self.torrents: + self.torrents[event.torrent_id][1]["state"] = event.state + self.cache_times[event.torrent_id]["state"] = time.time() - def on_torrent_added(self, torrent_id, from_state): - self.torrents[torrent_id] = [time.time() - self.cache_time - 1, {}] - self.cache_times[torrent_id] = {} + def on_torrent_added(self, event): + self.torrents[event.torrent_id] = [time.time() - self.cache_time - 1, {}] + self.cache_times[event.torrent_id] = {} def on_status(status): - self.torrents[torrent_id][1].update(status) + self.torrents[event.torrent_id][1].update(status) t = time.time() for key in status: - self.cache_times[torrent_id][key] = t - client.core.get_torrent_status(torrent_id, []).addCallback(on_status) + self.cache_times[event.torrent_id][key] = t + client.core.get_torrent_status(event.torrent_id, []).addCallback(on_status) - def on_torrent_removed(self, torrent_id): - del self.torrents[torrent_id] - del self.cache_times[torrent_id] + def on_torrent_removed(self, event): + del self.torrents[event.torrent_id] + del self.cache_times[event.torrent_id] diff --git a/deluge/ui/web/pluginmanager.py b/deluge/ui/web/pluginmanager.py index d247e0729..657be8617 100644 --- a/deluge/ui/web/pluginmanager.py +++ b/deluge/ui/web/pluginmanager.py @@ -58,26 +58,26 @@ def gather_info(plugin): "debug_scripts": debug_scripts, "script_directories": directories } - + class PluginManager(PluginManagerBase, component.Component): def __init__(self): component.Component.__init__(self, "Web.PluginManager") self.config = ConfigManager("web.conf") PluginManagerBase.__init__(self, "web.conf", "deluge.plugin.web") - + client.register_event_handler("PluginEnabledEvent", self._on_plugin_enabled_event) client.register_event_handler("PluginDisabledEvent", self._on_plugin_disabled_event) - + def _on_get_enabled_plugins(self, plugins): for plugin in plugins: self.enable_plugin(plugin) - - def _on_plugin_enabled_event(self, name): - self.enable_plugin(name) - def _on_plugin_disabled_event(self, name): - self.disable_plugin(name) - + def _on_plugin_enabled_event(self, event): + self.enable_plugin(event.name) + + def _on_plugin_disabled_event(self, event): + self.disable_plugin(event.name) + def disable_plugin(self, name): # Get the plugin instance try: @@ -85,31 +85,31 @@ class PluginManager(PluginManagerBase, component.Component): except KeyError: log.info("Plugin has no web ui") return - + info = gather_info(plugin) scripts = component.get("Scripts") for script in info["scripts"]: scripts.remove_script("%s/%s" % (name.lower(), os.path.basename(script).lower())) - + for script in info["debug_scripts"]: scripts.remove_script("%s/%s" % (name.lower(), os.path.basename(script).lower()), "debug") scripts.remove_script("%s/%s" % (name.lower(), os.path.basename(script).lower()), "dev") - + super(PluginManager, self).disable_plugin(name) - + def enable_plugin(self, name): super(PluginManager, self).enable_plugin(name) - + # Get the plugin instance try: plugin = component.get("WebPlugin." + name) except KeyError: log.info("Plugin has no web ui") return - + info = gather_info(plugin) - + scripts = component.get("Scripts") for script in info["scripts"]: log.debug("adding script %s for %s", name, os.path.basename(script)) @@ -127,16 +127,16 @@ class PluginManager(PluginManagerBase, component.Component): # Update the enabled plugins from the core d = client.core.get_enabled_plugins() d.addCallback(self._on_get_enabled_plugins) - + def stop(self): """ Stop the plugin manager """ self.disable_plugins() - + def update(self): pass - + def get_plugin_resources(self, name): # Get the plugin instance try: From 078ed6ba71d431b5321ce6de360e17c6c9757451 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 11 Dec 2010 05:42:45 +0000 Subject: [PATCH 6/7] Fixed "PluginEnabledEvent" and "PluginDisabledEvent" the argument cannot be called name since that should contain the event name. Ported plugins on deluge's git to this new event dispatching style. --- deluge/event.py | 20 +++--- deluge/plugins/autoadd/autoadd/core.py | 24 ++++--- deluge/plugins/autoadd/autoadd/gtkui.py | 66 +++++++++---------- deluge/plugins/execute/execute/core.py | 24 ++++--- deluge/plugins/execute/execute/gtkui.py | 12 ++-- deluge/plugins/extractor/extractor/core.py | 20 +++--- deluge/plugins/freespace/freespace/core.py | 16 +++-- deluge/plugins/freespace/freespace/gtkui.py | 14 ++-- deluge/plugins/label/label/core.py | 12 ++-- .../notifications/notifications/core.py | 4 +- deluge/plugins/scheduler/scheduler/core.py | 7 +- deluge/plugins/scheduler/scheduler/gtkui.py | 4 +- deluge/ui/console/eventlog.py | 4 +- deluge/ui/gtkui/pluginmanager.py | 4 +- deluge/ui/web/pluginmanager.py | 4 +- 15 files changed, 120 insertions(+), 115 deletions(-) diff --git a/deluge/event.py b/deluge/event.py index c24663fac..a4fc8b4a3 100644 --- a/deluge/event.py +++ b/deluge/event.py @@ -273,24 +273,24 @@ class PluginEnabledEvent(DelugeEvent): """ Emitted when a plugin is enabled in the Core. """ - __slots__ = ('name',) + __slots__ = ('plugin_name',) - def __init__(self, name): + def __init__(self, plugin_name): """ - :param name: the plugin name - :type name: string + :param plugin_name: the plugin name + :type plugin_name: string """ - self.name = name + self.plugin_name = plugin_name class PluginDisabledEvent(DelugeEvent): """ Emitted when a plugin is disabled in the Core. """ - __slots__ = ('name',) + __slots__ = ('plugin_name',) - def __init__(self, name): + def __init__(self, plugin_name): """ - :param name: the plugin name - :type name: string + :param plugin_name: the plugin name + :type plugin_name: string """ - self.name = name + self.plugin_name = plugin_name diff --git a/deluge/plugins/autoadd/autoadd/core.py b/deluge/plugins/autoadd/autoadd/core.py index aa58d8f53..ad2da5863 100644 --- a/deluge/plugins/autoadd/autoadd/core.py +++ b/deluge/plugins/autoadd/autoadd/core.py @@ -57,7 +57,7 @@ OPTIONS_AVAILABLE = { #option: builtin "enabled":False, "path":False, "append_extension":False, - "abspath":False, + "abspath":False, "download_location":True, "max_download_speed":True, "max_upload_speed":True, @@ -79,8 +79,6 @@ MAX_NUM_ATTEMPTS = 10 class AutoaddOptionsChangedEvent(DelugeEvent): """Emitted when the options for the plugin are changed.""" - def __init__(self): - pass def CheckInput(cond, message): if not cond: @@ -88,7 +86,7 @@ def CheckInput(cond, message): class Core(CorePluginBase): def enable(self): - + #reduce typing, assigning some values to self... self.config = deluge.configmanager.ConfigManager("autoadd.conf", DEFAULT_PREFS) self.watchdirs = self.config["watchdirs"] @@ -127,7 +125,7 @@ class Core(CorePluginBase): def update(self): pass - + @export() def set_options(self, watchdir_id, options): """Update the options for a watch folder.""" @@ -147,14 +145,14 @@ class Core(CorePluginBase): #disable the watch loop if it was active if watchdir_id in self.update_timers: self.disable_watchdir(watchdir_id) - + self.watchdirs[watchdir_id].update(options) #re-enable watch loop if appropriate if self.watchdirs[watchdir_id]['enabled']: self.enable_watchdir(watchdir_id) self.config.save() component.get("EventManager").emit(AutoaddOptionsChangedEvent()) - + def load_torrent(self, filename): try: log.debug("Attempting to open %s for add.", filename) @@ -171,7 +169,7 @@ class Core(CorePluginBase): info = lt.torrent_info(lt.bdecode(filedump)) return filedump - + def update_watchdir(self, watchdir_id): """Check the watch folder for new torrents to add.""" watchdir_id = str(watchdir_id) @@ -185,7 +183,7 @@ class Core(CorePluginBase): log.warning("Invalid AutoAdd folder: %s", watchdir["abspath"]) self.disable_watchdir(watchdir_id) return - + # Generate options dict for watchdir opts = {} if 'stop_at_ratio_toggle' in watchdir: @@ -246,7 +244,7 @@ class Core(CorePluginBase): """Disables any watch folders with unhandled exceptions.""" self.disable_watchdir(watchdir_id) log.error("Disabling '%s', error during update: %s" % (self.watchdirs[watchdir_id]["path"], failure)) - + @export def enable_watchdir(self, watchdir_id): watchdir_id = str(watchdir_id) @@ -259,7 +257,7 @@ class Core(CorePluginBase): self.watchdirs[watchdir_id]['enabled'] = True self.config.save() component.get("EventManager").emit(AutoaddOptionsChangedEvent()) - + @export def disable_watchdir(self, watchdir_id): watchdir_id = str(watchdir_id) @@ -287,7 +285,7 @@ class Core(CorePluginBase): def get_config(self): """Returns the config dictionary.""" return self.config.config - + @export() def get_watchdirs(self): return self.watchdirs.keys() @@ -319,7 +317,7 @@ class Core(CorePluginBase): self.config.save() component.get("EventManager").emit(AutoaddOptionsChangedEvent()) return watchdir_id - + @export def remove(self, watchdir_id): """Remove a watch folder.""" diff --git a/deluge/plugins/autoadd/autoadd/gtkui.py b/deluge/plugins/autoadd/autoadd/gtkui.py index 3fe74ca29..0bda2fac2 100644 --- a/deluge/plugins/autoadd/autoadd/gtkui.py +++ b/deluge/plugins/autoadd/autoadd/gtkui.py @@ -113,22 +113,22 @@ class OptionsDialog(): self.glade.get_widget(field+"_entry").show() self.glade.get_widget(field+"_chooser").hide() self.set_sensitive() - + def on_get_enabled_plugins(result): - if 'Label' in result: + if 'Label' in result: self.glade.get_widget('label_frame').show() else: self.glade.get_widget('label_frame').hide() self.glade.get_widget('label_toggle').set_active(False) - + client.core.get_enabled_plugins().addCallback(on_get_enabled_plugins) - + def set_sensitive(self): maintoggles = ['download_location', 'append_extension', 'move_completed', 'label', \ 'max_download_speed', 'max_upload_speed', 'max_connections', \ 'max_upload_slots', 'add_paused', 'auto_managed', 'stop_at_ratio', 'queue_to_top'] [self.on_toggle_toggled(self.glade.get_widget(x+'_toggle')) for x in maintoggles] - + def on_toggle_toggled(self, tb): toggle = str(tb.name).replace("_toggle", "") isactive = tb.get_active() @@ -166,29 +166,29 @@ class OptionsDialog(): self.glade.get_widget('stop_at_ratio').set_active(isactive) self.glade.get_widget('stop_ratio').set_sensitive(isactive) self.glade.get_widget('remove_at_ratio').set_sensitive(isactive) - + def on_apply(self, Event=None): client.autoadd.set_options(str(self.watchdir_id), self.generate_opts()).addCallbacks(self.on_added, self.on_error_show) - + def on_error_show(self, result): self.glade.get_widget('error_label').set_text(result.value.exception_msg) self.err_dialog = self.glade.get_widget('error_dialog') self.err_dialog.set_transient_for(self.dialog) result.cleanFailure() self.err_dialog.show() - + def on_added(self, result): self.dialog.destroy() - + def on_error_ok(self, Event=None): self.err_dialog.hide() - + def on_add(self, Event=None): client.autoadd.add(self.generate_opts()).addCallbacks(self.on_added, self.on_error_show) - + def on_cancel(self, Event=None): self.dialog.destroy() - + def generate_opts(self): # generate options dict based on gtk objects options = {} @@ -217,11 +217,11 @@ class OptionsDialog(): options[id] = self.glade.get_widget(id).get_active() options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active() return options - + class GtkUI(GtkPluginBase): def enable(self): - + self.glade = gtk.glade.XML(get_resource("config.glade")) self.glade.signal_autoconnect({ "on_add_button_clicked": self.on_add_button_clicked, @@ -229,18 +229,18 @@ class GtkUI(GtkPluginBase): "on_remove_button_clicked": self.on_remove_button_clicked }) self.opts_dialog = OptionsDialog() - + component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs) component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs) client.register_event_handler("AutoaddOptionsChangedEvent", self.on_options_changed_event) - + self.watchdirs = {} - + vbox = self.glade.get_widget("watchdirs_vbox") sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - + vbox.pack_start(sw, True, True, 0) self.store = self.create_model() @@ -256,28 +256,28 @@ class GtkUI(GtkPluginBase): component.get("Preferences").add_page("AutoAdd", self.glade.get_widget("prefs_box")) self.on_show_prefs() - + def disable(self): component.get("Preferences").remove_page("AutoAdd") component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs) component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs) - + def create_model(self): - + store = gtk.ListStore(str, bool, str) for watchdir_id, watchdir in self.watchdirs.iteritems(): store.append([watchdir_id, watchdir['enabled'], watchdir['path']]) return store - + def create_columns(self, treeView): rendererToggle = gtk.CellRendererToggle() column = gtk.TreeViewColumn("On", rendererToggle, activatable=True, active=1) - column.set_sort_column_id(1) + column.set_sort_column_id(1) treeView.append_column(column) tt = gtk.Tooltip() tt.set_text('Double-click to toggle') treeView.set_tooltip_cell(tt, None, None, rendererToggle) - + rendererText = gtk.CellRendererText() column = gtk.TreeViewColumn("Path", rendererText, text=2) column.set_sort_column_id(2) @@ -289,20 +289,20 @@ class GtkUI(GtkPluginBase): def load_watchdir_list(self): pass - + def add_watchdir_entry(self): pass - + def on_add_button_clicked(self, Event=None): #display options_window self.opts_dialog.show() - + def on_remove_button_clicked(self, Event=None): tree, tree_id = self.treeView.get_selection().get_selected() watchdir_id = str(self.store.get_value(tree_id, 0)) if watchdir_id: client.autoadd.remove(watchdir_id) - + def on_edit_button_clicked(self, Event=None, a=None, col=None): tree, tree_id = self.treeView.get_selection().get_selected() watchdir_id = str(self.store.get_value(tree_id, 0)) @@ -314,7 +314,7 @@ class GtkUI(GtkPluginBase): client.autoadd.enable_watchdir(watchdir_id) else: self.opts_dialog.show(self.watchdirs[watchdir_id], watchdir_id) - + def on_listitem_activated(self, treeview): tree, tree_id = self.treeView.get_selection().get_selected() if tree_id: @@ -323,7 +323,7 @@ class GtkUI(GtkPluginBase): else: self.glade.get_widget('edit_button').set_sensitive(False) self.glade.get_widget('remove_button').set_sensitive(False) - + def on_apply_prefs(self): log.debug("applying prefs for AutoAdd") for watchdir_id, watchdir in self.watchdirs.iteritems(): @@ -331,8 +331,8 @@ class GtkUI(GtkPluginBase): def on_show_prefs(self): client.autoadd.get_config().addCallback(self.cb_get_config) - - def on_options_changed_event(self): + + def on_options_changed_event(self, event): client.autoadd.get_config().addCallback(self.cb_get_config) def cb_get_config(self, config): @@ -344,4 +344,4 @@ class GtkUI(GtkPluginBase): # Disable the remove and edit buttons, because nothing in the store is selected self.glade.get_widget('remove_button').set_sensitive(False) self.glade.get_widget('edit_button').set_sensitive(False) - + diff --git a/deluge/plugins/execute/execute/core.py b/deluge/plugins/execute/execute/core.py index 4c5e66005..123cc63c9 100644 --- a/deluge/plugins/execute/execute/core.py +++ b/deluge/plugins/execute/execute/core.py @@ -62,15 +62,19 @@ class ExecuteCommandAddedEvent(DelugeEvent): """ Emitted when a new command is added. """ + __slots__ = ('command_id', 'event', 'command') def __init__(self, command_id, event, command): - self._args = [command_id, event, command] + self.command_id = command_id + self.event = event + self.command = command class ExecuteCommandRemovedEvent(DelugeEvent): """ Emitted when a command is removed. """ + __slots__ = ('command_id',) def __init__(self, command_id): - self._args = [command_id] + self.command_id = command_id class Core(CorePluginBase): def enable(self): @@ -80,17 +84,17 @@ class Core(CorePluginBase): # Go through the commands list and register event handlers for command in self.config["commands"]: - event = command[EXECUTE_EVENT] - if event in self.registered_events: + event_name = command[EXECUTE_EVENT] + if event_name in self.registered_events: continue - def create_event_handler(event): - def event_handler(torrent_id): - self.execute_commands(torrent_id, event) + def create_event_handler(event_name): + def event_handler(event): + self.execute_commands(event.torrent_id, event_name) return event_handler - event_handler = create_event_handler(event) - event_manager.register_event_handler(EVENT_MAP[event], event_handler) - self.registered_events[event] = event_handler + event_handler = create_event_handler(event_name) + event_manager.register_event_handler(EVENT_MAP[event_name], event_handler) + self.registered_events[event_name] = event_handler log.debug("Execute core plugin enabled!") diff --git a/deluge/plugins/execute/execute/gtkui.py b/deluge/plugins/execute/execute/gtkui.py index 7a341ea2b..82851814f 100644 --- a/deluge/plugins/execute/execute/gtkui.py +++ b/deluge/plugins/execute/execute/gtkui.py @@ -159,13 +159,13 @@ class ExecutePreferences(object): command = widget.get_text() client.execute.save_command(command_id, event, command) - def on_command_added_event(self, command_id, event, command): - log.debug("Adding command %s: %s", event, command) - self.add_command(command_id, event, command) + def on_command_added_event(self, event): + log.debug("Adding command %s: %s", event.event, event.command) + self.add_command(event.command_id, event.event, event.command) - def on_command_removed_event(self, command_id): - log.debug("Removing command %s", command_id) - self.remove_command(command_id) + def on_command_removed_event(self, event): + log.debug("Removing command %s", event.command_id) + self.remove_command(event.command_id) class GtkUI(GtkPluginBase): diff --git a/deluge/plugins/extractor/extractor/core.py b/deluge/plugins/extractor/extractor/core.py index f7c888e17..8221b5bc4 100644 --- a/deluge/plugins/extractor/extractor/core.py +++ b/deluge/plugins/extractor/extractor/core.py @@ -75,14 +75,14 @@ class Core(CorePluginBase): def update(self): pass - def _on_torrent_finished(self, torrent_id): + def _on_torrent_finished(self, event): """ This is called when a torrent finishes. We need to check to see if there are any files to extract. """ # Get the save path - save_path = component.get("TorrentManager")[torrent_id].get_status(["save_path"])["save_path"] - files = component.get("TorrentManager")[torrent_id].get_files() + save_path = component.get("TorrentManager")[event.torrent_id].get_status(["save_path"])["save_path"] + files = component.get("TorrentManager")[event.torrent_id].get_files() for f in files: ext = os.path.splitext(f["path"]) if ext[1] in (".gz", ".bz2", ".lzma"): @@ -98,22 +98,22 @@ class Core(CorePluginBase): # Now that we have the cmd, lets run it to extract the files fp = os.path.join(save_path, f["path"]) - + # Get the destination path dest = self.config["extract_path"] if self.config["use_name_folder"]: - name = component.get("TorrentManager")[torrent_id].get_status(["name"])["name"] + name = component.get("TorrentManager")[event.torrent_id].get_status(["name"])["name"] dest = os.path.join(dest, name) - # Create the destination folder if it doesn't exist + # Create the destination folder if it doesn't exist if not os.path.exists(dest): try: os.makedirs(dest) except Exception, e: log.error("Error creating destination folder: %s", e) return - - log.debug("Extracting to %s", dest) + + log.debug("Extracting to %s", dest) def on_extract_success(result, torrent_id): # XXX: Emit an event log.debug("Extract was successful for %s", torrent_id) @@ -124,8 +124,8 @@ class Core(CorePluginBase): # Run the command and add some callbacks d = getProcessValue(cmd[0], cmd[1].split() + [str(fp)], {}, str(dest)) - d.addCallback(on_extract_success, torrent_id) - d.addErrback(on_extract_failed, torrent_id) + d.addCallback(on_extract_success, event.torrent_id) + d.addErrback(on_extract_failed, event.torrent_id) @export def set_config(self, config): diff --git a/deluge/plugins/freespace/freespace/core.py b/deluge/plugins/freespace/freespace/core.py index 42aed12a6..6029cfe7a 100644 --- a/deluge/plugins/freespace/freespace/core.py +++ b/deluge/plugins/freespace/freespace/core.py @@ -53,12 +53,14 @@ class LowDiskSpaceEvent(DelugeEvent): """Triggered when the available space for a specific path is getting too low. """ + __slots__ = ('percents_dict',) + def __init__(self, percents_dict): """ :param percents: dictionary of path keys with their respecive occupation percentages. """ - self._args = [percents_dict] + self.percents_dict = percents_dict DEFAULT_PREFS = { "enabled": False, @@ -170,25 +172,25 @@ class Core(CorePluginBase): free_percent = free_blocks * 100 / total_blocks return free_percent - def __custom_email_notification(self, ocupied_percents): + def __custom_email_notification(self, event): subject = _("Low Disk Space Warning") message = _("You're running low on disk space:\n") - for path, ocupied_percent in ocupied_percents.iteritems(): + for path, ocupied_percent in event.percents_dict.iteritems(): message += _(' %s%% ocupation in %s\n') % (ocupied_percent, path) # "\"%s\"%% space occupation on %s") % (ocupied_percent, path) return subject, message - def __on_plugin_enabled(self, plugin_name): - if plugin_name == 'Notifications': + def __on_plugin_enabled(self, event): + if event.plugin_name == 'Notifications': component.get("CorePlugin.Notifications"). \ register_custom_email_notification( "LowDiskSpaceEvent", self.__custom_email_notification ) - def __on_plugin_disabled(self, plugin_name): - if plugin_name == 'Notifications': + def __on_plugin_disabled(self, event): + if event.plugin_name == 'Notifications': component.get("CorePlugin.Notifications"). \ deregister_custom_email_notification("LowDiskSpaceEvent") diff --git a/deluge/plugins/freespace/freespace/gtkui.py b/deluge/plugins/freespace/freespace/gtkui.py index 57a8117e4..fb0b5d5d8 100644 --- a/deluge/plugins/freespace/freespace/gtkui.py +++ b/deluge/plugins/freespace/freespace/gtkui.py @@ -132,22 +132,22 @@ class GtkUI(GtkPluginBase): self.glade.get_widget('enabled').set_active(config['enabled']) self.glade.get_widget('percent').set_value(config['percent']) - def __custom_popup_notification(self, ocupied_percents): + def __custom_popup_notification(self, event): title = _("Low Free Space") message = '' - for path, percent in ocupied_percents.iteritems(): + for path, percent in event.percents_dict.iteritems(): message += '%s%% %s\n' % (percent, path) message += '\n' return title, message - def __custom_blink_notification(self, ocupied_percents): + def __custom_blink_notification(self, event): return True # Yes, do blink - def __custom_sound_notification(self, ocupied_percents): + def __custom_sound_notification(self, event): return '' # Use default sound - def __on_plugin_enabled(self, plugin_name): - if plugin_name == 'Notifications': + def __on_plugin_enabled(self, event): + if event.plugin_name == 'Notifications': notifications = component.get("GtkPlugin.Notifications") notifications.register_custom_popup_notification( "LowDiskSpaceEvent", self.__custom_popup_notification @@ -159,7 +159,7 @@ class GtkUI(GtkPluginBase): "LowDiskSpaceEvent", self.__custom_sound_notification ) - def __on_plugin_disabled(self, plugin_name): + def __on_plugin_disabled(self, event): pass # if plugin_name == 'Notifications': # notifications = component.get("GtkPlugin.Notifications") diff --git a/deluge/plugins/label/label/core.py b/deluge/plugins/label/label/core.py index 63f8e7f6e..3380f2744 100644 --- a/deluge/plugins/label/label/core.py +++ b/deluge/plugins/label/label/core.py @@ -131,20 +131,20 @@ class Core(CorePluginBase): return dict( [(label, 0) for label in self.labels.keys()]) ## Plugin hooks ## - def post_torrent_add(self, torrent_id, from_state): + def post_torrent_add(self, event): log.debug("post_torrent_add") - torrent = self.torrents[torrent_id] + torrent = self.torrents[event.torrent_id] for label_id, options in self.labels.iteritems(): if options["auto_add"]: if self._has_auto_match(torrent, options): - self.set_torrent(torrent_id, label_id) + self.set_torrent(event.torrent_id, label_id) return - def post_torrent_remove(self, torrent_id): + def post_torrent_remove(self, event): log.debug("post_torrent_remove") - if torrent_id in self.torrent_labels: - del self.torrent_labels[torrent_id] + if event.torrent_id in self.torrent_labels: + del self.torrent_labels[event.torrent_id] ## Utils ## def clean_config(self): diff --git a/deluge/plugins/notifications/notifications/core.py b/deluge/plugins/notifications/notifications/core.py index 9586f7f5f..c28c39152 100644 --- a/deluge/plugins/notifications/notifications/core.py +++ b/deluge/plugins/notifications/notifications/core.py @@ -186,9 +186,9 @@ Subject: %(subject)s return _("Notification email sent.") - def _on_torrent_finished_event(self, torrent_id): + def _on_torrent_finished_event(self, event): log.debug("Handler for TorrentFinishedEvent called for CORE") - torrent = component.get("TorrentManager")[torrent_id] + torrent = component.get("TorrentManager")[event.torrent_id] torrent_status = torrent.get_status({}) # Email subject = _("Finished Torrent \"%(name)s\"") % torrent_status diff --git a/deluge/plugins/scheduler/scheduler/core.py b/deluge/plugins/scheduler/scheduler/core.py index e7fd86aae..c3c5008ea 100644 --- a/deluge/plugins/scheduler/scheduler/core.py +++ b/deluge/plugins/scheduler/scheduler/core.py @@ -74,11 +74,12 @@ class SchedulerEvent(DelugeEvent): """ Emitted when a schedule state changes. """ + __slots__ = ('colour',) def __init__(self, colour): """ :param colour: str, the current scheduler state """ - self._args = [colour] + self.colour = colour class Core(CorePluginBase): def enable(self): @@ -117,8 +118,8 @@ class Core(CorePluginBase): pass - def on_config_value_changed(self, key, value): - if key in CONTROLLED_SETTINGS: + def on_config_value_changed(self, event): + if event.key in CONTROLLED_SETTINGS: self.do_schedule(False) def __apply_set_functions(self): diff --git a/deluge/plugins/scheduler/scheduler/gtkui.py b/deluge/plugins/scheduler/scheduler/gtkui.py index e688d345b..73d156285 100644 --- a/deluge/plugins/scheduler/scheduler/gtkui.py +++ b/deluge/plugins/scheduler/scheduler/gtkui.py @@ -201,9 +201,9 @@ class GtkUI(GtkPluginBase): client.scheduler.get_config().addCallback(on_get_config) - def on_scheduler_event(self, state): + def on_scheduler_event(self, event): def on_state_deferred(s): - self.status_item.set_image_from_file(get_resource(state.lower() + ".png")) + self.status_item.set_image_from_file(get_resource(event.colour.lower() + ".png")) self.state_deferred.addCallback(on_state_deferred) diff --git a/deluge/ui/console/eventlog.py b/deluge/ui/console/eventlog.py index 2e74c1fe5..c5caddf68 100644 --- a/deluge/ui/console/eventlog.py +++ b/deluge/ui/console/eventlog.py @@ -107,7 +107,7 @@ class EventLog(component.Component): (event.key, color, event.value)) def on_plugin_enabled_event(self, event): - self.console.write(self.prefix + "PluginEnabled: {!info!}%s" % event.name) + self.console.write(self.prefix + "PluginEnabled: {!info!}%s" % event.plugin_name) def on_plugin_disabled_event(self, event): - self.console.write(self.prefix + "PluginDisabled: {!info!}%s" % event.name) + self.console.write(self.prefix + "PluginDisabled: {!info!}%s" % event.plugin_name) diff --git a/deluge/ui/gtkui/pluginmanager.py b/deluge/ui/gtkui/pluginmanager.py index 1ab6dc07b..5bbbef351 100644 --- a/deluge/ui/gtkui/pluginmanager.py +++ b/deluge/ui/gtkui/pluginmanager.py @@ -90,10 +90,10 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase, self.enable_plugin(plugin) def _on_plugin_enabled_event(self, event): - self.enable_plugin(event.name) + self.enable_plugin(event.plugin_name) def _on_plugin_disabled_event(self, event): - self.disable_plugin(event.name) + self.disable_plugin(event.plugin_name) ## Hook functions def run_on_show_prefs(self): diff --git a/deluge/ui/web/pluginmanager.py b/deluge/ui/web/pluginmanager.py index 657be8617..ec4c61c58 100644 --- a/deluge/ui/web/pluginmanager.py +++ b/deluge/ui/web/pluginmanager.py @@ -73,10 +73,10 @@ class PluginManager(PluginManagerBase, component.Component): self.enable_plugin(plugin) def _on_plugin_enabled_event(self, event): - self.enable_plugin(event.name) + self.enable_plugin(event.plugin_name) def _on_plugin_disabled_event(self, event): - self.disable_plugin(event.name) + self.disable_plugin(event.plugin_name) def disable_plugin(self, name): # Get the plugin instance From f28248780647032af66713ede92ec697042a2558 Mon Sep 17 00:00:00 2001 From: Damien Churchill Date: Sun, 12 Dec 2010 00:02:41 +0000 Subject: [PATCH 7/7] fix bug #1355 --- deluge/ui/web/js/deluge-all/Deluge.js | 2 +- deluge/ui/web/js/deluge-all/TorrentGrid.js | 9 ++++++++- deluge/ui/web/js/deluge-all/UI.js | 9 ++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/deluge/ui/web/js/deluge-all/Deluge.js b/deluge/ui/web/js/deluge-all/Deluge.js index de82dd7af..382b611dd 100644 --- a/deluge/ui/web/js/deluge-all/Deluge.js +++ b/deluge/ui/web/js/deluge-all/Deluge.js @@ -46,7 +46,7 @@ Ext.apply(Ext, { return true; }, - isObjectsEqual: function(obj1, obj2) { + areObjectsEqual: function(obj1, obj2) { var equal = true; if (!obj1 || !obj2) return false; for (var i in obj1) { diff --git a/deluge/ui/web/js/deluge-all/TorrentGrid.js b/deluge/ui/web/js/deluge-all/TorrentGrid.js index 04a020432..0455113c5 100644 --- a/deluge/ui/web/js/deluge-all/TorrentGrid.js +++ b/deluge/ui/web/js/deluge-all/TorrentGrid.js @@ -284,8 +284,15 @@ return ids; }, - update: function(torrents) { + update: function(torrents, wipe) { var store = this.getStore(); + + // Need to perform a complete reload of the torrent grid. + if (wipe) { + store.removeAll(); + this.torrents = {}; + } + var newTorrents = []; // Update and add any new torrents. diff --git a/deluge/ui/web/js/deluge-all/UI.js b/deluge/ui/web/js/deluge-all/UI.js index e8e86a593..4a1b96278 100644 --- a/deluge/ui/web/js/deluge-all/UI.js +++ b/deluge/ui/web/js/deluge-all/UI.js @@ -114,6 +114,9 @@ deluge.ui = { update: function() { var filters = deluge.sidebar.getFilterStates(); + this.oldFilters = this.filters; + this.filters = filters; + deluge.client.web.update_ui(Deluge.Keys.Grid, filters, { success: this.onUpdate, failure: this.onUpdateError, @@ -170,7 +173,11 @@ deluge.ui = { ' (Down: ' + fspeed(data['stats'].download_rate, true) + ' Up: ' + fspeed(data['stats'].upload_rate, true) + ')'; } - deluge.torrents.update(data['torrents']); + if (Ext.areObjectsEqual(this.filters, this.oldFilters)) { + deluge.torrents.update(data['torrents']); + } else { + deluge.torrents.update(data['torrents'], true); + } deluge.statusbar.update(data['stats']); deluge.sidebar.update(data['filters']); this.errorCount = 0;