From cceb2ef5a00509c8299bdc5ac1c52691b4ff3555 Mon Sep 17 00:00:00 2001 From: Andrew Resch Date: Tue, 25 Mar 2008 08:28:50 +0000 Subject: [PATCH] Start of peers tab implementation. --- deluge/core/torrent.py | 27 ++++++- deluge/ui/gtkui/files_tab.py | 1 - deluge/ui/gtkui/peers_tab.py | 150 +++++++++++++++++++++++++++++++++-- 3 files changed, 168 insertions(+), 10 deletions(-) diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index 7a5231475..8ae8c29fb 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -40,6 +40,7 @@ import deluge.common import deluge.component as component from deluge.configmanager import ConfigManager from deluge.log import LOG as log +import deluge.xmlrpclib TORRENT_STATE = deluge.common.TORRENT_STATE @@ -223,6 +224,29 @@ class Torrent: # list. return self.torrentqueue[self.torrent_id] + 1 + + def get_peers(self): + """Returns a list of peers and various information about them""" + ret = [] + peers = self.handle.get_peer_info() + + for peer in peers: + # Find the progress + num_pieces_complete = 0 + for piece in peer["pieces"]: + if piece: + num_pieces_complete += 1 + progress = num_pieces_complete / len(peer["pieces"]) * 100 + ret.append({ + "ip": peer["ip"], + "up_speed": peer["up_speed"], + "down_speed": peer["down_speed"], + "country": peer["country"], + "client": deluge.xmlrpclib.Binary(peer["client"]), + "progress": progress + }) + + return ret def get_status(self, keys): """Returns the status of the torrent based on the keys provided""" @@ -280,7 +304,8 @@ class Torrent: "ratio": self.get_ratio, "file_progress": self.handle.file_progress, "queue": self.get_queue_position, - "is_seed": self.handle.is_seed, + "is_seed": self.handle.is_seed, + "peers": self.get_peers } self.status = None diff --git a/deluge/ui/gtkui/files_tab.py b/deluge/ui/gtkui/files_tab.py index ec6567d9b..0586ffcf8 100644 --- a/deluge/ui/gtkui/files_tab.py +++ b/deluge/ui/gtkui/files_tab.py @@ -41,7 +41,6 @@ from deluge.ui.client import aclient as client from deluge.configmanager import ConfigManager import deluge.component as component import deluge.common -import deluge.ui.gtkui.listview from deluge.log import LOG as log diff --git a/deluge/ui/gtkui/peers_tab.py b/deluge/ui/gtkui/peers_tab.py index b683cc930..f55a4b44c 100644 --- a/deluge/ui/gtkui/peers_tab.py +++ b/deluge/ui/gtkui/peers_tab.py @@ -32,19 +32,32 @@ # statement from all source files in the program, then also delete it here. import gtk, gtk.glade +import os.path +import cPickle from deluge.ui.client import aclient as client +from deluge.configmanager import ConfigManager import deluge.component as component import deluge.common +from deluge.ui.gtkui.listview import cell_data_speed as cell_data_speed +from deluge.log import LOG as log def cell_data_country(column, cell, model, row, data): pass - + +class ColumnState: + def __init__(self, name, position, width, sort, sort_order): + self.name = name + self.position = position + self.width = width + self.sort = sort + self.sort_order = sort_order + class PeersTab: def __init__(self): glade = component.get("MainWindow").get_glade() self.listview = glade.get_widget("peers_listview") - # country, filename, size, priority + # country, ip, client, progress, progress, downspeed, upspeed self.liststore = gtk.ListStore(str, str, str, str, int, int, int) # Country column @@ -52,6 +65,12 @@ class PeersTab: render = gtk.CellRendererPixbuf() column.pack_start(render, False) column.set_cell_data_func(render, cell_data_country, 0) + column.set_sort_column_id(0) + column.set_clickable(True) + column.set_resizable(True) + column.set_expand(False) + column.set_min_width(10) + column.set_reorderable(True) self.listview.append_column(column) # Address column @@ -59,6 +78,12 @@ class PeersTab: render = gtk.CellRendererText() column.pack_start(render, False) column.add_attribute(render, "text", 1) + column.set_sort_column_id(1) + column.set_clickable(True) + column.set_resizable(True) + column.set_expand(False) + column.set_min_width(10) + column.set_reorderable(True) self.listview.append_column(column) # Client column @@ -66,34 +91,143 @@ class PeersTab: render = gtk.CellRendererText() column.pack_start(render, False) column.add_attribute(render, "text", 2) + column.set_sort_column_id(2) + column.set_clickable(True) + column.set_resizable(True) + column.set_expand(False) + column.set_min_width(10) + column.set_reorderable(True) self.listview.append_column(column) # Progress column column = gtk.TreeViewColumn(_("Progress")) render = gtk.CellRendererProgress() - column.pack_start(render, False) + column.pack_start(render) column.add_attribute(render, "text", 3) column.add_attribute(render, "value", 4) + column.set_sort_column_id(4) + column.set_clickable(True) + column.set_resizable(True) + column.set_expand(False) + column.set_min_width(10) + column.set_reorderable(True) self.listview.append_column(column) # Down Speed column column = gtk.TreeViewColumn(_("Down Speed")) render = gtk.CellRendererText() column.pack_start(render, False) - column.set_cell_data_func(render, deluge.common.fspeed, 5) + column.set_cell_data_func(render, cell_data_speed, 5) + column.set_sort_column_id(5) + column.set_clickable(True) + column.set_resizable(True) + column.set_expand(False) + column.set_min_width(10) + column.set_reorderable(True) self.listview.append_column(column) # Up Speed column column = gtk.TreeViewColumn(_("Up Speed")) render = gtk.CellRendererText() column.pack_start(render, False) - column.set_cell_data_func(render, deluge.common.fspeed, 6) + column.set_cell_data_func(render, cell_data_speed, 6) + column.set_sort_column_id(6) + column.set_clickable(True) + column.set_resizable(True) + column.set_expand(False) + column.set_min_width(10) + column.set_reorderable(True) self.listview.append_column(column) self.listview.set_model(self.liststore) - def update(self): - pass + self.load_state() + + self.torrent_id = None + + def save_state(self): + filename = "peers_tab.state" + state = [] + for index, column in enumerate(self.listview.get_columns()): + state.append(ColumnState(column.get_title(), index, column.get_width(), + column.get_sort_indicator(), int(column.get_sort_order()))) + + # Get the config location for saving the state file + config_location = ConfigManager("gtkui.conf")["config_location"] + + try: + log.debug("Saving FilesTab state file: %s", filename) + state_file = open(os.path.join(config_location, filename), "wb") + cPickle.dump(state, state_file) + state_file.close() + except IOError, e: + log.warning("Unable to save state file: %s", e) + def load_state(self): + filename = "peers_tab.state" + # Get the config location for loading the state file + config_location = ConfigManager("gtkui.conf")["config_location"] + state = None + + try: + log.debug("Loading FilesTab state file: %s", filename) + state_file = open(os.path.join(config_location, filename), "rb") + state = cPickle.load(state_file) + state_file.close() + except IOError, e: + log.warning("Unable to load state file: %s", e) + + if state == None: + return + + for column_state in state: + # Find matching columns in the listview + for (index, column) in enumerate(self.listview.get_columns()): + if column_state.name == column.get_title(): + # We have a match, so set options that were saved in state + if column_state.width > 0: + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(column_state.width) + column.set_sort_indicator(column_state.sort) + column.set_sort_order(column_state.sort_order) + if column_state.position != index: + # Column is in wrong position + if column_state.position == 0: + self.listview.move_column_after(column, None) + else: + self.listview.move_column_after(column, self.listview.get_columns()[column_state.position - 1]) + + def update(self): + # Get the first selected torrent + torrent_id = component.get("TorrentView").get_selected_torrents() + + # Only use the first torrent in the list or return if None selected + if len(torrent_id) != 0: + torrent_id = torrent_id[0] + else: + # No torrent is selected in the torrentview + self.liststore.clear() + return + + if torrent_id != self.torrent_id: + # We only want to do this if the torrent_id has changed + self.liststore.clear() + self.torrent_id = torrent_id + log.debug("torrent_id: %s", torrent_id) + client.get_torrent_status(self._on_get_torrent_status, torrent_id, ["peers"]) + + def _on_get_torrent_status(self, status): + self.liststore.clear() + log.debug("status: %s", status) + for peer in status["peers"]: + self.liststore.append([ + peer["country"], + peer["ip"], + peer["client"], + "%.2f%%" % peer["progress"], + peer["progress"], + peer["down_speed"], + peer["up_speed"]]) + def clear(self): - pass + self.liststore.clear()