From f61e86d7b3d8b35c0be4ccad58f3c276fbdfdd17 Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Thu, 26 Feb 2009 03:10:11 +0000 Subject: [PATCH] Add EventManager to the Core --- deluge/core/core.py | 14 ++++--- deluge/core/eventmanager.py | 69 +++++++++++++++++++++++++++++++ deluge/core/preferencesmanager.py | 2 +- deluge/core/torrent.py | 2 +- deluge/core/torrentmanager.py | 16 +++---- 5 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 deluge/core/eventmanager.py diff --git a/deluge/core/core.py b/deluge/core/core.py index 104194897..57d01aa4e 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -54,6 +54,7 @@ from deluge.core.filtermanager import FilterManager from deluge.core.preferencesmanager import PreferencesManager from deluge.core.autoadd import AutoAdd from deluge.core.authmanager import AuthManager +from deluge.core.eventmanager import EventManager from deluge.core.rpcserver import export STATUS_KEYS = ['active_time', 'compact', 'distributed_copies', 'download_payload_rate', 'eta', @@ -115,6 +116,7 @@ class Core(component.Component): self.session.add_extension(lt.create_smart_ban_plugin) # Create the components + self.eventmanager = EventManager() self.preferencesmanager = PreferencesManager() self.alertmanager = AlertManager(self.session) self.pluginmanager = PluginManager(self) @@ -216,7 +218,7 @@ class Core(component.Component): return 1 if VersionSplit(self.new_release) > VersionSplit(deluge.common.get_version()): - component.get("RPCServer").emit_event(NewVersionAvailableEvent(self.new_release)) + component.get("EventManager").emit(NewVersionAvailableEvent(self.new_release)) return self.new_release return False @@ -368,7 +370,7 @@ class Core(component.Component): def resume_all_torrents(self): """Resume all torrents in the session""" self.session.resume() - component.get("RPCServer").emit_event(SessionResumedEvent()) + component.get("EventManager").emit(SessionResumedEvent()) @export() def resume_torrent(self, torrent_ids): @@ -678,7 +680,7 @@ class Core(component.Component): try: # If the queue method returns True, then we should emit a signal if self.torrentmanager.queue_top(torrent_id): - component.get("RPCServer").emit_event(TorrentQueueChangedEvent()) + component.get("EventManager").emit(TorrentQueueChangedEvent()) except KeyError: log.warning("torrent_id: %s does not exist in the queue", torrent_id) @@ -692,7 +694,7 @@ class Core(component.Component): try: # If the queue method returns True, then we should emit a signal if self.torrentmanager.queue_up(torrent_id): - component.get("RPCServer").emit_event(TorrentQueueChangedEvent()) + component.get("EventManager").emit(TorrentQueueChangedEvent()) except KeyError: log.warning("torrent_id: %s does not exist in the queue", torrent_id) @@ -706,7 +708,7 @@ class Core(component.Component): try: # If the queue method returns True, then we should emit a signal if self.torrentmanager.queue_down(torrent_id): - component.get("RPCServer").emit_event(TorrentQueueChangedEvent()) + component.get("EventManager").emit(TorrentQueueChangedEvent()) except KeyError: log.warning("torrent_id: %s does not exist in the queue", torrent_id) @@ -717,7 +719,7 @@ class Core(component.Component): try: # If the queue method returns True, then we should emit a signal if self.torrentmanager.queue_bottom(torrent_id): - component.get("RPCServer").emit_event(TorrentQueueChangedEvent()) + component.get("EventManager").emit(TorrentQueueChangedEvent()) except KeyError: log.warning("torrent_id: %s does not exist in the queue", torrent_id) diff --git a/deluge/core/eventmanager.py b/deluge/core/eventmanager.py new file mode 100644 index 000000000..271b15974 --- /dev/null +++ b/deluge/core/eventmanager.py @@ -0,0 +1,69 @@ +# +# eventmanager.py +# +# Copyright (C) 2009 Andrew Resch +# +# 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 3 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. +# + +import deluge.component as component +from deluge.log import LOG as log + +class EventManager(component.Component): + def __init__(self): + component.Component.__init__(self, "EventManager") + self.handlers = {} + + def emit(self, event): + """ + Emits the event to interested clients. + + :param event: DelugeEvent + """ + # Emit the event to the interested clients + component.get("RPCServer").emit_event(event) + # Call any handlers for the event + if event.name in self.handlers: + for handler in self.handlers[event.name]: + handler(event.args) + + def register_event_handler(self, event, handler): + """ + Registers a function to be called when a `:param:event` is emitted. + + :param event: str, the event name + :param handler: function, to be called when `:param:event` is emitted + + """ + if event not in self.handlers: + self.handlers[event] = [] + + if handler not in self.handlers[event]: + self.handlers[event].append(handler) + + def deregister_event_handler(self, event, handler): + """ + Deregisters an event handler function. + + :param event: str, the event name + :param handler: function, currently registered to handle `:param:event` + + """ + if event in self.handlers and handler in self.handlers[event]: + self.handlers[event].remove(handler) diff --git a/deluge/core/preferencesmanager.py b/deluge/core/preferencesmanager.py index 3657ed780..e4027b24f 100644 --- a/deluge/core/preferencesmanager.py +++ b/deluge/core/preferencesmanager.py @@ -214,7 +214,7 @@ class PreferencesManager(component.Component): # Config set functions def _on_config_value_change(self, key, value): - component.get("RPCServer").emit_event(ConfigValueChangedEvent(key, value)) + component.get("EventManager").emit(ConfigValueChangedEvent(key, value)) def _on_set_torrentfiles_location(self, key, value): if self.config["copy_torrent_file"]: diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 4522580d6..5e9ab27d7 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -679,7 +679,7 @@ class Torrent: # show it as 'Paused'. We need to emit a torrent_paused signal because # the torrent_paused alert from libtorrent will not be generated. self.update_state() - component.get("RPCServer").emit_event(TorrentStateChangedEvent(self.torrent_id, "Paused")) + component.get("EventManager").emit(TorrentStateChangedEvent(self.torrent_id, "Paused")) else: try: self.handle.pause() diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index 8a75a7a20..58dca3b33 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -404,7 +404,7 @@ class TorrentManager(component.Component): self.save_state() # Emit the torrent_added signal - component.get("RPCServer").emit_event(TorrentAddedEvent(torrent.torrent_id)) + component.get("EventManager").emit(TorrentAddedEvent(torrent.torrent_id)) return torrent.torrent_id @@ -451,7 +451,7 @@ class TorrentManager(component.Component): self.save_state() # Emit the signal to the clients - component.get("RPCServer").emit_event(TorrentRemovedEvent(torrent_id)) + component.get("EventManager").emit(TorrentRemovedEvent(torrent_id)) return True @@ -636,7 +636,7 @@ class TorrentManager(component.Component): torrent.is_finished = True torrent.update_state() torrent.save_resume_data() - component.get("RPCServer").emit_event(TorrentFinishedEvent(torrent_id)) + component.get("EventManager").emit(TorrentFinishedEvent(torrent_id)) def on_alert_torrent_paused(self, alert): log.debug("on_alert_torrent_paused") @@ -644,7 +644,7 @@ class TorrentManager(component.Component): torrent_id = str(alert.handle.info_hash()) # Set the torrent state self.torrents[torrent_id].update_state() - component.get("RPCServer").emit_event(TorrentStateChangedEvent(torrent_id, "Paused")) + component.get("EventManager").emit(TorrentStateChangedEvent(torrent_id, "Paused")) # Write the fastresume file self.torrents[torrent_id].save_resume_data() @@ -732,13 +732,13 @@ class TorrentManager(component.Component): torrent = self.torrents[torrent_id] torrent.is_finished = torrent.handle.is_seed() torrent.update_state() - component.get("RPCServer").emit_event(TorrentResumedEvent(torrent_id)) + component.get("EventManager").emit(TorrentResumedEvent(torrent_id)) def on_alert_state_changed(self, alert): log.debug("on_alert_state_changed") torrent_id = str(alert.handle.info_hash()) self.torrents[torrent_id].update_state() - component.get("RPCServer").emit_event(TorrentStateChangedEvent(torrent_id, self.torrents[torrent_id].state)) + component.get("EventManager").emit(TorrentStateChangedEvent(torrent_id, self.torrents[torrent_id].state)) def on_alert_save_resume_data(self, alert): log.debug("on_alert_save_resume_data") @@ -764,7 +764,7 @@ class TorrentManager(component.Component): folder_rename = True if len(wait_on_folder[2]) == 1: # This is the last alert we were waiting for, time to send signal - component.get("RPCServer").emit_event(TorrentFolderRenamedEvent(torrent_id, wait_on_folder[0], wait_on_folder[1])) + component.get("EventManager").emit(TorrentFolderRenamedEvent(torrent_id, wait_on_folder[0], wait_on_folder[1])) del torrent.waiting_on_folder_rename[i] break # This isn't the last file to be renamed in this folder, so just @@ -773,7 +773,7 @@ class TorrentManager(component.Component): if not folder_rename: # This is just a regular file rename so send the signal - component.get("RPCServer").emit_event(TorrentFileRenamedEvent(torrent_id, alert.index, alert.name)) + component.get("EventManager").emit(TorrentFileRenamedEvent(torrent_id, alert.index, alert.name)) def on_alert_metadata_received(self, alert): log.debug("on_alert_metadata_received")