Added TorrentDetails component to GtkUI, but it is currently not
optimized. Added more status fields to Torrent.
This commit is contained in:
parent
0d12b1e0cf
commit
be5855dcd6
|
@ -66,23 +66,6 @@ def get_default_plugin_dir():
|
|||
|
||||
## Formatting text functions
|
||||
|
||||
def estimate_eta(total_size, total_done, download_rate):
|
||||
"""Returns a string with the estimated ETA and will return 'Unlimited'
|
||||
if the torrent is complete
|
||||
"""
|
||||
try:
|
||||
return ftime(get_eta(total_size, total_done, download_rate))
|
||||
except ZeroDivisionError:
|
||||
return "Infinity"
|
||||
|
||||
def get_eta(size, done, speed):
|
||||
"""Returns the ETA in seconds
|
||||
Will raise an exception if the torrent is completed
|
||||
"""
|
||||
if (size - done) == 0:
|
||||
raise ZeroDivisionError
|
||||
return (size - done) / speed
|
||||
|
||||
def fsize(fsize_b):
|
||||
"""Returns formatted string describing filesize
|
||||
fsize_b should be in bytes
|
||||
|
@ -105,16 +88,14 @@ def fspeed(bps):
|
|||
"""Returns a formatted string representing transfer speed"""
|
||||
return '%s/s' % (fsize(bps))
|
||||
|
||||
def fseed(num_seeds, total_seeds):
|
||||
"""Returns a formatted string num_seeds (total_seeds)"""
|
||||
return str(str(num_seeds) + " (" + str(total_seeds) + ")")
|
||||
|
||||
def fpeer(num_peers, total_peers):
|
||||
"""Returns a formatted string num_peers (total_peers)"""
|
||||
return str(str(num_peers) + " (" + str(total_peers) + ")")
|
||||
|
||||
def ftime(seconds):
|
||||
"""Returns a formatted time string"""
|
||||
if seconds is 0:
|
||||
return "Infinity"
|
||||
if seconds < 60:
|
||||
return '%ds' % (seconds)
|
||||
minutes = int(seconds/60)
|
||||
|
|
|
@ -43,6 +43,8 @@ class Torrent:
|
|||
self.handle = handle
|
||||
# Set the torrent_id for this torrent
|
||||
self.torrent_id = str(handle.info_hash())
|
||||
# This is for saving the total uploaded between sessions
|
||||
self.total_uploaded = 0
|
||||
|
||||
def get_state(self):
|
||||
"""Returns the state of this torrent for saving to the session state"""
|
||||
|
@ -62,7 +64,23 @@ class Torrent:
|
|||
eta = 0
|
||||
|
||||
return eta
|
||||
|
||||
|
||||
def get_ratio(self):
|
||||
"""Returns the ratio for this torrent"""
|
||||
up = self.total_uploaded + self.handle.status().total_payload_upload
|
||||
down = self.handle.status().total_done
|
||||
|
||||
# Convert 'up' and 'down' to floats for proper calculation
|
||||
up = float(up)
|
||||
down = float(down)
|
||||
|
||||
try:
|
||||
ratio = up / down
|
||||
except ZeroDivisionError:
|
||||
return 0.0
|
||||
|
||||
return ratio
|
||||
|
||||
def get_status(self, keys):
|
||||
"""Returns the status of the torrent based on the keys provided"""
|
||||
# Create the full dictionary
|
||||
|
@ -70,11 +88,27 @@ class Torrent:
|
|||
|
||||
# Adjust progress to be 0-100 value
|
||||
progress = status.progress*100
|
||||
|
||||
|
||||
# Get the total number of seeds and peers
|
||||
if status.num_complete is -1:
|
||||
total_seeds = status.num_seeds
|
||||
else:
|
||||
total_seeds = status.num_complete
|
||||
|
||||
if status.num_incomplete is -1:
|
||||
total_peers = status.num_peers - status.num_seeds
|
||||
else:
|
||||
total_peers = status.num_incomplete
|
||||
|
||||
full_status = {
|
||||
"name": self.handle.torrent_info().name(),
|
||||
"total_size": self.handle.torrent_info().total_size(),
|
||||
"num_pieces": self.handle.status().num_pieces,
|
||||
"num_files": self.handle.torrent_info().num_files(),
|
||||
"num_pieces": self.handle.torrent_info().num_pieces(),
|
||||
"piece_length": self.handle.torrent_info().piece_length(),
|
||||
"distributed_copies": status.distributed_copies,
|
||||
"total_done": status.total_done,
|
||||
"total_uploaded": self.total_uploaded + status.total_payload_upload,
|
||||
"state": int(status.state),
|
||||
"paused": status.paused,
|
||||
"progress": progress,
|
||||
|
@ -83,11 +117,14 @@ class Torrent:
|
|||
"total_payload_upload": status.total_payload_upload,
|
||||
"download_payload_rate": status.download_payload_rate,
|
||||
"upload_payload_rate": status.upload_payload_rate,
|
||||
"num_peers": status.num_peers,
|
||||
"num_peers": status.num_peers - status.num_seeds,
|
||||
"num_seeds": status.num_seeds,
|
||||
"total_peers": total_peers,
|
||||
"total_seeds": total_seeds,
|
||||
"total_wanted": status.total_wanted,
|
||||
"eta": self.get_eta(),
|
||||
"ratio": 0.0
|
||||
"ratio": self.get_ratio(),
|
||||
"tracker": status.current_tracker
|
||||
}
|
||||
|
||||
# Create the desired status dictionary and return it
|
||||
|
|
|
@ -40,6 +40,7 @@ import pkg_resources
|
|||
from menubar import MenuBar
|
||||
from toolbar import ToolBar
|
||||
from torrentview import TorrentView
|
||||
from torrentdetails import TorrentDetails
|
||||
|
||||
from deluge.log import LOG as log
|
||||
|
||||
|
@ -56,11 +57,13 @@ class MainWindow:
|
|||
self.menubar = MenuBar(self)
|
||||
self.toolbar = ToolBar(self)
|
||||
self.torrentview = TorrentView(self)
|
||||
self.torrentdetails = TorrentDetails(self)
|
||||
|
||||
gobject.timeout_add(1000, self.update)
|
||||
|
||||
def update(self):
|
||||
self.torrentview.update()
|
||||
self.torrentdetails.update()
|
||||
return True
|
||||
|
||||
def show(self):
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#
|
||||
# torrentdetails.py
|
||||
#
|
||||
# Copyright (C) 2007 Andrew Resch ('andar') <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 2 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.
|
||||
|
||||
"""The torrent details component shows info about the selected torrent."""
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk, gtk.glade
|
||||
import gettext
|
||||
|
||||
import deluge.ui.functions as functions
|
||||
import deluge.common
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class TorrentDetails:
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
glade = self.window.main_glade
|
||||
|
||||
self.core = functions.get_core()
|
||||
|
||||
self.notebook = glade.get_widget("torrent_info")
|
||||
self.details_tab = glade.get_widget("torrentdetails_tab")
|
||||
|
||||
# Get the labels we need to update.
|
||||
self.progress_bar = glade.get_widget("progressbar")
|
||||
self.name = glade.get_widget("summary_name")
|
||||
self.total_size = glade.get_widget("summary_total_size")
|
||||
self.num_files = glade.get_widget("summary_num_files")
|
||||
self.pieces = glade.get_widget("summary_pieces")
|
||||
self.availability = glade.get_widget("summary_availability")
|
||||
self.total_downloaded = glade.get_widget("summary_total_downloaded")
|
||||
self.total_uploaded = glade.get_widget("summary_total_uploaded")
|
||||
self.download_speed = glade.get_widget("summary_download_speed")
|
||||
self.upload_speed = glade.get_widget("summary_upload_speed")
|
||||
self.seeders = glade.get_widget("summary_seeders")
|
||||
self.peers = glade.get_widget("summary_peers")
|
||||
self.percentage_done = glade.get_widget("summary_percentage_done")
|
||||
self.share_ratio = glade.get_widget("summary_share_ratio")
|
||||
self.tracker = glade.get_widget("summary_tracker")
|
||||
self.tracker_status = glade.get_widget("summary_tracker_status")
|
||||
self.next_announce = glade.get_widget("summary_next_announce")
|
||||
self.eta = glade.get_widget("summary_eta")
|
||||
|
||||
def update(self):
|
||||
# Only update if this page is showing
|
||||
if self.notebook.page_num(self.details_tab) is \
|
||||
self.notebook.get_current_page():
|
||||
# Get the first selected torrent
|
||||
selected = self.window.torrentview.get_selected_torrents()
|
||||
|
||||
# Only use the first torrent in the list or return if None selected
|
||||
if selected is not None:
|
||||
selected = selected[0]
|
||||
else:
|
||||
# No torrent is selected in the torrentview
|
||||
return
|
||||
|
||||
# Get the torrent status
|
||||
status_keys = ["progress", "name", "total_size", "num_files",
|
||||
"num_pieces", "piece_length", "distributed_copies",
|
||||
"total_done", "total_payload_download", "total_uploaded",
|
||||
"total_payload_upload", "download_payload_rate",
|
||||
"upload_payload_rate", "num_peers", "num_seeds", "total_peers",
|
||||
"total_seeds", "eta", "ratio", "tracker", "next_announce"]
|
||||
status = functions.get_torrent_status(self.core,
|
||||
selected,
|
||||
status_keys)
|
||||
|
||||
# We need to adjust the value core gives us for progress
|
||||
progress = status["progress"]/100
|
||||
self.progress_bar.set_fraction(progress)
|
||||
self.progress_bar.set_text(deluge.common.fpcnt(progress))
|
||||
|
||||
self.name.set_text(status["name"])
|
||||
self.total_size.set_text(deluge.common.fsize(status["total_size"]))
|
||||
self.num_files.set_text(str(status["num_files"]))
|
||||
self.pieces.set_text("%s (%s)" % (status["num_pieces"],
|
||||
deluge.common.fsize(status["piece_length"])))
|
||||
self.availability.set_text("%.3f" % status["distributed_copies"])
|
||||
self.total_downloaded.set_text("%s (%s)" % \
|
||||
(deluge.common.fsize(status["total_done"]),
|
||||
deluge.common.fsize(status["total_payload_download"])))
|
||||
self.total_uploaded.set_text("%s (%s)" % \
|
||||
(deluge.common.fsize(status["total_uploaded"]),
|
||||
deluge.common.fsize(status["total_payload_upload"])))
|
||||
self.download_speed.set_text(
|
||||
deluge.common.fspeed(status["download_payload_rate"]))
|
||||
self.upload_speed.set_text(
|
||||
deluge.common.fspeed(status["upload_payload_rate"]))
|
||||
self.seeders.set_text(deluge.common.fpeer(status["num_seeds"],
|
||||
status["total_seeds"]))
|
||||
self.peers.set_text(deluge.common.fpeer(status["num_peers"],
|
||||
status["total_peers"]))
|
||||
self.eta.set_text(deluge.common.ftime(status["eta"]))
|
||||
self.share_ratio.set_text("%.3f" % status["ratio"])
|
||||
self.tracker.set_text(status["tracker"])
|
||||
self.next_announce.set_text(
|
||||
deluge.common.ftime(status["next_announce"]))
|
||||
|
|
@ -63,11 +63,13 @@ class TorrentView(listview.ListView):
|
|||
self.add_func_column("Seeders",
|
||||
listview.cell_data_peer,
|
||||
[int, int],
|
||||
status_field=["num_seeds", "num_seeds"])
|
||||
status_field=["num_seeds",
|
||||
"total_seeds"])
|
||||
self.add_func_column("Peers",
|
||||
listview.cell_data_peer,
|
||||
[int, int],
|
||||
status_field=["num_peers", "num_peers"])
|
||||
status_field=["num_peers",
|
||||
"total_peers"])
|
||||
self.add_func_column("Down Speed",
|
||||
listview.cell_data_speed,
|
||||
[float],
|
||||
|
@ -201,6 +203,11 @@ class TorrentView(listview.ListView):
|
|||
torrent_ids.append(
|
||||
self.liststore.get_value(
|
||||
self.liststore.get_iter(path), 0))
|
||||
|
||||
if len(torrent_ids) is 0:
|
||||
# Only return a list if there is something in it.
|
||||
return None
|
||||
|
||||
return torrent_ids
|
||||
except ValueError:
|
||||
return None
|
||||
|
|
Loading…
Reference in New Issue