pieces rewrite - micah

This commit is contained in:
Marcos Pinto 2007-08-08 06:32:41 +00:00
commit 2fa11dc18f
3 changed files with 292 additions and 241 deletions

View file

@ -18,25 +18,19 @@
plugin_name = _("Torrent Pieces") plugin_name = _("Torrent Pieces")
plugin_author = "Micah Bucy" plugin_author = "Micah Bucy"
plugin_version = "0.2" plugin_version = "0.3"
plugin_description = _(""" plugin_description = _("""
Adds a pieces tab which gives piece by piece progress for a torrent. Pieces tab now shows percentage instead
Each piece is represented by a small progress bar. of progress bars. There are no longer any tooltips.
Peer speed uses following symbols:
fast is +
medium is =
slow is -
Pieces currently downloading show up as partially filled progress bars, monospace font is required for columns to be aligned.
but this does not represent percentage done.
More information is provided as a tooltip for each piece. Finished torrents do not show piece information, just
For currently downloading pieces, the tooltip contains the number a message that the torrent is complete.
of blocks finished as well as the peer speed for that piece.
When the plugin initializes, such as when enabling the plugin or
when a different torrent is selected, the cpu will spike. This is normal,
as initialization must get information on every piece from libtorrent,
and the cpu will normalize once all of the information is retrieved.
This plugin supports multifile torrents. If a file is skipped, it does not
show up in the pieces tab.
""") """)
def deluge_init(deluge_path): def deluge_init(deluge_path):
@ -58,24 +52,74 @@ class TorrentPieces:
print "Loading TorrentPieces plugin..." print "Loading TorrentPieces plugin..."
self.manager = core self.manager = core
self.parent = interface self.parent = interface
scrolledWindow = gtk.ScrolledWindow() self.config_file = deluge.common.CONFIG_DIR + "/pieces.conf"
scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.config = deluge.pref.Preferences(self.config_file)
self.topWidget = scrolledWindow try:
self.config.load()
except IOError:
# File does not exist
pass
self.glade = gtk.glade.XML(path + "/pieces_preferences.glade")
widget = self.glade.get_widget("hbox_columns")
self.combo_columns = gtk.combo_box_new_text()
for x in xrange(100):
self.combo_columns.append_text(str(x+1))
widget.pack_start(self.combo_columns, expand=False)
widget.show_all()
widget = self.glade.get_widget("hbox_font_size")
self.combo_font_size = gtk.combo_box_new_text()
for x in xrange(100):
self.combo_font_size.append_text(str(x+1))
widget.pack_start(self.combo_font_size, expand=False)
widget.show_all()
self.dialog = self.glade.get_widget("dialog")
self.glade.signal_autoconnect({
'on_button_cancel_pressed': self.cancel_pressed,
'on_button_ok_pressed': self.ok_pressed
})
scrolled_window = gtk.ScrolledWindow()
scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
viewport = gtk.Viewport()
scrolled_window.add(viewport)
self.top_widget = scrolled_window
self.parentNotebook = self.parent.notebook self.parent_notebook = self.parent.notebook
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Pieces"))) self.parent_notebook.append_page(self.top_widget, gtk.Label(_("Pieces")))
self.topWidget.show_all() self.top_widget.show_all()
self.tab_pieces = PiecesTabManager(self.manager) columns = self.config.get("columns")
if columns is None:
columns = 15
font_size = self.config.get("font_size")
if font_size is None:
font_size = 9
self.tab_pieces = PiecesTabManager(self.manager, viewport, columns, font_size)
self.manager.connect_event(self.manager.constants['EVENT_FINISHED'], self.handle_event)
def unload(self): def unload(self):
self.tab_pieces.disconnect_handlers() self.tab_pieces.disconnect_handlers()
self.manager.disconnect_event(self.manager.constants['EVENT_FINISHED'], self.handle_event)
self.tab_pieces.clear_pieces_store() self.tab_pieces.clear_pieces_store()
numPages = self.parentNotebook.get_n_pages() tab_page = self.parent_notebook.page_num(self.top_widget)
for page in xrange(numPages): self.parent_notebook.remove_page(tab_page)
if self.parentNotebook.get_nth_page(page) == self.topWidget:
self.parentNotebook.remove_page(page) def configure(self, window):
break try:
self.combo_columns.set_active(self.config.get("columns"))
except:
self.combo_columns.set_active(15)
try:
self.combo_font_size.set_active(self.config.get("font_size"))
except:
self.combo_font_size.set_active(9)
self.dialog.set_transient_for(window)
self.dialog.show()
def handle_event(self, event):
self.tab_pieces.disconnect_handlers()
self.tab_pieces.clear_pieces_store()
self.tab_pieces.set_unique_id(event['unique_ID'])
self.tab_pieces.prepare_pieces_store()
def update(self): def update(self):
update_files_removed = self.manager.update_files_removed update_files_removed = self.manager.update_files_removed
@ -89,38 +133,29 @@ class TorrentPieces:
#if different torrent was selected or file priorities were changed. #if different torrent was selected or file priorities were changed.
self.tab_pieces.disconnect_handlers() self.tab_pieces.disconnect_handlers()
self.tab_pieces.clear_pieces_store() self.tab_pieces.clear_pieces_store()
numPages = self.parentNotebook.get_n_pages()
for page in xrange(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
break
switch_page = False
if self.parentNotebook.get_current_page() == page:
switch_page = True
self.parentNotebook.remove_page(page)
viewport = gtk.Viewport()
scrolledWindow = gtk.ScrolledWindow()
scrolledWindow.add(viewport)
scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
label = gtk.Label(_("""
This is a temporary page used while the pieces tab gets built.
When operations are complete this will automatically become the
pieces tab.
"""))
label.set_alignment(0,0)
viewport.add(label)
self.parentNotebook.insert_page(scrolledWindow,gtk.Label(_("Pieces")),page)
scrolledWindow.show_all()
if switch_page:
self.parentNotebook.set_current_page(page)
self.tab_pieces.set_unique_id(unique_id) self.tab_pieces.set_unique_id(unique_id)
self.topWidget = self.tab_pieces.prepare_pieces_store() self.tab_pieces.prepare_pieces_store()
switch_page = False
if self.parentNotebook.get_current_page() == page:
switch_page = True
self.parentNotebook.remove_page(page)
self.parentNotebook = self.parent.notebook
self.parentNotebook.insert_page(self.topWidget, gtk.Label(_("Pieces")), page)
self.topWidget.show_all()
if switch_page:
self.parentNotebook.set_current_page(page)
self.tab_pieces.connect_handlers() self.tab_pieces.connect_handlers()
def ok_pressed(self, src):
self.dialog.hide()
needs_store_update = False
if self.config.get("columns") !=\
self.combo_columns.get_active()\
or self.config.get("font_size") !=\
self.combo_font_size.get_active():
needs_store_update = True
self.config.set("columns",
self.combo_columns.get_active())
self.config.set("font_size",
self.combo_font_size.get_active())
self.tab_pieces.set_columns(self.combo_columns.get_active())
self.tab_pieces.set_font_size(self.combo_font_size.get_active())
if needs_store_update:
self.tab_pieces.clear_pieces_store(clear_unique_id=False)
self.tab_pieces.prepare_pieces_store()
def cancel_pressed(self, src):
self.dialog.hide()

View file

@ -2,19 +2,22 @@ import gtk
import math import math
class PiecesTabManager(object): class PiecesTabManager(object):
def __init__(self, manager): def __init__(self, manager, viewport, columns, font_size):
self.vbox = None
self.manager = manager self.manager = manager
self.progress = [] self.viewport = viewport
self.tooltips = [] self.font_desc = None
self.eventboxes = [] self.set_font_size(font_size)
self.rows = 0 self.columns = columns
self.columns = 33 self.vbox = None
self.piece_width = 30 self.pieces = {}
self.piece_height = 20 self.labels = []
self.rows = []
self.pieces_block_info = {}
self.speed_symbols = {}
self.num_blocks = 0
self.last_num_blocks = 0
self.row = -1
self.unique_id = -1 self.unique_id = -1
self.peer_speed = []
self.piece_info = []
self.all_files = None self.all_files = None
self.file_priorities = None self.file_priorities = None
self.index = 0 self.index = 0
@ -29,54 +32,70 @@ class PiecesTabManager(object):
def set_unique_id(self, unique_id): def set_unique_id(self, unique_id):
self.unique_id = unique_id self.unique_id = unique_id
def clear_pieces_store(self): def clear_pieces_store(self, clear_unique_id=True):
self.unique_id = -1 self.pieces = {}
self.rows = 0 self.pieces_block_info = {}
self.peer_speed = [] self.speed_symbols = {}
self.eventboxes = [] self.labels = []
self.progress = [] self.rows = []
self.piece_info = [] self.row = -1
self.tooltips = [] if clear_unique_id:
self.unique_id = -1
self.all_files = None self.all_files = None
self.file_priorities = None self.file_priorities = None
self.current_first_index = None
self.current_last_index = None
self.index = 0 self.index = 0
self.num_files = 0
self.prev_file_index = -1 self.prev_file_index = -1
self.file_index = 0 self.file_index = 0
self.next_file_index = 1 self.next_file_index = 1
self.num_files = 0
self.current_first_index = None
self.current_last_index = None
if not self.vbox is None: if not self.vbox is None:
self.vbox.destroy() self.vbox.destroy()
self.vbox = None self.vbox = None
def set_columns(self, columns):
self.columns = columns
def set_font_size(self, font_size):
import pango
self.font_desc = pango.FontDescription('monospace %s' % font_size)
def prepare_pieces_store(self): def prepare_pieces_store(self):
gtk.main_iteration_do(False) gtk.main_iteration_do(False)
viewport = gtk.Viewport()
scrolledWindow = gtk.ScrolledWindow()
scrolledWindow.add(viewport)
scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.vbox = gtk.VBox() self.vbox = gtk.VBox()
viewport.add(self.vbox) self.viewport.add(self.vbox)
torrent_state = self.manager.get_torrent_state(self.unique_id)
if torrent_state['is_seed']:
label = gtk.Label(_("Torrent complete"))
label.set_alignment(0,0)
self.vbox.pack_start(label, expand=False)
self.vbox.show_all()
return
self.all_files = self.manager.get_file_piece_range(self.unique_id) self.all_files = self.manager.get_file_piece_range(self.unique_id)
self.num_blocks = self.all_files[0]['first_num_blocks']
self.last_num_blocks = self.all_files[len(self.all_files)-1]['last_num_blocks']
self.file_priorities = self.manager.get_priorities(self.unique_id) self.file_priorities = self.manager.get_priorities(self.unique_id)
state = self.manager.get_torrent_state(self.unique_id) state = self.manager.get_torrent_state(self.unique_id)
self.num_pieces = state["num_pieces"] self.num_pieces = state["num_pieces"]
for priority in self.file_priorities: for priority in self.file_priorities:
self.current_first_index = self.all_files[self.file_index]['first_index'] try:
self.current_last_index = self.all_files[self.file_index]['last_index'] self.current_first_index = self.all_files[self.file_index]['first_index']
if priority > 0: self.current_last_index = self.all_files[self.file_index]['last_index']
#if file is being downloaded build the file pieces information except:
self.build_file_pieces() print "length of all_files", len(self.all_files)
print "length of file_priorities", len(self.file_priorities)
print "file index", self.file_index
else: else:
#if file is not being downloaded skip the file pieces if priority > 0:
self.skip_current_file() #if file is being downloaded build the file pieces information
self.file_index += 1 self.build_file_pieces()
self.next_file_index += 1 self.file_index += 1
self.prev_file_index += 1 self.next_file_index += 1
self.prev_file_index += 1
self.get_current_pieces_info() self.get_current_pieces_info()
return scrolledWindow self.vbox.show_all()
return
def build_file_pieces(self): def build_file_pieces(self):
gtk.main_iteration_do(False) gtk.main_iteration_do(False)
@ -84,34 +103,20 @@ class PiecesTabManager(object):
label.set_alignment(0,0) label.set_alignment(0,0)
label.set_text(self.all_files[self.file_index]['path']) label.set_text(self.all_files[self.file_index]['path'])
self.vbox.pack_start(label, expand=False) self.vbox.pack_start(label, expand=False)
table = gtk.Table()
self.rows = int(math.ceil((self.current_last_index-self.current_first_index)/self.columns)+1)
self.vbox.pack_start(table, expand=False)
table.resize(self.rows, self.columns)
table.set_size_request((self.columns+1)*self.piece_width, (self.rows+1)*self.piece_height)
if self.current_last_index != self.current_first_index: if self.current_last_index != self.current_first_index:
#if there is more than one piece #if there is more than one piece
self.build_pieces_table(table) self.build_pieces_table()
only_one_piece = False self.vbox.pack_start(gtk.Label(), expand=False)
else: else:
#if file only has one piece #if file only has one piece
self.index = 0 self.index = 0
only_one_piece = True
self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0})
self.progress.append(gtk.ProgressBar())
self.tooltips.append(gtk.Tooltips())
self.eventboxes.append(gtk.EventBox())
self.peer_speed.append("unknown")
main_index = self.current_last_index main_index = self.current_last_index
if self.file_index > 0 and not self.piece_info[main_index] is None and only_one_piece: if self.file_index == 0 or not main_index in self.pieces:
#if file has only one piece and it is shared destroy the table
table.destroy()
if self.file_index == 0 or self.piece_info[main_index] is None or not only_one_piece:
# piece could be shared if file has only one piece and it's not the first file # piece could be shared if file has only one piece and it's not the first file
# only create it if it does not exist # only create it if it does not exist
self.build_last_file_piece(table, main_index, only_one_piece) self.build_last_file_piece(main_index)
def build_pieces_table(self, table): def build_pieces_table(self):
temp_prev_priority = 1 temp_prev_priority = 1
if self.file_index == 0\ if self.file_index == 0\
or self.current_first_index !=\ or self.current_first_index !=\
@ -131,175 +136,181 @@ class PiecesTabManager(object):
diff = 0 diff = 0
temp_range = self.current_last_index-self.current_first_index temp_range = self.current_last_index-self.current_first_index
#last piece handled outside of loop, skip it from range #last piece handled outside of loop, skip it from range
row_prev = 0
for index in xrange(temp_range): for index in xrange(temp_range):
gtk.main_iteration_do(False) gtk.main_iteration_do(False)
main_index = diff+self.current_first_index+index main_index = diff+self.current_first_index+index
if temp_prev_priority > 0:
#normal behavior
self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0})
self.progress.append(gtk.ProgressBar())
self.tooltips.append(gtk.Tooltips())
self.eventboxes.append(gtk.EventBox())
self.peer_speed.append("unknown")
else:
#if first piece is shared with a skipped file
self.share_skipped_piece(main_index)
temp_prev_priority = 1
self.progress[main_index].set_size_request(self.piece_width, self.piece_height)
row = index/self.columns row = index/self.columns
column = index%self.columns column = index%self.columns
table.attach(self.eventboxes[main_index], column, column+1, row, row+1, if row == 0 and column == 0:
xoptions=0, yoptions=0, xpadding=0, ypadding=0) self.row += 1
self.eventboxes[main_index].add(self.progress[main_index]) self.rows.append([])
self.labels.append(gtk.Label())
self.labels[row].set_alignment(0,0)
self.vbox.pack_start(self.labels[self.row], expand=False)
if row > row_prev:
self.row += 1
row_list = {}
self.rows.append([])
self.labels.append(gtk.Label())
self.labels[row].set_alignment(0,0)
self.vbox.pack_start(self.labels[self.row], expand=False)
percentage = " 0% "
self.pieces[main_index] = {'row':self.row, 'column':column}
self.pieces_block_info[main_index] = 0
self.speed_symbols[main_index] = " "
row_prev = row
if self.manager.has_piece(self.unique_id, main_index): if self.manager.has_piece(self.unique_id, main_index):
#if piece is already finished #if piece is already finished
self.progress[main_index].set_fraction(1) percentage = " 100% "
self.tooltips[main_index].set_tip(self.eventboxes[main_index], _("Piece finished")) self.pieces_block_info[main_index] = self.num_blocks
else: self.rows[self.row].append(percentage)
#if piece is not already finished self.labels[self.row].modify_font(self.font_desc)
self.tooltips[main_index].set_tip(self.eventboxes[main_index], _("Piece not started")) self.labels[self.row].set_text(str(self.rows[self.row]))
self.labels[self.row].set_alignment(0,0)
self.index = temp_range self.index = temp_range
def build_last_file_piece(self, table, main_index, only_one_piece): def build_last_file_piece(self, main_index):
gtk.main_iteration_do(False) gtk.main_iteration_do(False)
if only_one_piece and self.file_index > 0:
#if piece is shared with a skipped file
self.share_skipped_piece(main_index)
self.progress[main_index].set_size_request(self.piece_width, self.piece_height)
if self.next_file_index < len(self.all_files): if self.next_file_index < len(self.all_files):
# if there is another file # if there is another file
if self.file_priorities[self.next_file_index]==0\ if self.file_priorities[self.next_file_index]==0\
or self.current_last_index != self.all_files[self.next_file_index]['first_index']: or self.current_last_index != self.all_files[self.next_file_index]['first_index']:
#if next file is skipped or there is no shared piece, keep last piece #if next file is skipped or there is no shared piece, keep last piece
row=self.index/self.columns row = self.index/self.columns
column=self.index%self.columns column = self.index%self.columns
table.attach(self.eventboxes[main_index], column, column+1, row, row+1, if column == 0:
xoptions=0, yoptions=0, xpadding=0, ypadding=0) self.row += 1
self.eventboxes[main_index].add(self.progress[main_index]) self.labels.append(gtk.Label())
self.vbox.pack_start(self.labels[self.row], expand=False)
self.rows.append([])
self.pieces[main_index] = {'row':self.row, 'column':column}
if self.file_priorities[self.next_file_index]>0\ if self.file_priorities[self.next_file_index]>0\
and self.current_last_index == self.all_files[self.next_file_index]['first_index']: and self.current_last_index == self.all_files[self.next_file_index]['first_index']:
#if next file is not skipped and there is a shared piece, do not keep last piece #if next file is not skipped and there is a shared piece, do not keep last piece
if only_one_piece: self.row += 1
#only piece in file is shared, destroy table for file
table.destroy()
label = gtk.Label() label = gtk.Label()
label.set_alignment(0,0) label.set_alignment(0,0)
label.set_text(_("Piece shared with next file(s)")) label.set_text(_("Piece shared with next file(s)"))
self.vbox.pack_start(label, expand=False) self.vbox.pack_start(label, expand=False)
temp_table = gtk.Table() self.labels.append(gtk.Label())
temp_table.resize(1,2) self.vbox.pack_start(self.labels[self.row], expand=False)
temp_table.set_size_request(self.piece_width, 2*self.piece_height) self.vbox.pack_start(gtk.Label(), expand=False)
temp_table.attach(self.eventboxes[main_index], 0, 1, 0, 1, self.rows.append([])
xoptions=0, yoptions=0, xpadding=0, ypadding=0) self.pieces[main_index] = {'row':self.row, 'column':0}
self.eventboxes[main_index].add(self.progress[main_index])
self.vbox.pack_start(temp_table, expand=False)
else: else:
#if there is no other file #if there is no other file
row=self.index/self.columns row = self.index/self.columns
column=self.index%self.columns column = self.index%self.columns
table.attach(self.eventboxes[main_index], column, column+1, row, row+1, if column == 0:
xoptions=0, yoptions=0, xpadding=0, ypadding=0) self.row += 1
self.eventboxes[main_index].add(self.progress[main_index]) self.labels.append(gtk.Label())
self.rows.append([])
self.pieces[main_index] = {'row':self.row, 'column':column}
percentage = " 0% "
self.pieces_block_info[main_index] = 0
self.speed_symbols[main_index] = " "
if self.manager.has_piece(self.unique_id, main_index): if self.manager.has_piece(self.unique_id, main_index):
#if the last piece is already finished #if piece is already finished
self.progress[main_index].set_fraction(1) percentage = " 100% "
self.tooltips[main_index].set_tip(self.eventboxes[main_index], _("Piece finished")) self.pieces_block_info[main_index] = self.num_blocks
else: self.rows[self.row].append(percentage)
#if the last piece is not already finished self.labels[self.row].modify_font(self.font_desc)
self.tooltips[main_index].set_tip(self.eventboxes[main_index], _("Piece not started")) self.labels[self.row].set_text(str(self.rows[self.row]))
self.labels[self.row].set_alignment(0,0)
def share_skipped_piece(self, main_index):
self.piece_info[main_index] = {'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0}
self.progress[main_index] = gtk.ProgressBar()
self.tooltips[main_index] = gtk.Tooltips()
self.eventboxes[main_index] = gtk.EventBox()
self.peer_speed[main_index] = "unknown"
def skip_current_file(self):
if self.file_index == 0\
or self.current_first_index !=\
self.all_files[self.prev_file_index]['last_index']:
#if first piece is not shared
temp_range = 1+self.current_last_index-self.current_first_index
else:
#if first piece is shared
temp_range = self.current_last_index-self.current_first_index
for index in xrange(temp_range):
self.piece_info.append(None)
self.progress.append(None)
self.eventboxes.append(None)
self.tooltips.append(None)
self.peer_speed.append(None)
def connect_handlers(self): def connect_handlers(self):
self.handlers_connected = True self.handlers_connected = True
self.manager.connect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.handle_event) self.manager.connect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.handle_event)
self.manager.connect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.handle_event) self.manager.connect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.handle_event)
self.manager.connect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.handle_event) self.manager.connect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.handle_event)
self.manager.connect_event(self.manager.constants['EVENT_HASH_FAILED_ERROR'], self.handle_event)
def disconnect_handlers(self): def disconnect_handlers(self):
if self.handlers_connected: if self.handlers_connected:
self.manager.disconnect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.handle_event) self.manager.disconnect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.handle_event)
self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.handle_event) self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_FINISHED'], self.handle_event)
self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.handle_event) self.manager.disconnect_event(self.manager.constants['EVENT_BLOCK_DOWNLOADING'], self.handle_event)
self.manager.disconnect_event(self.manager.constants['EVENT_HASH_FAILED_ERROR'], self.handle_event)
self.handlers_connected = False self.handlers_connected = False
def handle_event(self, event): def handle_event(self, event):
#protect against pieces trying to display after file priority changed #protect against pieces trying to display after file priority changed
#or different torrent selected #or different torrent selected
if event['unique_ID'] == self.unique_id\ if event['unique_ID'] == self.unique_id\
and not self.piece_info[event['piece_index']] is None: and event['piece_index'] in self.pieces:
index = event['piece_index']
row = self.pieces[index]['row']
column = self.pieces[index]['column']
if event['event_type'] is self.manager.constants['EVENT_PIECE_FINISHED']: if event['event_type'] is self.manager.constants['EVENT_PIECE_FINISHED']:
self.update_pieces_store(event['piece_index'], piece_finished=True) self.rows[row][column] = " 100% "
if index == self.all_files[len(self.all_files)-1]['last_index']:
self.pieces_block_info[index] = self.last_num_blocks
else:
self.pieces_block_info[index] = self.num_blocks
self.labels[row].set_text(str(self.rows[row]))
elif event['event_type'] is self.manager.constants['EVENT_HASH_FAILED_ERROR']:
self.rows[row][column] = " 0% "
self.pieces_block_info[index] = 0
elif event['event_type'] is self.manager.constants['EVENT_BLOCK_DOWNLOADING']: elif event['event_type'] is self.manager.constants['EVENT_BLOCK_DOWNLOADING']:
index = event['piece_index'] if index == self.all_files[len(self.all_files)-1]['last_index']:
if self.piece_info[index]['blocks_total'] == 0: percentage = (100*self.pieces_block_info[index])/self.last_num_blocks
self.piece_info[index] = self.manager.get_piece_info(self.unique_id, index)
temp_peer_speed = event['peer_speed']
if temp_peer_speed == "fast":
peer_speed_msg = _("fast")
elif temp_peer_speed == "slow":
peer_speed_msg = _("slow")
elif temp_peer_speed == "medium":
peer_speed_msg = _("medium")
else: else:
peer_speed_msg = _("unknown") percentage = (100*self.pieces_block_info[index])/self.num_blocks
self.peer_speed[index] = peer_speed_msg # Pad accordingly
self.update_pieces_store(index) symbol = " "
else: if event['peer_speed'] == "fast":
index = event['piece_index'] symbol = "+"
if self.piece_info[index]['blocks_total'] == 0: elif event['peer_speed'] == "medium":
self.piece_info[index] = self.manager.get_piece_info(self.unique_id, index) symbol = "="
elif event['peer_speed'] == "slow":
symbol = "-"
percentage_label = " "
if percentage < 99:
if percentage <= 9:
percentage_label = " "
else:
percentage_label = " "
self.speed_symbols[index] = symbol
percentage_label = symbol + percentage_label + str(percentage) + "% "
self.rows[row][column] = percentage_label
self.labels[row].set_text(str(self.rows[row]))
else: # block finished
self.pieces_block_info[index] += 1
if index == self.all_files[len(self.all_files)-1]['last_index']:
percentage = (100*self.pieces_block_info[index])/self.last_num_blocks
else: else:
self.piece_info[index]['blocks_finished'] += 1 percentage = (100*self.pieces_block_info[index])/self.num_blocks
self.update_pieces_store(event['piece_index']) # Pad accordingly
percentage_label = " "
if percentage < 99:
if percentage <= 9:
percentage_label = " "
else:
percentage_label = " "
percentage_label = self.speed_symbols[index] + percentage_label + str(percentage) + "% "
self.rows[row][column] = percentage_label
self.labels[row].set_text(str(self.rows[row]))
def get_current_pieces_info(self): def get_current_pieces_info(self):
all_piece_info = self.manager.get_all_piece_info(self.unique_id) all_piece_info = self.manager.get_all_piece_info(self.unique_id)
for piece_index in all_piece_info: for info_index in xrange(len(all_piece_info)):
index = piece_index['piece_index'] index = all_piece_info[info_index]['piece_index']
if not self.piece_info[index] is None: if index in self.pieces:
temp_piece_info = {'blocks_total':piece_index['blocks_total'], \ row = self.pieces[index]['row']
'blocks_finished':piece_index['blocks_finished']} column = self.pieces[index]['column']
self.piece_info[index] = temp_piece_info if index == self.all_files[len(self.all_files)-1]['last_index']:
blocks_total = str(temp_piece_info['blocks_total']) percentage = (100*self.pieces_block_info[index])/self.last_num_blocks
info_string = str(temp_piece_info['blocks_finished']) + "/" + blocks_total + " " + _("blocks finished") + "\n" \ else:
+ _("peer speed: unknown") percentage = (100*self.pieces_block_info[index])/self.num_blocks
if self.progress[index].get_fraction() == 0: # Pad accordingly
self.progress[index].set_fraction(0.5) label = " "
self.tooltips[index].set_tip(self.eventboxes[index], info_string) if percentage < 99:
if percentage <= 9:
label = " "
else:
label = " "
label = label + str(percentage) + "% "
self.rows[row][column] = label
self.labels[row].set_text(str(self.rows[row]))
def update_pieces_store(self, index, piece_finished=False):
if piece_finished:
self.progress[index].set_fraction(1)
self.tooltips[index].set_tip(self.eventboxes[index], _("Piece finished"))
else:
temp_fraction = self.progress[index].get_fraction()
if temp_fraction == 0:
self.progress[index].set_fraction(0.5)
if temp_fraction != 1:
temp_piece_info = self.piece_info[index]
blocks_total = str(temp_piece_info['blocks_total'])
info_string = str(temp_piece_info['blocks_finished']) + "/" + blocks_total + " " + _("blocks finished") + "\n" \
+ _("peer speed: ") + self.peer_speed[index]
self.tooltips[index].set_tip(self.eventboxes[index], info_string)

