files tab and peers tab made into plugins - micah

This commit is contained in:
Marcos Pinto 2007-08-05 04:07:17 +00:00
parent bf695f9cfa
commit eff70a1c2c
16 changed files with 1244 additions and 1265 deletions

File diff suppressed because it is too large Load diff

View file

@ -52,7 +52,7 @@ def enable(core, interface):
### The Plugin ###
import deluge
import gtk
from EventLogging.tab_log import LogManager
from EventLogging.tab_log import LogTabManager
class EventLogging:
@ -86,8 +86,8 @@ class EventLogging:
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Event Log")))
self.viewport.show()
self.scrolledWindow.show()
self.tab_log = LogManager(self.viewport, self.manager)
self.tab_log.prepare_log_store()
self.tab_log = LogTabManager(self.viewport, self.manager)
self.tab_log.build_log_view()
if self.config.get("enable_finished"):
self.manager.connect_event(self.manager.constants['EVENT_FINISHED'], self.tab_log.handle_event)
if self.config.get("enable_peer_error"):

View file

@ -5,7 +5,7 @@ import time
CONFIG_DIR = xdg.BaseDirectory.save_config_path('deluge')
class LogManager(object):
class LogTabManager(object):
def __init__(self, viewport, manager):
self.log_files = False
self.viewport = viewport
@ -21,7 +21,7 @@ class LogManager(object):
self.vbox.destroy()
self.vbox = None
def prepare_log_store(self):
def build_log_view(self):
self.vbox = gtk.VBox()
self.viewport.add(self.vbox)
self.vbox.show_all()

View file

