From 7b4498091206ad2ad89fa4f1d09b214e96f454f4 Mon Sep 17 00:00:00 2001 From: Calum Lind Date: Sat, 12 Jul 2014 21:54:45 +0100 Subject: [PATCH] [#1126] [#2322] Emit FinishedEvent after moving storage complete Also changed the Execute and Extractor plugins to process the updated FinishedEvent functionality. --- deluge/core/torrent.py | 4 +-- deluge/core/torrentmanager.py | 26 +++++++++++++------ .../Execute/deluge/plugins/execute/core.py | 25 +++++++----------- .../deluge/plugins/extractor/core.py | 9 ++----- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index d44ed94ef..a44d4c196 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -876,8 +876,8 @@ class Torrent(object): "max_upload_slots": lambda: self.options["max_upload_slots"], "max_upload_speed": lambda: self.options["max_upload_speed"], "message": lambda: self.statusmsg, - "move_on_completed_path": lambda: self.options["move_completed_path"], - "move_on_completed": lambda: self.options["move_completed"], + "move_on_completed_path": lambda: self.options["move_completed_path"], # Deprecated, use move_completed_path + "move_on_completed": lambda: self.options["move_completed"], # Deprecated, use move_completed "move_completed_path": lambda: self.options["move_completed_path"], "move_completed": lambda: self.options["move_completed"], "next_announce": lambda: self.status.next_announce.seconds, diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index dda6bc843..0812e0d57 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -160,6 +160,9 @@ class TorrentManager(component.Component): # The Deferreds will be completed when resume data has been saved. self.waiting_on_resume_data = {} + # Keep track of torrents finished but moving storage + self.waiting_on_finish_moving = [] + # Keeps track of resume data self.resume_data = {} @@ -933,17 +936,15 @@ class TorrentManager(component.Component): torrent.is_finished, total_download, torrent.options["move_completed"], torrent.options["move_completed_path"]) + torrent.update_state() + torrent.is_finished = True # Move completed download to completed folder if needed if not torrent.is_finished and total_download and torrent.options["move_completed"]: if torrent.options["download_location"] != torrent.options["move_completed_path"]: + self.waiting_on_finish_moving.append(torrent_id) torrent.move_storage(torrent.options["move_completed_path"]) - - torrent.update_state() - if not torrent.is_finished and total_download: - torrent.is_finished = True - component.get("EventManager").emit(TorrentFinishedEvent(torrent_id)) - else: - torrent.is_finished = True + else: + component.get("EventManager").emit(TorrentFinishedEvent(torrent_id)) # Torrent is no longer part of the queue try: @@ -1058,12 +1059,17 @@ class TorrentManager(component.Component): """Alert handler for libtorrent storage_moved_alert""" log.debug("on_alert_storage_moved") try: - torrent = self.torrents[str(alert.handle.info_hash())] + torrent_id = str(alert.handle.info_hash()) + torrent = self.torrents[torrent_id] except (RuntimeError, KeyError): return torrent.set_download_location(os.path.normpath(alert.handle.save_path())) torrent.set_move_completed(False) + if torrent in self.waiting_on_finish_moving: + self.waiting_on_finish_moving.remove(torrent_id) + component.get("EventManager").emit(TorrentFinishedEvent(torrent_id)) + def on_alert_storage_moved_failed(self, alert): """Alert handler for libtorrent storage_moved_failed_alert""" log.warning("on_alert_storage_moved_failed: %s", decode_string(alert.message())) @@ -1076,6 +1082,10 @@ class TorrentManager(component.Component): torrent.set_status_message("Error: moving storage location failed") torrent.pause() + if torrent in self.waiting_on_finish_moving: + self.waiting_on_finish_moving.remove(torrent_id) + component.get("EventManager").emit(TorrentFinishedEvent(torrent_id)) + def on_alert_torrent_resumed(self, alert): """Alert handler for libtorrent torrent_resumed_alert""" log.debug("on_alert_torrent_resumed") diff --git a/deluge/plugins/Execute/deluge/plugins/execute/core.py b/deluge/plugins/Execute/deluge/plugins/execute/core.py index a9cc491bc..dbd1b1a12 100644 --- a/deluge/plugins/Execute/deluge/plugins/execute/core.py +++ b/deluge/plugins/Execute/deluge/plugins/execute/core.py @@ -44,6 +44,7 @@ import deluge.component as component from deluge.configmanager import ConfigManager from deluge.core.rpcserver import export from deluge.event import DelugeEvent +from deluge.common import utf8_encoded log = logging.getLogger(__name__) @@ -98,25 +99,17 @@ class Core(CorePluginBase): def execute_commands(self, torrent_id, event, *arg): torrent = component.get("TorrentManager").torrents[torrent_id] - info = torrent.get_status(["name", "save_path", "move_on_completed", "move_on_completed_path"]) + info = torrent.get_status(["name", "download_location"]) - # Grab the torrent name and save path - torrent_name = info["name"] - if event == "complete": - save_path = info["move_on_completed_path"] if info ["move_on_completed"] else info["save_path"] - elif event == "added" and arg[0]: + # Grab the torrent name and download location + # getProcessOutputAndValue requires args to be str + torrent_id = utf8_encoded(torrent_id) + torrent_name = utf8_encoded(info["name"]) + if event == "added" and arg[0]: # No futher action as from_state (arg[0]) is True return else: - save_path = info["save_path"] - - # getProcessOutputAndValue requires args to be str - if isinstance(torrent_id, unicode): - torrent_id = torrent_id.encode("utf-8", "ignore") - if isinstance(torrent_name, unicode): - torrent_name = torrent_name.encode("utf-8", "ignore") - if isinstance(save_path, unicode): - save_path = save_path.encode("utf-8", "ignore") + download_location = utf8_encoded(info["download_location"]) log.debug("[execute] Running commands for %s", event) @@ -135,7 +128,7 @@ class Core(CorePluginBase): command = os.path.expandvars(command[EXECUTE_COMMAND]) command = os.path.expanduser(command) log.debug("[execute] running %s", command) - d = getProcessOutputAndValue(command, (torrent_id, torrent_name, save_path), env=os.environ) + d = getProcessOutputAndValue(command, (torrent_id, torrent_name, download_location), env=os.environ) d.addCallback(log_error, command) def disable(self): diff --git a/deluge/plugins/Extractor/deluge/plugins/extractor/core.py b/deluge/plugins/Extractor/deluge/plugins/extractor/core.py index cc8e72be0..c9ae4b9f6 100644 --- a/deluge/plugins/Extractor/deluge/plugins/extractor/core.py +++ b/deluge/plugins/Extractor/deluge/plugins/extractor/core.py @@ -113,7 +113,6 @@ class Core(CorePluginBase): if not self.config["extract_path"]: self.config["extract_path"] = deluge.configmanager.ConfigManager("core.conf")["download_location"] component.get("EventManager").register_event_handler("TorrentFinishedEvent", self._on_torrent_finished) - def disable(self): component.get("EventManager").deregister_event_handler("TorrentFinishedEvent", self._on_torrent_finished) @@ -125,11 +124,7 @@ class Core(CorePluginBase): This is called when a torrent finishes and checks if any files to extract. """ tid = component.get("TorrentManager").torrents[torrent_id] - tid_status = tid.get_status(["save_path", "move_completed", "name"]) - - if tid_status["move_completed"]: - log.warning("Cannot extract torrents with 'Move Completed' enabled") - return + tid_status = tid.get_status(["download_location", "name"]) files = tid.get_files() for f in files: @@ -143,7 +138,7 @@ class Core(CorePluginBase): cmd = EXTRACT_COMMANDS[file_ext] # Now that we have the cmd, lets run it to extract the files - fpath = os.path.join(tid_status["save_path"], os.path.normpath(f["path"])) + fpath = os.path.join(tid_status["download_location"], os.path.normpath(f["path"])) # Get the destination path dest = os.path.normpath(self.config["extract_path"])