View file

@ -1292,6 +1292,7 @@ static PyObject *torrent_get_file_piece_range(PyObject *self, PyObject *args)
torrent_info const &info = M_torrents->at(index).handle.get_torrent_info(); torrent_info const &info = M_torrents->at(index).handle.get_torrent_info();
int file_index = 0; int file_index = 0;
size_type first_num_blocks, last_num_blocks;
PyObject *file_info; PyObject *file_info;
for(torrent_info::file_iterator i = info.begin_files(); i != info.end_files(); ++i) for(torrent_info::file_iterator i = info.begin_files(); i != info.end_files(); ++i)
@ -1299,10 +1300,14 @@ static PyObject *torrent_get_file_piece_range(PyObject *self, PyObject *args)
file_entry const &currFile = (*i); file_entry const &currFile = (*i);
peer_request first_index = info.map_file(file_index, 0, 1); peer_request first_index = info.map_file(file_index, 0, 1);
peer_request last_index = info.map_file(file_index, currFile.size-1, 1); peer_request last_index = info.map_file(file_index, currFile.size-1, 1);
first_num_blocks = info.piece_length()/(16 * 1024);
last_num_blocks = ceil((double)(info.piece_size(last_index.piece))/(16 * 1024));
file_info = Py_BuildValue( file_info = Py_BuildValue(
"{s:i,s:i,s:s}", "{s:i,s:i,s:i,s:i,s:s}",
"first_index", first_index.piece, "first_index", first_index.piece,
"last_index", last_index.piece, "last_index", last_index.piece,
"first_num_blocks", (int)first_num_blocks,
"last_num_blocks", (int)last_num_blocks,
"path", currFile.path.string().c_str() "path", currFile.path.string().c_str()
); );
file_index++; file_index++;