Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DownloadState.get_ratio() #7853

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/tribler/core/components/libtorrent/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ def mock_lt_status():
lt_status.download_rate = 43
lt_status.total_upload = 100
lt_status.total_download = 200
lt_status.all_time_upload = 100
lt_status.total_payload_upload = 30
lt_status.total_payload_download = 100
lt_status.all_time_upload = 200
lt_status.all_time_download = 1000
lt_status.total_done = 200
lt_status.list_peers = 10
lt_status.download_payload_rate = 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from tribler.core.utilities.notifier import Notifier
from tribler.core.utilities.osutils import fix_filebasename
from tribler.core.utilities.path_util import Path
from tribler.core.utilities.simpledefs import DOWNLOAD, DownloadStatus
from tribler.core.utilities.simpledefs import DownloadStatus
from tribler.core.utilities.unicode import ensure_unicode, hexlify
from tribler.core.utilities.utilities import bdecode_compat, safe_repr

Expand Down Expand Up @@ -447,7 +447,7 @@ def on_torrent_finished_alert(self, alert: lt.torrent_finished_alert):
self._logger.info(f'On torrent finished alert: {safe_repr(alert)}')
self.update_lt_status(self.handle.status())
self.checkpoint()
downloaded = self.get_state().get_total_transferred(DOWNLOAD)
downloaded = self.get_state().total_download
if downloaded > 0 and self.stream is not None and self.notifier is not None:
name = self.tdef.get_name_as_unicode()
infohash = self.tdef.get_infohash().hex()
Expand All @@ -465,7 +465,7 @@ def _stop_if_finished(self):
seeding_ratio = self.download_defaults.seeding_ratio
seeding_time = self.download_defaults.seeding_time
if (mode == 'never' or
(mode == 'ratio' and state.get_seeding_ratio() >= seeding_ratio) or
(mode == 'ratio' and state.get_all_time_ratio() >= seeding_ratio) or
(mode == 'time' and state.get_seeding_time() >= seeding_time)):
self.stop()

Expand Down Expand Up @@ -510,7 +510,7 @@ def force_recheck(self):
self.handle.resume()
self.handle.force_recheck()

def get_state(self):
def get_state(self) -> DownloadState:
""" Returns a snapshot of the current state of the download
@return DownloadState
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
Author(s): Arno Bakker
"""
import logging
from typing import Optional

from tribler.core.components.libtorrent.utils.libtorrent_helper import libtorrent
from tribler.core.utilities.simpledefs import (
DownloadStatus, UPLOAD,
)
Expand All @@ -31,7 +33,7 @@ class DownloadState:
cf. libtorrent torrent_status
"""

def __init__(self, download, lt_status, error):
def __init__(self, download, lt_status: Optional[libtorrent.torrent_status], error):
"""
Internal constructor.
@param download The download this state belongs too.
Expand Down Expand Up @@ -97,21 +99,66 @@ def get_current_payload_speed(self, direct):
return self.lt_status.upload_payload_rate
return self.lt_status.download_payload_rate

def get_total_transferred(self, direct):
@property
def all_time_upload(self) -> int:
""" Returns accumulated upload payload byte counter.
It is saved in and restored from resume data to keep totals across sessions.
"""
Returns the total amount of up or downloaded bytes.
@return The amount in bytes.
if not self.lt_status:
return 0
return self.lt_status.all_time_upload

@property
def all_time_download(self) -> int:
""" Returns accumulated download payload byte counter.
It is saved in and restored from resume data to keep totals across sessions.
"""
if not self.lt_status:
return 0
return self.lt_status.all_time_download

@property
def total_upload(self) -> int:
""" Returns the number of bytes uploaded to all peers, accumulated, this session only
"""
if not self.lt_status:
return 0
return self.lt_status.total_upload

@property
def total_download(self) -> int:
""" Returns the number of bytes downloaded to all peers, accumulated, this session only
"""
if not self.lt_status:
return 0
elif direct == UPLOAD:
return self.lt_status.total_upload
return self.lt_status.total_download

def get_seeding_ratio(self):
if self.lt_status and self.lt_status.total_done > 0:
return self.lt_status.all_time_upload / float(self.lt_status.total_done)
return 0
@property
def total_payload_upload(self) -> int:
"""
Returns the amount of bytes send this session, but only the actual payload data.
@return The amount in bytes.
"""
if not self.lt_status:
return 0
return self.lt_status.total_payload_upload

@property
def total_payload_download(self) -> int:
"""
Returns the amount of bytes received this session, but only the actual payload data.
@return The amount in bytes.
"""
if not self.lt_status:
return 0
return self.lt_status.total_payload_download