@ -8,8 +8,55 @@ def deluge_init(deluge_path):
global path
path = deluge_path
from NetworkGraph.plugin import plugin_NetGraph
def enable(core, interface):
global path
return plugin_NetGraph(path, core, interface)
return NetworkGraph(path, core, interface)
from NetworkGraph.tab_graph import GraphTabManager
class NetworkGraph:
def __init__(self, path, core, interface):
import gtk
self.parent = interface
self.location = path
self.manager = core
scrolledWindow = gtk.ScrolledWindow()
scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
image = gtk.Image()
viewport = gtk.Viewport()
viewport.add(image)
scrolledWindow.add(viewport)
image.show()
viewport.show()
self.topWidget = scrolledWindow
self.parentNotebook = self.parent.notebook
# print "Parent NOTEBOOK:", self.parentNotebook
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Graph")))
# print "My INDEX in parentNoteBook:", self.index
self.bootupRuns = 3 # This ensures that we pass the resizing phase, with scrollbars, etc.
# So the first time it is viewed, we are all ready
scrolledWindow.show()
import pango
pangoContext = self.parent.window.get_pango_context()
pangoLayout = pango.Layout(pangoContext)
self.tab_graph = GraphTabManager(scrolledWindow, image, pangoLayout, self.manager)
def unload(self): # Shutdown is called when the plugin is deactivated
numPages = self.parentNotebook.get_n_pages()
for page in range(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
self.parentNotebook.remove_page(page)
break
def update(self):
if (not self.parentNotebook.get_nth_page(self.parentNotebook.get_current_page()) == \
self.topWidget\
or not self.parent.update_interface)\
and not self.bootupRuns > 0:
return
self.bootupRuns = max(self.bootupRuns - 1, 0)
self.tab_graph.update_graph_store()
self.tab_graph.update_graph_view()

View file

@ -1,159 +0,0 @@
# netgraph plugin
class plugin_NetGraph:
def __init__(self, path, deluge_core, deluge_interface):
import gtk
self.parent = deluge_interface
self.location = path
self.core = deluge_core
self.image = gtk.Image()
self.viewPort = gtk.Viewport()
self.viewPort.add(self.image)
self.scrolledWindow = gtk.ScrolledWindow()
self.scrolledWindow.add(self.viewPort)
self.scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.topWidget = self.scrolledWindow
self.parentNotebook = self.parent.notebook
# print "Parent NOTEBOOK:", self.parentNotebook
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Graph")))
# print "My INDEX in parentNoteBook:", self.index
self.image.show()
self.viewPort.show()
self.scrolledWindow.show()
self.length = 60
self.width = -1
self.height = -1
import pango
self.pangoContext = self.parent.window.get_pango_context()
self.pangoLayout = pango.Layout(self.pangoContext)
self.savedUpSpeeds = []
self.savedDownSpeeds = []
self.bootupRuns = 3 # This ensures that we pass the resizing phase, with scrollbars, etc.
# So the first time it is viewed, we are all ready
def unload(self): # Shutdown is called when the plugin is deactivated
numPages = self.parentNotebook.get_n_pages()
for page in range(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
self.parentNotebook.remove_page(page)
break
def update(self):
if self.parent.update_interface:
import gtk
session_info = self.core.get_state()
self.savedUpSpeeds.insert(0, session_info['upload_rate'])
if len(self.savedUpSpeeds) > self.length:
self.savedUpSpeeds.pop()
self.savedDownSpeeds.insert(0, session_info['download_rate'])
if len(self.savedDownSpeeds) > self.length:
self.savedDownSpeeds.pop()
if not self.parentNotebook.get_nth_page(self.parentNotebook.get_current_page()) == \
self.topWidget and not self.bootupRuns > 0:
return
self.bootupRuns = max(self.bootupRuns - 1, 0)
extraWidth = self.scrolledWindow.get_vscrollbar().get_allocation().width * 1.5
extraHeight = self.scrolledWindow.get_hscrollbar().get_allocation().height * 1.5
allocation = self.scrolledWindow.get_allocation()
allocation.width = int(allocation.width) - extraWidth
allocation.height = int(allocation.height) - extraHeight
# Don't try to allocate a size too small, or you might crash
if allocation.width < 2 or allocation.height < 2:
return
# savedDownSpeeds = [1,2,3,2,1]
# savedUpSpeeds = [5,8,0,0,1,2]
# allocation = self.image.get_allocation()
# allocation.width = 300
# allocation.height = 200
if not allocation.width == self.width or not allocation.height == self.height:
# print "New Pixmap!"
self.width = allocation.width
self.height = allocation.height
self.networkPixmap = gtk.gdk.Pixmap(None, self.width,
self.height, gtk.gdk.visual_get_system().depth)
self.image.set_from_pixmap(self.networkPixmap, None)
self.ctx = self.networkPixmap.cairo_create()
self.networkPixmap.draw_rectangle(self.image.get_style().white_gc,True, 0, 0, self.width, self.height)
maxSpeed = max(max(self.savedDownSpeeds),max(self.savedUpSpeeds))
if maxSpeed == 0:
return
maxSpeed = maxSpeed*1.1 # Give some extra room on top
self.drawSpeedPoly(self.savedDownSpeeds, (0.5,1, 0.5, 1.0), maxSpeed, True)
self.drawSpeedPoly(self.savedDownSpeeds, (0, 0.75,0, 1.0), maxSpeed, False)
self.drawSpeedPoly(self.savedUpSpeeds, (0.33,0.33,1.0, 0.5), maxSpeed, True)
self.drawSpeedPoly(self.savedUpSpeeds, (0, 0, 1.0, 0.75), maxSpeed, False)
meanUpSpeed = sum(self.savedUpSpeeds) /len(self.savedUpSpeeds)
meanDownSpeed = sum(self.savedDownSpeeds)/len(self.savedDownSpeeds)
shownSpeed = max(meanUpSpeed, meanDownSpeed)
import deluge.common
self.pangoLayout.set_text(deluge.common.fspeed(shownSpeed))
self.networkPixmap.draw_layout(self.image.get_style().black_gc,
4,
int(self.height - 1 - (self.height*shownSpeed/maxSpeed)),
self.pangoLayout)
self.networkPixmap.draw_line(self.image.get_style().black_gc,
0,
int(self.height - (self.height*shownSpeed/maxSpeed)),
self.width,
int(self.height - (self.height*shownSpeed/maxSpeed)))
self.networkPixmap.draw_rectangle(self.image.get_style().black_gc,False, 0, 0, self.width-1, self.height-1)
self.image.queue_draw()
def tracePath(self, speeds, maxSpeed):
lineWidth = 4
self.ctx.set_line_width(lineWidth)
self.ctx.move_to(self.width + lineWidth,self.height + lineWidth)
self.ctx.line_to(self.width + lineWidth,int(self.height-(self.height*speeds[0]/maxSpeed)))
for i in range(len(speeds)):
self.ctx.line_to(int(self.width-1-((i*self.width)/(self.length-1))),
int(self.height-1-(self.height*speeds[i]/maxSpeed)))
self.ctx.line_to(int(self.width-1-(((len(speeds)-1)*self.width)/(self.length-1))),
int(self.height)-1 + lineWidth)
self.ctx.close_path()
def drawSpeedPoly(self, speeds, color, maxSpeed, fill):
self.tracePath(speeds, maxSpeed)
self.ctx.set_source_rgba(color[0],color[1],color[2], color[3])
if fill:
self.ctx.fill()
else:
self.ctx.stroke()

View file

@ -0,0 +1,85 @@
# Copyright (C) 2007
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
### Initialization ###
plugin_name = _("Torrent Files")
plugin_author = "Deluge"
plugin_version = "0.2"
plugin_description = _("""
This is just the files tab as a plugin.
""")
def deluge_init(deluge_path):
global path
path = deluge_path
def enable(core, interface):
global path
return TorrentFiles(path, core, interface)
### The Plugin ###
import deluge
import gtk
from TorrentFiles.tab_files import FilesTabManager
class TorrentFiles:
def __init__(self, path, core, interface):
print "Loading TorrentFiles plugin..."
self.manager = core
self.parent = interface
self.treeView = gtk.TreeView()
self.scrolledWindow = gtk.ScrolledWindow()
self.scrolledWindow.add(self.treeView)
self.scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.topWidget = self.scrolledWindow
self.parentNotebook = self.parent.notebook
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Files")))
self.treeView.show()
self.scrolledWindow.show()
self.tab_files = FilesTabManager(self.treeView, self.manager)
self.tab_files.build_file_view()
def unload(self):
self.tab_files.clear_file_store()
numPages = self.parentNotebook.get_n_pages()
for page in xrange(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
self.parentNotebook.remove_page(page)
break
def update(self):
if not self.parent.update_interface:
return
numPages = self.parentNotebook.get_n_pages()
for page in xrange(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
unique_id = self.parent.get_selected_torrent()
if unique_id is None:
#if no torrents added or more than one torrent selected
self.tab_files.clear_file_store()
return
if self.tab_files.file_unique_id != unique_id:
self.tab_files.clear_file_store()
self.tab_files.set_unique_id(unique_id)
self.tab_files.prepare_file_store()
else:
self.tab_files.update_file_store()
break

View file

@ -0,0 +1,68 @@
from itertools import izip
from deluge.files import FilesBaseManager
from deluge import dgtk
import gobject
import gtk
class FilesTabManager(FilesBaseManager):
def __init__(self, file_view, manager):
file_store = gtk.ListStore(str, gobject.TYPE_UINT64,
gobject.TYPE_UINT, float)
super(FilesTabManager, self).__init__(file_view, file_store)
self.manager = manager
self.file_unique_id = None
# Stores file path -> gtk.TreeIter's iter mapping for quick look up
# in self.update_file_store()
self.file_store_dict = {}
def build_file_view(self):
super(FilesTabManager, self).build_file_view()
def percent(column, cell, model, iter, data):
percent = float(model.get_value(iter, data))
percent_str = "%.2f%%"%percent
cell.set_property("text", percent_str)
dgtk.add_func_column(self.file_view, _("Progress"), percent, 3)
def set_unique_id(self, unique_id):
self.file_unique_id = unique_id
def priority_clicked(self, widget):
state = self.manager.get_torrent_state(self.file_unique_id)
if state["compact_mode"]:
self.compact_allocation_warning()
else:
super(FilesTabManager, self).priority_clicked(widget)
# From core to UI
def prepare_file_store(self):
if not self.file_store_dict:
all_files = self.manager.get_torrent_file_info(self.file_unique_id)
file_priorities = self.manager.get_priorities(self.file_unique_id)
for file, priority in izip(all_files, file_priorities):
iter = self.file_store.append([file['path'], file['size'],
priority, round(file['progress'], 2)])
self.file_store_dict[file['path']] = iter
# From core to UI
def update_file_store(self):
new_file_info = self.manager.get_torrent_file_info(self.file_unique_id)
for file in new_file_info:
iter = self.file_store_dict[file['path']]
dgtk.update_store(self.file_store, iter, (3,),
(round(file['progress'], 2),))
# From UI to core
def update_priorities(self):
prev_file_priorities = self.manager.get_priorities(self.file_unique_id)
file_priorities = []
update = False
for x, priority in izip(self.file_store, prev_file_priorities):
file_priorities.append(x[2])
if x[2] > 0 and priority == 0:
update = True
if x[2] == 0:
update = True
self.manager.prioritize_files(self.file_unique_id, file_priorities, update_files_removed=update)

View file

@ -0,0 +1,85 @@
# Copyright (C) 2007
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
### Initialization ###
plugin_name = _("Torrent Peers")
plugin_author = "Deluge"
plugin_version = "0.2"
plugin_description = _("""
This is just the peers tab as a plugin.
""")
def deluge_init(deluge_path):
global path
path = deluge_path
def enable(core, interface):
global path
return TorrentPeers(path, core, interface)
### The Plugin ###
import deluge
import gtk
from TorrentPeers.tab_peers import PeersTabManager
class TorrentPeers:
def __init__(self, path, core, interface):
print "Loading TorrentPeers plugin..."
self.manager = core
self.parent = interface
treeView = gtk.TreeView()
scrolledWindow = gtk.ScrolledWindow()
scrolledWindow.add(treeView)
scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.topWidget = scrolledWindow
self.parentNotebook = self.parent.notebook
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Peers")))
treeView.show()
scrolledWindow.show()
self.tab_peers = PeersTabManager(treeView, self.manager)
self.tab_peers.build_peers_view()
def unload(self):
self.tab_peers.clear_peer_store()
numPages = self.parentNotebook.get_n_pages()
for page in xrange(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
self.parentNotebook.remove_page(page)
break
def update(self):
if not self.parent.update_interface:
return
numPages = self.parentNotebook.get_n_pages()
for page in xrange(numPages):
if self.parentNotebook.get_nth_page(page) == self.topWidget:
unique_id = self.parent.get_selected_torrent()
if unique_id is None:
#if no torrents added or more than one torrent selected
self.tab_peers.clear_peer_store()
return
if self.tab_peers.peer_unique_id != unique_id:
self.tab_peers.clear_peer_store()
self.tab_peers.set_unique_id(unique_id)
self.tab_peers.update_peer_store()
else:
self.tab_peers.update_peer_store()
break

View file

@ -1,31 +1,30 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# tab_details.py
from itertools import izip
from deluge import dgtk
from deluge import common
import gobject
import gtk
import common
import dgtk
class PeersTabManager(object):
def __init__(self, peer_view, manager):
self.peer_view = peer_view
self.manager = manager
self.peer_unique_id = None
# IP int, IP string, Client, Percent Complete, Down Speed, Up Speed
# IP int is for faster sorting
self.peer_store = gtk.ListStore(gobject.TYPE_UINT, gtk.gdk.Pixbuf,
str, str, float, int, int)
# Stores IP -> gtk.TreeIter's iter mapping for quick look up
# in update_torrent_info_widget
self.peer_store_dict = {}
self.peer_store_dict = {}
self._cached_flags = {}
def clear_peer_store(self):
self.peer_store.clear()
self.peer_store_dict = {}
self.peer_unique_id = None
def set_unique_id(self, unique_id):
self.peer_unique_id = unique_id
def build_peers_view(self):
def percent(column, cell, model, iter, data):
percent = float(model.get_value(iter, data))
@ -44,11 +43,7 @@ class PeersTabManager(object):
dgtk.cell_data_speed, 5)
dgtk.add_func_column(self.peer_view, _("Up Speed"),
dgtk.cell_data_speed, 6)
def clear_store(self):
self.peer_store.clear()
self.peer_store_dict = {}
def get_country_flag_image(self, country):
flag_image = None
if country.isalpha():
@ -65,9 +60,9 @@ class PeersTabManager(object):
self._cached_flags[country] = flag_image
return flag_image
def update(self, unique_id):
new_peer_info = self.manager.get_torrent_peer_info(unique_id)
def update_peer_store(self):
new_peer_info = self.manager.get_torrent_peer_info(self.peer_unique_id)
new_ips = set()
for peer in new_peer_info:

View file

@ -50,7 +50,7 @@ def enable(core, interface):
### The Plugin ###
import deluge
import gtk
from TorrentPieces.tab_pieces import PiecesManager
from TorrentPieces.tab_pieces import PiecesTabManager
class TorrentPieces:
@ -66,7 +66,7 @@ class TorrentPieces:
self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Pieces")))
self.topWidget.show_all()
self.tab_pieces = PiecesManager(self.manager)
self.tab_pieces = PiecesTabManager(self.manager)
def unload(self):
self.manager.disconnect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.tab_pieces.handle_event)

View file

@ -1,7 +1,7 @@
import gtk
import math
class PiecesManager(object):
class PiecesTabManager(object):
def __init__(self, manager):
self.vbox = None
self.manager = manager
@ -15,8 +15,6 @@ class PiecesManager(object):
self.unique_id = -1
self.peer_speed = []
self.piece_info = []
self.first_indexes = []
self.last_indexes = []
self.all_files = None
self.file_priorities = None
self.index = 0
@ -24,6 +22,8 @@ class PiecesManager(object):
self.file_index = 0
self.next_file_index = 1
self.num_files = 0
self.current_first_index = None
self.current_last_index = None
def set_unique_id(self, unique_id):
self.unique_id = unique_id
@ -36,10 +36,10 @@ class PiecesManager(object):
self.progress = []
self.piece_info = []
self.tooltips = []
self.first_indexes = []
self.last_indexes = []
self.all_files = None
self.file_priorities = None
self.current_first_index = None
self.current_last_index = None
self.index = 0
self.num_files = 0
self.prev_file_index = -1
@ -57,16 +57,13 @@ class PiecesManager(object):
scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.vbox = gtk.VBox()
viewport.add(self.vbox)
self.all_files = self.manager.get_torrent_file_info(self.unique_id)
self.all_files = self.manager.get_file_piece_range(self.unique_id)
self.file_priorities = self.manager.get_priorities(self.unique_id)
state = self.manager.get_torrent_state(self.unique_id)
self.num_pieces = state["num_pieces"]
for priority in self.file_priorities:
if self.file_index == 0:
file_piece_range = self.manager.get_file_piece_range(self.unique_id,\
self.file_index, self.all_files[self.file_index]['size'])
self.first_indexes.append(file_piece_range['first_index'])
self.last_indexes.append(file_piece_range['last_index'])
self.current_first_index = self.all_files[self.file_index]['first_index']
self.current_last_index = self.all_files[self.file_index]['last_index']
if priority > 0:
#if file is being downloaded build the file pieces information
self.build_file_pieces()
@ -87,11 +84,11 @@ class PiecesManager(object):
label.set_text(self.all_files[self.file_index]['path'])
self.vbox.pack_start(label, expand=False)
table = gtk.Table()
self.rows = int(math.ceil((self.last_indexes[self.file_index]-self.first_indexes[self.file_index])/self.columns)+1)
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.last_indexes[self.file_index] != self.first_indexes[self.file_index]:
if self.current_last_index != self.current_first_index:
#if there is more than one piece
self.build_pieces_table(table)
only_one_piece = False
@ -99,14 +96,12 @@ class PiecesManager(object):
#if file only has one piece
self.index = 0
only_one_piece = True
main_index = self.last_indexes[self.file_index]
# do the following even if file has only one piece and that piece has already been created
if self.next_file_index < len(self.all_files):
#if there is another file
file_piece_range = self.manager.get_file_piece_range(self.unique_id,\
self.next_file_index, self.all_files[self.next_file_index]['size'])
self.first_indexes.append(file_piece_range['first_index'])
self.last_indexes.append(file_piece_range['last_index'])
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
if self.file_index > 0 and not self.piece_info[main_index] is None and only_one_piece:
#if file has only one piece and it is shared destroy the table
table.destroy()
@ -117,10 +112,11 @@ class PiecesManager(object):
def build_pieces_table(self, table):
temp_prev_priority = 1
if self.first_indexes[self.file_index] == 0\
or self.first_indexes[self.file_index] != self.last_indexes[self.prev_file_index]:
if self.current_first_index == 0\
or self.current_first_index !=\
self.all_files[self.prev_file_index]['last_index']:
#if first piece is not a shared piece
temp_range = self.last_indexes[self.file_index]-self.first_indexes[self.file_index]
temp_range = self.current_last_index-self.current_first_index
diff = 0
else:
#if first piece is shared
@ -128,15 +124,16 @@ class PiecesManager(object):
if temp_prev_priority > 0:
#if last file was not skipped, skip the first piece
diff = 1
temp_range = self.last_indexes[self.file_index]-(self.first_indexes[self.file_index]+1)
temp_range = self.current_last_index-(self.current_first_index+1)
#otherwise keep the first piece
else:
diff = 0
temp_range = self.last_indexes[self.file_index]-self.first_indexes[self.file_index]
temp_range = self.current_last_index-self.current_first_index
#last piece handled outside of loop, skip it from range
temp_first_index = self.current_first_index
for index in xrange(temp_range):
gtk.main_iteration_do(False)
main_index = diff+self.first_indexes[self.file_index]+index
main_index = diff+temp_first_index+index
if temp_prev_priority > 0:
#normal behavior
self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0})
@ -161,23 +158,18 @@ class PiecesManager(object):
else:
#if piece is not already finished
self.tooltips[main_index].set_tip(self.eventboxes[main_index], _("Piece not started"))
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")
self.index = index+1
self.index = temp_range
def build_last_file_piece(self, table, main_index, only_one_piece):
gtk.main_iteration_do(False)
if only_one_piece:
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 there is another file
if self.file_priorities[self.next_file_index]==0\
or self.last_indexes[self.file_index] != self.first_indexes[self.next_file_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
row=self.index/self.columns
column=self.index%self.columns
@ -185,7 +177,7 @@ class PiecesManager(object):
xoptions=0, yoptions=0, xpadding=0, ypadding=0)
self.eventboxes[main_index].add(self.progress[main_index])
if self.file_priorities[self.next_file_index]>0\
and self.last_indexes[self.file_index] == self.first_indexes[self.next_file_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 only_one_piece:
#only piece in file is shared, destroy table for file
@ -224,26 +216,20 @@ class PiecesManager(object):
self.peer_speed[main_index] = "unknown"
def skip_current_file(self):
if self.first_indexes[self.file_index] == 0 or self.first_indexes[self.file_index] != self.last_indexes[self.prev_file_index]:
if self.current_first_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.last_indexes[self.file_index]-self.first_indexes[self.file_index]
temp_range = 1+self.current_last_index-self.current_first_index
else:
#if first piece is shared
temp_range = self.last_indexes[self.file_index]-self.first_indexes[self.file_index]
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)
if self.next_file_index < len(self.all_files):
#if there is another file
file_piece_range = self.manager.get_file_piece_range(self.unique_id,\
self.next_file_index, self.all_files[self.next_file_index]['size'])
self.first_indexes.append(file_piece_range['first_index'])
self.last_indexes.append(file_piece_range['last_index'])
if self.last_indexes[self.next_file_index] >= self.num_pieces:
self.last_indexes[self.next_file_index] = self.num_pieces-1
def handle_event(self, event):
#protect against pieces trying to display after file priority changed

View file

@ -322,10 +322,8 @@ class Manager:
return self.config.get(key)
# Get file piece range
def get_file_piece_range(self, unique_id,\
file_index, file_size):
return deluge_core.get_file_piece_range(unique_id,\
file_index, file_size)
def get_file_piece_range(self, unique_id):
return deluge_core.get_file_piece_range(unique_id)
# Check if piece is finished
def has_piece(self, unique_id, piece_index):

View file

@ -1269,21 +1269,40 @@ static PyObject *torrent_get_file_info(PyObject *self, PyObject *args)
static PyObject *torrent_get_file_piece_range(PyObject *self, PyObject *args)
{
python_long unique_ID;
int file_index, file_size;
if (!PyArg_ParseTuple(args, "iii", &unique_ID, &file_index, &file_size))
if (!PyArg_ParseTuple(args, "i", &unique_ID))
return NULL;
long index = get_index_from_unique_ID(unique_ID);
if (PyErr_Occurred())
return NULL;
std::vector<PyObject *> temp_files;
torrent_info const &info = M_torrents->at(index).handle.get_torrent_info();
peer_request first_index = info.map_file(file_index, 0, 1);
peer_request last_index = info.map_file(file_index, file_size-1, 1);
return Py_BuildValue(
"{s:i,s:i}",
"first_index", first_index.piece,
"last_index", last_index.piece
);
int file_index = 0;
PyObject *file_info;
for(torrent_info::file_iterator i = info.begin_files(); i != info.end_files(); ++i)
{
file_entry const &currFile = (*i);
peer_request first_index = info.map_file(file_index, 0, 1);
peer_request last_index = info.map_file(file_index, currFile.size-1, 1);
file_info = Py_BuildValue(
"{s:i,s:i,s:s}",
"first_index", first_index.piece,
"last_index", last_index.piece,
"path", currFile.path.string().c_str()
);
file_index++;
temp_files.push_back(file_info);
};
PyObject *ret = PyTuple_New(temp_files.size());
for (unsigned long i = 0; i < temp_files.size(); i++)
PyTuple_SetItem(ret, i, temp_files[i]);
return ret;
};
/*static PyObject *torrent_get_unique_IDs(PyObject *self, PyObject *args)

View file

@ -34,7 +34,7 @@ import gtk
import common
import dgtk
import tab_files
import files
import pref
PREFS_FILENAME = "prefs.state"
@ -284,7 +284,7 @@ class FilesDlg:
self.dialog = self.glade.get_widget("file_dialog")
self.dialog.set_icon_from_file(common.get_pixmap("deluge32.png"))
self.files_manager = tab_files.FilesDialogManager(
self.files_manager = files.FilesDialogManager(
self.glade.get_widget("file_view"),
dumped_torrent)
self.files_manager.build_file_view()

View file

@ -137,70 +137,6 @@ class FilesBaseManager(object):
def update_priorities(self):
pass
class FilesTabManager(FilesBaseManager):
def __init__(self, file_view, manager):
file_store = gtk.ListStore(str, gobject.TYPE_UINT64,
gobject.TYPE_UINT, float)
super(FilesTabManager, self).__init__(file_view, file_store)
self.manager = manager
self.file_unique_id = None
# Stores file path -> gtk.TreeIter's iter mapping for quick look up
# in self.update_file_store()
self.file_store_dict = {}
def build_file_view(self):
super(FilesTabManager, self).build_file_view()
def percent(column, cell, model, iter, data):
percent = float(model.get_value(iter, data))
percent_str = "%.2f%%"%percent
cell.set_property("text", percent_str)
dgtk.add_func_column(self.file_view, _("Progress"), percent, 3)
def set_unique_id(self, unique_id):
self.file_unique_id = unique_id
def priority_clicked(self, widget):
state = self.manager.get_torrent_state(self.file_unique_id)
if state["compact_mode"]:
self.compact_allocation_warning()
else:
super(FilesTabManager, self).priority_clicked(widget)
# From core to UI
def prepare_file_store(self):
if not self.file_store_dict:
all_files = self.manager.get_torrent_file_info(self.file_unique_id)
file_priorities = self.manager.get_priorities(self.file_unique_id)
for file, priority in izip(all_files, file_priorities):
iter = self.file_store.append([file['path'], file['size'],
priority, round(file['progress'], 2)])
self.file_store_dict[file['path']] = iter
# From core to UI
def update_file_store(self):
new_file_info = self.manager.get_torrent_file_info(self.file_unique_id)
for file in new_file_info:
iter = self.file_store_dict[file['path']]
dgtk.update_store(self.file_store, iter, (3,),
(round(file['progress'], 2),))
# From UI to core
def update_priorities(self):
prev_file_priorities = self.manager.get_priorities(self.file_unique_id)
file_priorities = []
update = False
for x, priority in izip(self.file_store, prev_file_priorities):
file_priorities.append(x[2])
if x[2] > 0 and priority == 0:
update = True
if x[2] == 0:
update = True
self.manager.prioritize_files(self.file_unique_id, file_priorities, update_files_removed=update)
class FilesDialogManager(FilesBaseManager):
def __init__(self, file_view, dumped_torrent):
file_store = gtk.ListStore(str, gobject.TYPE_UINT64,

View file

@ -47,8 +47,7 @@ import dgtk
import ipc_manager
import plugins
import tab_details
import tab_files
import tab_peers
import files
class DelugeGTK:
def __init__(self):
@ -81,12 +80,6 @@ class DelugeGTK:
# Tabs
self.tab_details = tab_details.DetailsTabManager(self.wtree,
self.manager)
self.tab_peers = tab_peers.PeersTabManager(
self.wtree.get_widget("peer_view"), self.manager)
self.tab_peers.build_peers_view()
self.tab_files = tab_files.FilesTabManager(
self.wtree.get_widget("file_view"), self.manager)
self.tab_files.build_file_view()
self.statusbar = self.wtree.get_widget("statusbar")
@ -579,9 +572,6 @@ class DelugeGTK:
# Torrent is already selected, we don't need to do anything
return True
self.tab_peers.clear_store()
self.tab_files.clear_file_store()
unique_id = model.get_value(model.get_iter(path), 0)
self.update_torrent_info_widget(unique_id)
@ -982,14 +972,6 @@ class DelugeGTK:
if page_num == 0: # Details
self.tab_details.update(unique_id)
elif page_num == 1: # Peers
self.tab_peers.update(unique_id)
elif page_num == 2: # Files
# Fill self.file_store with files only once and only when we click to
# Files tab or it's already open
self.tab_files.set_unique_id(unique_id)
self.tab_files.prepare_file_store()
self.tab_files.update_file_store()
# Return the id of the last single selected torrent
def get_selected_torrent(self):
@ -1152,8 +1134,6 @@ class DelugeGTK:
def clear_details_pane(self):
self.tab_details.clear()
self.tab_peers.clear_store()
self.tab_files.clear_file_store()
def remove_toggle_warning(self, args, warning):
if not args.get_active():