diff --git a/deluge/core/core.py b/deluge/core/core.py index ad1fc5f45..dfb75918d 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -229,12 +229,12 @@ class Core( # Start the SignalManager self.signals = SignalManager() - - # Start the TorrentManager - self.torrents = TorrentManager(self.session, self.alerts) - + # Load plugins self.plugins = PluginManager(self) + + # Start the TorrentManager + self.torrents = TorrentManager(self.session, self.alerts) # Register alert handlers self.alerts.register_handler("torrent_paused_alert", @@ -517,7 +517,47 @@ class Core( """Clears the ip filter""" self.ip_filter = lt.ip_filter() self.session.set_ip_filter(self.ip_filter) - + + ## Queueing functions ## + def export_queue_top(self, torrent_id): + log.debug("Attempting to queue %s to top", torrent_id) + try: + # If the queue method returns True, then we should emit a signal + if self.torrents.queue.top(torrent_id): + self._torrent_queue_changed(torrent_id) + except KeyError: + log.warning("torrent_id: %s does not exist in the queue", + torrent_id) + + def export_queue_up(self, torrent_id): + log.debug("Attempting to queue %s to up", torrent_id) + try: + # If the queue method returns True, then we should emit a signal + if self.torrents.queue.up(torrent_id): + self._torrent_queue_changed(torrent_id) + except KeyError: + log.warning("torrent_id: %s does not exist in the queue", + torrent_id) + + def export_queue_down(self, torrent_id): + log.debug("Attempting to queue %s to down", torrent_id) + try: + # If the queue method returns True, then we should emit a signal + if self.torrents.queue.down(torrent_id): + self._torrent_queue_changed(torrent_id) + except KeyError: + log.warning("torrent_id: %s does not exist in the queue", + torrent_id) + + def export_queue_bottom(self, torrent_id): + log.debug("Attempting to queue %s to bottom", torrent_id) + try: + # If the queue method returns True, then we should emit a signal + if self.torrents.queue.bottom(torrent_id): + self._torrent_queue_changed(torrent_id) + except KeyError: + log.warning("torrent_id: %s does not exist in the queue", + torrent_id) # Signals def torrent_added(self, torrent_id): """Emitted when a new torrent is added to the core""" @@ -553,6 +593,10 @@ class Core( """Emitted when a config value has changed""" log.debug("config_value_changed signal emitted") self.signals.emit("config_value_changed", key, value) + + def _torrent_queue_changed(self): + """Emitted when a torrent queue position is changed""" + log.debug("torrent_queue_changed signal emitted") # Config set functions def _on_config_value_change(self, key, value): diff --git a/deluge/core/pluginmanager.py b/deluge/core/pluginmanager.py index c34f244b4..8c80f6ba4 100644 --- a/deluge/core/pluginmanager.py +++ b/deluge/core/pluginmanager.py @@ -50,7 +50,8 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase, # Set up the hooks dictionary self.hooks = { "post_torrent_add": [], - "post_torrent_remove": [] + "post_torrent_remove": [], + "post_session_load": [] } self.status_fields = {} @@ -139,6 +140,14 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase, for function in self.hooks["post_torrent_remove"]: function(torrent_id) + def run_post_session_load(self): + """This hook is run after all the torrents have been loaded into the + session from the saved state. It is called prior to resuming the + torrents and they all will have a 'Paused' state.""" + log.debug("run_post_session_load") + for function in self.hooks["post_session_load"]: + function() + def get_torrent_list(self): """Returns a list of torrent_id's in the current session.""" return component.get("TorrentManager").get_torrent_list() diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 01e3e58ec..13e465277 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -252,7 +252,8 @@ class Torrent: "max_upload_speed": self.max_upload_speed, "max_download_speed": self.max_download_speed, "prioritize_first_last": self.prioritize_first_last, - "private": self.private + "private": self.private, + "queue": 0 } fns = { diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index ff4ac45f4..0429da39a 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -48,7 +48,8 @@ from deluge.core.torrent import Torrent from deluge.log import LOG as log class TorrentState: - def __init__(self, + def __init__(self, + torrent_id, filename, total_uploaded, trackers, @@ -63,6 +64,7 @@ class TorrentState: private, file_priorities ): + self.torrent_id = torrent_id self.filename = filename self.total_uploaded = total_uploaded self.trackers = trackers @@ -129,6 +131,9 @@ class TorrentManager(component.Component): self.on_alert_storage_moved) def start(self): + # Get the pluginmanager reference + self.plugins = component.get("PluginManager") + # Try to load the state from file self.load_state() @@ -151,7 +156,8 @@ class TorrentManager(component.Component): """Returns a list of torrent_ids""" return self.torrents.keys() - def add(self, filename, filedump=None, options=None, total_uploaded=0, trackers=None): + def add(self, filename, filedump=None, options=None, total_uploaded=0, + trackers=None, save_state=True): """Add a torrent to the manager and returns it's torrent_id""" log.info("Adding torrent: %s", filename) log.debug("options: %s", options) @@ -262,8 +268,10 @@ class TorrentManager(component.Component): # Save the torrent file torrent.save_torrent_file(filedump) - # Save the session state - self.save_state() + if save_state: + # Save the session state + self.save_state() + return torrent.torrent_id def load_torrent(self, filename): @@ -410,7 +418,8 @@ class TorrentManager(component.Component): except IOError: log.warning("Unable to load state file.") - # Try to add the torrents in the state to the session + # Try to add the torrents in the state to the session + add_paused = {} for torrent_state in state.torrents: try: options = { @@ -421,25 +430,37 @@ class TorrentManager(component.Component): "max_download_speed_per_torrent": torrent_state.max_download_speed, "prioritize_first_last_pieces": torrent_state.prioritize_first_last, "download_location": torrent_state.save_path, - "add_paused": torrent_state.paused, + "add_paused": True, "default_private": torrent_state.private, "file_priorities": torrent_state.file_priorities } + # We need to resume all non-add_paused torrents after plugin hook + add_paused[torrent_state.torrent_id] = torrent_state.paused self.add( torrent_state.filename, options=options, total_uploaded=torrent_state.total_uploaded, - trackers=torrent_state.trackers) + trackers=torrent_state.trackers, + save_state=False) except AttributeError, e: log.error("Torrent state file is either corrupt or incompatible!") break - + + # Run the post_session_load plugin hooks + self.plugins.run_post_session_load() + + # Resume any torrents that need to be resumed + for key in add_paused.keys(): + if add_paused[key] == True: + self.torrents[key].handle.resume() + def save_state(self): """Save the state of the TorrentManager to the torrents.state file""" state = TorrentManagerState() # Create the state for each Torrent and append to the list for torrent in self.torrents.values(): torrent_state = TorrentState( + torrent.torrent_id, torrent.filename, torrent.get_status(["total_uploaded"])["total_uploaded"], torrent.trackers,