Add new component SessionProxy
Use SessionProxy in place of core.get_torrent_status calls
This commit is contained in:
parent
0b44023f92
commit
da9af84dc1
|
@ -81,7 +81,8 @@ class DetailsTab(Tab):
|
||||||
status_keys = ["name", "total_size", "num_files",
|
status_keys = ["name", "total_size", "num_files",
|
||||||
"tracker", "save_path", "message", "hash", "comment"]
|
"tracker", "save_path", "message", "hash", "comment"]
|
||||||
|
|
||||||
client.core.get_torrent_status(selected, status_keys).addCallback(self._on_get_torrent_status)
|
session = component.get("SessionProxy")
|
||||||
|
session.get_torrent_status(selected, status_keys).addCallback(self._on_get_torrent_status)
|
||||||
|
|
||||||
def _on_get_torrent_status(self, status):
|
def _on_get_torrent_status(self, status):
|
||||||
# Check to see if we got valid data from the core
|
# Check to see if we got valid data from the core
|
||||||
|
|
|
@ -94,8 +94,8 @@ class EditTrackersDialog:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the trackers for this torrent
|
# Get the trackers for this torrent
|
||||||
|
session = component.get("SessionProxy")
|
||||||
client.core.get_torrent_status(self.torrent_id, ["trackers"]).addCallback(self._on_get_torrent_status)
|
session.get_torrent_status(self.torrent_id, ["trackers"]).addCallback(self._on_get_torrent_status)
|
||||||
client.force_call()
|
client.force_call()
|
||||||
|
|
||||||
def _on_get_torrent_status(self, status):
|
def _on_get_torrent_status(self, status):
|
||||||
|
|
|
@ -315,7 +315,7 @@ class FilesTab(Tab):
|
||||||
log.debug("Getting file list from core..")
|
log.debug("Getting file list from core..")
|
||||||
status_keys += ["files"]
|
status_keys += ["files"]
|
||||||
|
|
||||||
client.core.get_torrent_status(self.torrent_id, status_keys).addCallback(self._on_get_torrent_status)
|
component.get("SessionProxy").get_torrent_status(self.torrent_id, status_keys).addCallback(self._on_get_torrent_status)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.treestore.clear()
|
self.treestore.clear()
|
||||||
|
@ -323,7 +323,7 @@ class FilesTab(Tab):
|
||||||
|
|
||||||
def _on_row_activated(self, tree, path, view_column):
|
def _on_row_activated(self, tree, path, view_column):
|
||||||
if client.is_localhost:
|
if client.is_localhost:
|
||||||
client.core.get_torrent_status(self.torrent_id, ["save_path", "files"]).addCallback(self._on_open_file)
|
component.get("SessionProxy").get_torrent_status(self.torrent_id, ["save_path", "files"]).addCallback(self._on_open_file)
|
||||||
|
|
||||||
def get_file_path(self, row, path=""):
|
def get_file_path(self, row, path=""):
|
||||||
if not row:
|
if not row:
|
||||||
|
|
|
@ -80,6 +80,7 @@ from ipcinterface import IPCInterface
|
||||||
from deluge.ui.tracker_icons import TrackerIcons
|
from deluge.ui.tracker_icons import TrackerIcons
|
||||||
from queuedtorrents import QueuedTorrents
|
from queuedtorrents import QueuedTorrents
|
||||||
from addtorrentdialog import AddTorrentDialog
|
from addtorrentdialog import AddTorrentDialog
|
||||||
|
from deluge.ui.sessionproxy import SessionProxy
|
||||||
import dialogs
|
import dialogs
|
||||||
import common
|
import common
|
||||||
|
|
||||||
|
@ -207,6 +208,7 @@ class GtkUI(object):
|
||||||
client.set_disconnect_callback(self.__on_disconnect)
|
client.set_disconnect_callback(self.__on_disconnect)
|
||||||
|
|
||||||
self.trackericons = TrackerIcons()
|
self.trackericons = TrackerIcons()
|
||||||
|
self.sessionproxy = SessionProxy()
|
||||||
# Initialize various components of the gtkui
|
# Initialize various components of the gtkui
|
||||||
self.mainwindow = MainWindow()
|
self.mainwindow = MainWindow()
|
||||||
self.menubar = MenuBar()
|
self.menubar = MenuBar()
|
||||||
|
|
|
@ -314,7 +314,7 @@ class MenuBar(component.Component):
|
||||||
def _on_torrent_status(status):
|
def _on_torrent_status(status):
|
||||||
deluge.common.open_file(status["save_path"])
|
deluge.common.open_file(status["save_path"])
|
||||||
for torrent_id in component.get("TorrentView").get_selected_torrents():
|
for torrent_id in component.get("TorrentView").get_selected_torrents():
|
||||||
client.core.get_torrent_status(torrent_id, ["save_path"]).addCallback(_on_torrent_status)
|
component.get("SessionProxy").get_torrent_status(torrent_id, ["save_path"]).addCallback(_on_torrent_status)
|
||||||
|
|
||||||
def on_menuitem_move_activate(self, data=None):
|
def on_menuitem_move_activate(self, data=None):
|
||||||
log.debug("on_menuitem_move_activate")
|
log.debug("on_menuitem_move_activate")
|
||||||
|
@ -337,8 +337,7 @@ class MenuBar(component.Component):
|
||||||
component.get("TorrentView").get_selected_torrents(), result)
|
component.get("TorrentView").get_selected_torrents(), result)
|
||||||
chooser.destroy()
|
chooser.destroy()
|
||||||
else:
|
else:
|
||||||
client.core.get_torrent_status(component.get("TorrentView").get_selected_torrent(), ["save_path"]).addCallback(self.show_move_storage_dialog)
|
component.get("SessionProxy").get_torrent_status(component.get("TorrentView").get_selected_torrent(), ["save_path"]).addCallback(self.show_move_storage_dialog)
|
||||||
client.force_call(False)
|
|
||||||
|
|
||||||
def show_move_storage_dialog(self, status):
|
def show_move_storage_dialog(self, status):
|
||||||
log.debug("show_move_storage_dialog")
|
log.debug("show_move_storage_dialog")
|
||||||
|
@ -469,4 +468,3 @@ class MenuBar(component.Component):
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
getattr(self.window.main_glade.get_widget(item), attr)()
|
getattr(self.window.main_glade.get_widget(item), attr)()
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Notification:
|
||||||
self.get_torrent_status(torrent_id)
|
self.get_torrent_status(torrent_id)
|
||||||
|
|
||||||
def get_torrent_status(self, torrent_id):
|
def get_torrent_status(self, torrent_id):
|
||||||
client.core.get_torrent_status(torrent_id, ["name", "num_files", "total_payload_download"]).addCallback(self._on_get_torrent_status)
|
component.get("SessionProxy").get_torrent_status(torrent_id, ["name", "num_files", "total_payload_download"]).addCallback(self._on_get_torrent_status)
|
||||||
|
|
||||||
def _on_get_torrent_status(self, status):
|
def _on_get_torrent_status(self, status):
|
||||||
if status is None:
|
if status is None:
|
||||||
|
|
|
@ -98,7 +98,7 @@ class OptionsTab(Tab):
|
||||||
if torrent_id != self.prev_torrent_id:
|
if torrent_id != self.prev_torrent_id:
|
||||||
self.prev_status = None
|
self.prev_status = None
|
||||||
|
|
||||||
client.core.get_torrent_status(torrent_id,
|
component.get("SessionProxy").get_torrent_status(torrent_id,
|
||||||
["max_download_speed",
|
["max_download_speed",
|
||||||
"max_upload_speed",
|
"max_upload_speed",
|
||||||
"max_connections",
|
"max_connections",
|
||||||
|
|
|
@ -257,7 +257,7 @@ class PeersTab(Tab):
|
||||||
self.peers = {}
|
self.peers = {}
|
||||||
self.torrent_id = torrent_id
|
self.torrent_id = torrent_id
|
||||||
|
|
||||||
client.core.get_torrent_status(torrent_id, ["peers"]).addCallback(self._on_get_torrent_status)
|
component.get("SessionProxy").get_torrent_status(torrent_id, ["peers"]).addCallback(self._on_get_torrent_status)
|
||||||
|
|
||||||
def get_flag_pixbuf(self, country):
|
def get_flag_pixbuf(self, country):
|
||||||
if country == " ":
|
if country == " ":
|
||||||
|
|
|
@ -116,7 +116,7 @@ class StatusTab(Tab):
|
||||||
"max_upload_speed", "max_download_speed", "active_time",
|
"max_upload_speed", "max_download_speed", "active_time",
|
||||||
"seeding_time", "seed_rank", "is_auto_managed", "time_added"]
|
"seeding_time", "seed_rank", "is_auto_managed", "time_added"]
|
||||||
|
|
||||||
client.core.get_torrent_status(
|
component.get("SessionProxy").get_torrent_status(
|
||||||
selected, status_keys).addCallback(self._on_get_torrent_status)
|
selected, status_keys).addCallback(self._on_get_torrent_status)
|
||||||
|
|
||||||
def _on_get_torrent_status(self, status):
|
def _on_get_torrent_status(self, status):
|
||||||
|
|
|
@ -164,7 +164,7 @@ def seed_peer_column_sort(model, iter1, iter2, data):
|
||||||
class TorrentView(listview.ListView, component.Component):
|
class TorrentView(listview.ListView, component.Component):
|
||||||
"""TorrentView handles the listing of torrents."""
|
"""TorrentView handles the listing of torrents."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
component.Component.__init__(self, "TorrentView", interval=2)
|
component.Component.__init__(self, "TorrentView", interval=2, depend=["SessionProxy"])
|
||||||
self.window = component.get("MainWindow")
|
self.window = component.get("MainWindow")
|
||||||
# Call the ListView constructor
|
# Call the ListView constructor
|
||||||
listview.ListView.__init__(self,
|
listview.ListView.__init__(self,
|
||||||
|
@ -256,10 +256,9 @@ class TorrentView(listview.ListView, component.Component):
|
||||||
"""Start the torrentview"""
|
"""Start the torrentview"""
|
||||||
# We need to get the core session state to know which torrents are in
|
# We need to get the core session state to know which torrents are in
|
||||||
# the session so we can add them to our list.
|
# the session so we can add them to our list.
|
||||||
client.core.get_session_state().addCallback(self._on_session_state)
|
component.get("SessionProxy").get_torrents_status({}, []).addCallback(self._on_session_state)
|
||||||
|
|
||||||
def _on_session_state(self, state):
|
def _on_session_state(self, state):
|
||||||
log.debug("on_session_state: %s", state)
|
|
||||||
self.treeview.freeze_child_notify()
|
self.treeview.freeze_child_notify()
|
||||||
model = self.treeview.get_model()
|
model = self.treeview.get_model()
|
||||||
for torrent_id in state:
|
for torrent_id in state:
|
||||||
|
@ -268,7 +267,10 @@ class TorrentView(listview.ListView, component.Component):
|
||||||
self.treeview.set_model(model)
|
self.treeview.set_model(model)
|
||||||
self.treeview.thaw_child_notify()
|
self.treeview.thaw_child_notify()
|
||||||
self.got_state = True
|
self.got_state = True
|
||||||
self.update()
|
# Update the view right away with our status
|
||||||
|
self.status = state
|
||||||
|
self.set_columns_to_update()
|
||||||
|
self.update_view()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""Stops the torrentview"""
|
"""Stops the torrentview"""
|
||||||
|
@ -294,10 +296,8 @@ class TorrentView(listview.ListView, component.Component):
|
||||||
self.filter = dict(filter_dict) #copied version of filter_dict.
|
self.filter = dict(filter_dict) #copied version of filter_dict.
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def send_status_request(self, columns=None):
|
def set_columns_to_update(self, columns=None):
|
||||||
# Store the 'status_fields' we need to send to core
|
|
||||||
status_keys = []
|
status_keys = []
|
||||||
# Store the actual columns we will be updating
|
|
||||||
self.columns_to_update = []
|
self.columns_to_update = []
|
||||||
|
|
||||||
if columns is None:
|
if columns is None:
|
||||||
|
@ -317,6 +317,11 @@ class TorrentView(listview.ListView, component.Component):
|
||||||
|
|
||||||
# Remove duplicate keys
|
# Remove duplicate keys
|
||||||
self.columns_to_update = list(set(self.columns_to_update))
|
self.columns_to_update = list(set(self.columns_to_update))
|
||||||
|
return status_keys
|
||||||
|
|
||||||
|
def send_status_request(self, columns=None):
|
||||||
|
# Store the 'status_fields' we need to send to core
|
||||||
|
status_keys = self.set_columns_to_update(columns)
|
||||||
|
|
||||||
# If there is nothing in status_keys then we must not continue
|
# If there is nothing in status_keys then we must not continue
|
||||||
if status_keys is []:
|
if status_keys is []:
|
||||||
|
@ -327,8 +332,8 @@ class TorrentView(listview.ListView, component.Component):
|
||||||
|
|
||||||
# Request the statuses for all these torrent_ids, this is async so we
|
# Request the statuses for all these torrent_ids, this is async so we
|
||||||
# will deal with the return in a signal callback.
|
# will deal with the return in a signal callback.
|
||||||
client.core.get_torrents_status(
|
component.get("SessionProxy").get_torrents_status(
|
||||||
self.filter, status_keys, True).addCallback(self._on_get_torrents_status)
|
self.filter, status_keys).addCallback(self._on_get_torrents_status)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if self.got_state:
|
if self.got_state:
|
||||||
|
|
|
@ -0,0 +1,227 @@
|
||||||
|
#
|
||||||
|
# sessionproxy.py
|
||||||
|
#
|
||||||
|
# Copyright (C) 2010 Andrew Resch <andrewresch@gmail.com>
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# In addition, as a special exception, the copyright holders give
|
||||||
|
# permission to link the code of portions of this program with the OpenSSL
|
||||||
|
# library.
|
||||||
|
# You must obey the GNU General Public License in all respects for all of
|
||||||
|
# the code used other than OpenSSL. If you modify file(s) with this
|
||||||
|
# exception, you may extend this exception to your version of the file(s),
|
||||||
|
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||||
|
# this exception statement from your version. If you delete this exception
|
||||||
|
# statement from all source files in the program, then also delete it here.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from twisted.internet.defer import maybeDeferred, succeed
|
||||||
|
|
||||||
|
import deluge.component as component
|
||||||
|
from deluge.ui.client import client
|
||||||
|
from deluge.log import LOG as log
|
||||||
|
import time
|
||||||
|
|
||||||
|
class SessionProxy(component.Component):
|
||||||
|
"""
|
||||||
|
The SessionProxy component is used to cache session information client-side
|
||||||
|
to reduce the number of RPCs needed to provide a rich user interface.
|
||||||
|
|
||||||
|
On start-up it will query the Core for a full status of all the torrents in
|
||||||
|
the session. After that point, it will query the Core for only changes in
|
||||||
|
the status of the torrents and will try to satisfy client requests from the
|
||||||
|
cache.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
log.debug("SessionProxy init..")
|
||||||
|
component.Component.__init__(self, "SessionProxy", interval=5)
|
||||||
|
|
||||||
|
# Set the cache time in seconds
|
||||||
|
# This is how long data will be valid before refetching from the core
|
||||||
|
self.cache_time = 1.5
|
||||||
|
|
||||||
|
# Hold the torrents' status.. {torrent_id: [time, {status_dict}], ...}
|
||||||
|
self.torrents = {}
|
||||||
|
|
||||||
|
# Hold the time awhen the last state filter was used and the torrent_ids returned
|
||||||
|
# [(filter_dict, time, (torrent_id, ...)), ...]
|
||||||
|
self.state_filter_queries = []
|
||||||
|
|
||||||
|
client.register_event_handler("TorrentStateChangedEvent", self.on_torrent_state_changed)
|
||||||
|
client.register_event_handler("TorrentRemovedEvent", self.on_torrent_removed)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
def on_torrent_status(status):
|
||||||
|
# Save the time we got the torrent status
|
||||||
|
t = time.time()
|
||||||
|
for key, value in status.items():
|
||||||
|
self.torrents[key] = [t, value]
|
||||||
|
|
||||||
|
return client.core.get_torrents_status({}, [], True).addCallback(on_torrent_status)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.torrents = {}
|
||||||
|
self.state_filter_queries = {}
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
# Clean-up any stale filter queries
|
||||||
|
sfq = self.state_filter_queries
|
||||||
|
t = time.time()
|
||||||
|
self.state_filter_queries = [x for x in sfq if (t - x[1]) < self.cache_time]
|
||||||
|
|
||||||
|
def create_status_dict(self, torrent_ids, keys):
|
||||||
|
"""
|
||||||
|
Creates a status dict from the cache.
|
||||||
|
|
||||||
|
:param torrent_ids: the torrent_ids
|
||||||
|
:type torrent_ids: list of strings
|
||||||
|
:param keys: the status keys
|
||||||
|
:type keys: list of strings
|
||||||
|
|
||||||
|
:returns: a dict with the status information for the *torrent_ids*
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
"""
|
||||||
|
sd = {}
|
||||||
|
for torrent_id in torrent_ids:
|
||||||
|
sd[torrent_id] = dict([(x, y) for x, y in self.torrents[torrent_id][1].iteritems() if x in keys])
|
||||||
|
return sd
|
||||||
|
|
||||||
|
def get_torrent_status(self, torrent_id, keys):
|
||||||
|
"""
|
||||||
|
Get a status dict for one torrent.
|
||||||
|
|
||||||
|
:param torrent_id: the torrent_id
|
||||||
|
:type torrent_id: string
|
||||||
|
:param keys: the status keys
|
||||||
|
:type keys: list of strings
|
||||||
|
|
||||||
|
:returns: a dict of status information
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
"""
|
||||||
|
if torrent_id in self.torrents:
|
||||||
|
if time.time() - self.torrents[torrent_id][0] < self.cache_time:
|
||||||
|
return succeed(self.create_status_dict([torrent_id], keys)[torrent_id])
|
||||||
|
else:
|
||||||
|
d = client.core.get_torrent_status(torrent_id, keys, True)
|
||||||
|
def on_status(result, torrent_id):
|
||||||
|
self.torrents[torrent_id][0] = time.time()
|
||||||
|
self.torrents[torrent_id][1].update(result)
|
||||||
|
return self.torrents[torrent_id][1]
|
||||||
|
return d.addCallback(on_status, torrent_id)
|
||||||
|
else:
|
||||||
|
d = client.core.get_torrent_status(torrent_id, keys, True)
|
||||||
|
def on_status(result):
|
||||||
|
if result:
|
||||||
|
self.torrents[torrent_id] = (time.time(), result)
|
||||||
|
return result
|
||||||
|
return d.addCallback(on_status)
|
||||||
|
|
||||||
|
def get_torrents_status(self, filter_dict, keys):
|
||||||
|
"""
|
||||||
|
Get a dict of torrent statuses.
|
||||||
|
|
||||||
|
The filter can take 2 keys, *state* and *id*. The state filter can be
|
||||||
|
one of the torrent states or the special one *Active*. The *id* key is
|
||||||
|
simply a list of torrent_ids.
|
||||||
|
|
||||||
|
:param filter_dict: the filter used for this query
|
||||||
|
:type filter_dict: dict
|
||||||
|
:param keys: the status keys
|
||||||
|
:type keys: list of strings
|
||||||
|
|
||||||
|
:returns: a dict of torrent_ids and their status dicts
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Helper functions and callbacks ---------------------------------------
|
||||||
|
def on_status(result, torrent_ids, keys):
|
||||||
|
# Update the internal torrent status dict with the update values
|
||||||
|
t = time.time()
|
||||||
|
for key, value in result.items():
|
||||||
|
self.torrents[key][0] = t
|
||||||
|
self.torrents[key][1].update(value)
|
||||||
|
|
||||||
|
# Create the status dict
|
||||||
|
if not torrent_ids:
|
||||||
|
torrent_ids = self.torrents.keys()
|
||||||
|
|
||||||
|
return self.create_status_dict(torrent_ids, keys)
|
||||||
|
|
||||||
|
def find_torrents_to_fetch(torrent_ids):
|
||||||
|
to_fetch = []
|
||||||
|
t = time.time()
|
||||||
|
for key in torrent_ids:
|
||||||
|
torrent = self.torrents[key]
|
||||||
|
if t - torrent[0] > self.cache_time:
|
||||||
|
to_fetch.append(key)
|
||||||
|
|
||||||
|
return to_fetch
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if not filter_dict:
|
||||||
|
# This means we want all the torrents status
|
||||||
|
# We get a list of any torrent_ids with expired status dicts
|
||||||
|
to_fetch = find_torrents_to_fetch(self.torrents.keys())
|
||||||
|
if to_fetch:
|
||||||
|
d = client.core.get_torrents_status({"id": to_fetch}, keys, True)
|
||||||
|
return d.addCallback(on_status, [], keys)
|
||||||
|
|
||||||
|
# Don't need to fetch anything
|
||||||
|
return maybeDeferred(self.create_status_dict, self.torrents.keys(), keys)
|
||||||
|
|
||||||
|
if "state" in filter_dict:
|
||||||
|
# We check if a similar query has already been done within our cache time
|
||||||
|
# and return results for those torrent_ids
|
||||||
|
for sfq in self.state_filter_queries:
|
||||||
|
if sfq[0] == filter_dict and (time.time() - sfq[1]) < self.cache_time:
|
||||||
|
# We found a winner!
|
||||||
|
if "id" in filter_dict:
|
||||||
|
filter_fict["id"].extend(sfq[2])
|
||||||
|
else:
|
||||||
|
filter_dict["id"] = sfq[2]
|
||||||
|
del filter_dict["state"]
|
||||||
|
break
|
||||||
|
|
||||||
|
if "state" in filter_dict:
|
||||||
|
# If we got there, then there is no suitable cached filter query, so
|
||||||
|
# we'll just query the core
|
||||||
|
d = client.core.get_torrents_status(filer_dict, keys. True)
|
||||||
|
def on_filter_status(result, keys):
|
||||||
|
return on_status(result, result.keys(), keys)
|
||||||
|
return d.addCallback(on_filter_status, keys)
|
||||||
|
|
||||||
|
# At this point we should have a filter with just "id" in it
|
||||||
|
to_fetch = find_torrents_to_fetch(filter_dict["id"])
|
||||||
|
if to_fetch:
|
||||||
|
d = client.core.get_torrents_status({"id": to_fetch}, keys, True)
|
||||||
|
return d.addCallback(on_status, filter_dict["id"], keys)
|
||||||
|
else:
|
||||||
|
# Don't need to fetch anything, so just return data from the cache
|
||||||
|
return maybeDeferred(self.create_status_dict, filter_dict["id"], keys)
|
||||||
|
|
||||||
|
def on_torrent_state_changed(self, torrent_id, state):
|
||||||
|
self.torrents[torrent_id][1]["state"] = state
|
||||||
|
|
||||||
|
def on_torrent_removed(self, torrent_id):
|
||||||
|
del self.torrents[torrent_id]
|
Loading…
Reference in New Issue