def get_all_time_ratio(self) -> float:
""" Returns the accumulated seeding ratio of the download across multiple sessions.
"""
if not self.lt_status or not self.all_time_download:
return 0
return self.all_time_upload / self.all_time_download

def get_seeding_time(self):
return self.lt_status.finished_time if self.lt_status else 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from aiohttp import web
from aiohttp_apispec import docs, json_schema
from ipv8.REST.schema import schema
from ipv8.messaging.anonymization.tunnel import CIRCUIT_ID_PORT, PEER_FLAG_EXIT_BT
from ipv8.messaging.anonymization.tunnel import PEER_FLAG_EXIT_BT
from marshmallow.fields import Boolean, Float, Integer, List, String

from tribler.core.components.libtorrent.download_manager.download import Download, IllegalFileIndex
Expand Down Expand Up @@ -237,9 +237,9 @@ def get_files_info_json_paged(download: Download, view_start: Path, view_size: i
'eta': Integer,
'num_peers': Integer,
'num_seeds': Integer,
'total_up': Integer,
'total_down': Integer,
'ratio': Float,
'all_time_upload': Integer,
'all_time_download': Integer,
'all_time_ratio': Float,
'files': String,
'trackers': String,
'hops': Integer,
Expand Down Expand Up @@ -313,7 +313,6 @@ async def get_downloads(self, request):

download_status = get_extended_status(
self.tunnel_community, download) if self.tunnel_community else download.get_state().get_status()

download_json = {
"name": download_name,
"progress": state.get_progress(),
Expand All @@ -328,9 +327,9 @@ async def get_downloads(self, request):
"num_seeds": num_seeds,
"num_connected_peers": num_connected_peers,
"num_connected_seeds": num_connected_seeds,
"total_up": state.get_total_transferred(UPLOAD),
"total_down": state.get_total_transferred(DOWNLOAD),
"ratio": state.get_seeding_ratio(),
"all_time_upload": state.all_time_upload,
"all_time_download": state.all_time_download,
"all_time_ratio": state.get_all_time_ratio(),
"trackers": tracker_info,
"hops": download.config.get_hops(),
"anon_download": download.get_anon_mode(),
Expand Down Expand Up @@ -363,7 +362,6 @@ async def get_downloads(self, request):
if 'extended_version' in peer_info:
peer_info['extended_version'] = _safe_extended_peer_info(peer_info['extended_version'])


download_json["peers"] = peer_list

# Add piece information if requested
Expand Down Expand Up @@ -688,7 +686,6 @@ async def collapse_tree_directory(self, request):

return RESTResponse({'path': path})


@docs(
tags=["Libtorrent"],
summary="Expand a tree directory.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ def test_on_torrent_finished_alert(test_download: Download):
test_download.handle = Mock(is_valid=Mock(return_value=True))
test_download.notifier = MagicMock()
test_download.stream = Mock()
test_download.get_state = Mock(return_value=Mock(get_total_transferred=Mock(return_value=1)))
test_download.get_state = Mock(return_value=Mock(total_download=1))

test_download.on_torrent_finished_alert(Mock())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ def test_getters_setters_1(mock_download):
assert download_state.get_progress() == 0
assert download_state.get_error() is None
assert download_state.get_current_speed(UPLOAD) == 0
assert download_state.get_total_transferred(UPLOAD) == 0
assert download_state.total_upload == 0
assert download_state.total_download == 0
assert download_state.total_payload_download == 0
assert download_state.total_payload_upload == 0
assert download_state.all_time_upload == 0
assert download_state.all_time_download == 0
assert download_state.get_num_seeds_peers() == (0, 0)
assert download_state.get_peerlist() == []

Expand All @@ -48,9 +53,16 @@ def test_getters_setters_2(mock_download, mock_lt_status):
assert download_state.get_status() == DownloadStatus.DOWNLOADING
assert download_state.get_current_speed(UPLOAD) == 123
assert download_state.get_current_speed(DOWNLOAD) == 43
assert download_state.get_total_transferred(UPLOAD) == 100
assert download_state.get_total_transferred(DOWNLOAD) == 200
assert download_state.get_seeding_ratio() == 0.5
assert download_state.total_upload == 100
assert download_state.total_download == 200

assert download_state.total_payload_upload == 30
assert download_state.total_payload_download == 100

assert download_state.all_time_upload == 200
assert download_state.all_time_download == 1000
assert download_state.get_all_time_ratio() == 0.2

assert download_state.get_eta() == 0.25
assert download_state.get_num_seeds_peers() == (5, 5)
assert download_state.get_pieces_complete() == []
Expand Down
2 changes: 1 addition & 1 deletion src/tribler/gui/debug_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def on_ipv8_general_stats(self, data):
return
self.window().ipv8_general_tree_widget.clear()
for key, value in data["ipv8_statistics"].items():
if key in ('total_up', 'total_down'):
if key in ('total_upload', 'total_download'):
value = f"{value / (1024.0 * 1024.0):.2f} MB"
elif key == 'session_uptime':
value = f"{str(datetime.timedelta(seconds=int(value)))}"
Expand Down
18 changes: 9 additions & 9 deletions src/tribler/gui/qt_resources/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -3486,7 +3486,14 @@ margin-right: 10px;</string>
</property>
</widget>
</item>
<item row="9" column="0">
<item row="8" column="1">
<widget class="QLabel" name="download_detail_ratio_label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_26">
<property name="styleSheet">
<string notr="true">font-weight: bold;</string>
Expand All @@ -3496,20 +3503,13 @@ margin-right: 10px;</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="11" column="1">
<widget class="QLabel" name="download_detail_availability_label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="download_detail_ratio_label">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
Expand Down
9 changes: 5 additions & 4 deletions src/tribler/gui/widgets/downloadsdetailstabwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from tribler.core.utilities.simpledefs import DownloadStatus
from tribler.gui.defs import STATUS_STRING
from tribler.gui.network.request_manager import request_manager
from tribler.gui.utilities import compose_magnetlink, connect, copy_to_clipboard, format_size, format_speed, tr
from tribler.gui.widgets.torrentfiletreewidget import PreformattedTorrentFileTreeWidget

Expand Down Expand Up @@ -172,11 +171,13 @@ def update_pages(self, new_download=False):
)
self.window().download_detail_infohash_label.setText(self.current_download['infohash'])
self.window().download_detail_destination_label.setText(self.current_download["destination"])
up = format_size(self.current_download['total_up'])
down = format_size(self.current_download['total_down'])
all_time_upload = format_size(self.current_download['all_time_upload'])
all_time_download = format_size(self.current_download['all_time_download'])
all_time_ratio = self.current_download['all_time_ratio']
self.window().download_detail_ratio_label.setText(
f"{self.current_download['ratio']:.3f}, up: {up}, down: {down}"
f"{all_time_ratio:.3f}, upload: {all_time_upload}, download: {all_time_download}"
)

self.window().download_detail_availability_label.setText(f"{self.current_download['availability']:.2f}")

if new_download:
Expand Down
14 changes: 7 additions & 7 deletions src/tribler/gui/widgets/downloadspage.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ def __init__(self):
self.dialog = None
self.loading_message_widget: Optional[LoadingDownloadWidgetItem] = None
self.loading_list_item: Optional[LoadingListItem] = None
self.total_download = 0
self.total_upload = 0
self.total_download_speed = 0
self.total_upload_speed = 0

# Used to keep track of the last processed request with a purpose of ignoring old requests
self.last_processed_request_id = 0
Expand Down Expand Up @@ -203,8 +203,8 @@ def on_received_downloads(self, result):

self.downloads = result

self.total_download = 0
self.total_upload = 0
self.total_download_speed = 0
self.total_upload_speed = 0

download_infohashes = set()

Expand All @@ -223,8 +223,8 @@ def on_received_downloads(self, result):

item.update_with_download(download)

self.total_download += download["speed_down"]
self.total_upload += download["speed_up"]
self.total_download_speed += download["speed_down"]
self.total_upload_speed += download["speed_up"]

download_infohashes.add(download["infohash"])

Expand All @@ -246,7 +246,7 @@ def on_received_downloads(self, result):
del self.download_widgets[infohash]

self.window().tray_set_tooltip(
f"Down: {format_speed(self.total_download)}, Up: {format_speed(self.total_upload)}"
f"Down: {format_speed(self.total_download_speed)}, Up: {format_speed(self.total_upload_speed)}"
)
self.update_download_visibility()
self.refresh_top_panel()
Expand Down
2 changes: 1 addition & 1 deletion src/tribler/gui/widgets/downloadwidgetitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def update_item(self):
self.setText(5, f"{self.download_info['num_connected_peers']} ({self.download_info['num_peers']})")
self.setText(6, format_speed(self.download_info["speed_down"]))
self.setText(7, format_speed(self.download_info["speed_up"]))
self.setText(8, f"{float(self.download_info['ratio']):.3f}")
self.setText(8, f"{float(self.download_info['all_time_ratio']):.3f}")
self.setText(9, "yes" if self.download_info["anon_download"] else "no")
self.setText(10, str(self.download_info["hops"]) if self.download_info["anon_download"] else "-")
self.setText(12, datetime.fromtimestamp(int(self.download_info["time_added"])).strftime('%Y-%m-%d %H:%M'))
Expand Down
Loading