diff --git a/deluge/core/core.py b/deluge/core/core.py index b0fbdce62..4b95e4db0 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -385,9 +385,9 @@ class Core(component.Component): self.torrentmanager[torrent_id].resume() @export - def get_torrent_status(self, torrent_id, keys): + def get_torrent_status(self, torrent_id, keys, diff=False): # Build the status dictionary - status = self.torrentmanager[torrent_id].get_status(keys) + status = self.torrentmanager[torrent_id].get_status(keys, diff) # Get the leftover fields and ask the plugin manager to fill them leftover_fields = list(set(keys) - set(status.keys())) @@ -396,7 +396,7 @@ class Core(component.Component): return status @export - def get_torrents_status(self, filter_dict, keys): + def get_torrents_status(self, filter_dict, keys, diff=False): """ returns all torrents , optionally filtered by filter_dict. """ @@ -405,7 +405,7 @@ class Core(component.Component): # Get the torrent status for each torrent_id for torrent_id in torrent_ids: - status_dict[torrent_id] = self.get_torrent_status(torrent_id, keys) + status_dict[torrent_id] = self.get_torrent_status(torrent_id, keys, diff) return status_dict diff --git a/deluge/core/pluginmanager.py b/deluge/core/pluginmanager.py index 647a297c1..07f16bcfb 100644 --- a/deluge/core/pluginmanager.py +++ b/deluge/core/pluginmanager.py @@ -96,8 +96,7 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase, try: status[field] = self.status_fields[field](torrent_id) except KeyError: - log.warning("Status field %s is not registered with the\ - PluginManager.", field) + pass return status def register_status_field(self, field, function): diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index b1b891df0..8b4531247 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -72,7 +72,7 @@ class TorrentOptions(dict): self["file_priorities"] = [] self["mapped_files"] = {} -class Torrent: +class Torrent(object): """Torrent holds information about torrents added to the libtorrent session. """ def __init__(self, handle, options, state=None, filename=None, magnet=None): @@ -80,6 +80,16 @@ class Torrent: # Get the core config self.config = ConfigManager("core.conf") + self.rpcserver = component.get("RPCServer") + + # This dict holds previous status dicts returned for this torrent + # We use this to return dicts that only contain changes from the previous + # {session_id: status_dict, ...} + self.prev_status = {} + from twisted.internet.task import LoopingCall + self.prev_status_cleanup_loop = LoopingCall(self.cleanup_prev_status) + self.prev_status_cleanup_loop.start(10) + # Set the libtorrent handle self.handle = handle # Set the torrent_id for this torrent @@ -525,8 +535,21 @@ class Torrent: return host return "" - def get_status(self, keys): - """Returns the status of the torrent based on the keys provided""" + def get_status(self, keys, diff=False): + """ + Returns the status of the torrent based on the keys provided + + :param keys: the keys to get the status on + :type keys: list of str + :param diff: if True, will return a diff of the changes since the last + call to get_status based on the session_id + :type diff: bool + + :returns: a dictionary of the status keys and their values + :rtype: dict + + """ + # Create the full dictionary self.status = self.handle.status() if self.handle.has_metadata(): @@ -656,6 +679,24 @@ class Torrent: status_dict[key] = full_status[key] elif key in fns: status_dict[key] = fns[key]() + + session_id = self.rpcserver.get_session_id() + if diff: + if session_id in self.prev_status: + # We have a previous status dict, so lets make a diff + status_diff = {} + for key, value in status_dict.items(): + if key in self.prev_status[session_id]: + if value != self.prev_status[session_id][key]: + status_diff[key] = value + else: + status_diff[key] = value + + self.prev_status[session_id] = status_dict + return status_diff + + self.prev_status[session_id] = status_dict + return status_dict return status_dict @@ -828,3 +869,14 @@ class Torrent: wait_on_folder[2].append(f["index"]) self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1).encode("utf-8")) self.waiting_on_folder_rename.append(wait_on_folder) + + def cleanup_prev_status(self): + """ + This method gets called to check the validity of the keys in the prev_status + dict. If the key is no longer valid, the dict will be deleted. + + """ + for key in self.prev_status.keys(): + if not self.rpcserver.is_session_valid(key): + del self.prev_status[key] + diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index cb6f05591..eb2c02762 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -387,6 +387,8 @@ class TorrentManager(component.Component): if options["mapped_files"]: for index, name in options["mapped_files"].items(): log.debug("renaming file index %s to %s", index, name) + import code + code.interact(local=locals()) torrent_info.rename_file(index, name.encode("utf-8")) add_torrent_params["ti"] = torrent_info diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py index 6725c840f..03a6f0839 100644 --- a/deluge/ui/gtkui/torrentview.py +++ b/deluge/ui/gtkui/torrentview.py @@ -325,7 +325,7 @@ class TorrentView(listview.ListView, component.Component): # Request the statuses for all these torrent_ids, this is async so we # will deal with the return in a signal callback. client.core.get_torrents_status( - self.filter, status_keys).addCallback(self._on_get_torrents_status) + self.filter, status_keys, True).addCallback(self._on_get_torrents_status) def update(self): # Send a status request