diff --git a/src/tribler/core/components/libtorrent/download_manager/download_state.py b/src/tribler/core/components/libtorrent/download_manager/download_state.py index ce4a4ece66d..ef0d83f21d1 100644 --- a/src/tribler/core/components/libtorrent/download_manager/download_state.py +++ b/src/tribler/core/components/libtorrent/download_manager/download_state.py @@ -4,6 +4,7 @@ Author(s): Arno Bakker """ import logging +import math from typing import Optional from tribler.core.components.libtorrent.utils.libtorrent_helper import libtorrent @@ -33,7 +34,7 @@ class DownloadState: cf. libtorrent torrent_status """ - def __init__(self, download, lt_status: Optional[libtorrent.torrent_status], error): + def __init__(self, download, lt_status: Optional[libtorrent.torrent_status], error: Optional = None): """ Internal constructor. @param download The download this state belongs too. @@ -156,8 +157,12 @@ def total_payload_download(self) -> int: 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: + if not self.lt_status: return 0 + + if not self.all_time_download: + return 0 if not self.all_time_upload else math.inf + return self.all_time_upload / self.all_time_download def get_seeding_time(self): diff --git a/src/tribler/core/components/libtorrent/tests/test_download_state.py b/src/tribler/core/components/libtorrent/tests/test_download_state.py index a96d9329592..5cd47198220 100644 --- a/src/tribler/core/components/libtorrent/tests/test_download_state.py +++ b/src/tribler/core/components/libtorrent/tests/test_download_state.py @@ -1,3 +1,4 @@ +import math from unittest.mock import Mock import pytest @@ -61,7 +62,6 @@ def test_getters_setters_2(mock_download, mock_lt_status): 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) @@ -79,6 +79,51 @@ def test_getters_setters_2(mock_download, mock_lt_status): assert download_state.get_progress() == 0.75 +def test_all_time_ratio_no_lt_status(): + # Test when lt_status is None + state = DownloadState( + download=Mock(), + lt_status=None, + ) + assert state.get_all_time_ratio() == 0 + + +def test_all_time_ratio(): + # Test all time ratio formula + state = DownloadState( + download=Mock(), + lt_status=Mock( + all_time_upload=200, + all_time_download=1000, + ), + ) + assert state.get_all_time_ratio() == 0.2 + + +def test_all_time_ratio_no_all_time_download(): + # Test all time ratio formula when all_time_download is 0 and all_time_upload is 0 + state = DownloadState( + download=Mock(), + lt_status=Mock( + all_time_upload=0, + all_time_download=0, + ), + ) + assert state.get_all_time_ratio() == 0 + + +def test_all_time_ratio_no_all_time_download_inf(): + # Test all time ratio formula when all_time_download is 0 and all_time_upload is not 0 + state = DownloadState( + download=Mock(), + lt_status=Mock( + all_time_upload=200, + all_time_download=0, + ), + ) + assert state.get_all_time_ratio() == math.inf + + def test_get_files_completion(mock_download, mock_tdef): """ Testing whether the right completion of files is returned diff --git a/src/tribler/gui/widgets/downloadsdetailstabwidget.py b/src/tribler/gui/widgets/downloadsdetailstabwidget.py index ad79de3026a..0e32d228a20 100644 --- a/src/tribler/gui/widgets/downloadsdetailstabwidget.py +++ b/src/tribler/gui/widgets/downloadsdetailstabwidget.py @@ -1,3 +1,4 @@ +import math import operator from enum import IntEnum from pathlib import PurePosixPath @@ -174,8 +175,9 @@ def update_pages(self, new_download=False): 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'] + all_time_ratio = '∞' if all_time_ratio == math.inf else f'{all_time_ratio:.3f}' self.window().download_detail_ratio_label.setText( - f"{all_time_ratio:.3f}, upload: {all_time_upload}, download: {all_time_download}" + f"{all_time_ratio}, upload: {all_time_upload}, download: {all_time_download}" ) self.window().download_detail_availability_label.setText(f"{self.current_download['availability']:.2f}") diff --git a/src/tribler/gui/widgets/downloadwidgetitem.py b/src/tribler/gui/widgets/downloadwidgetitem.py index ca40235ff00..35f861f9397 100644 --- a/src/tribler/gui/widgets/downloadwidgetitem.py +++ b/src/tribler/gui/widgets/downloadwidgetitem.py @@ -1,4 +1,5 @@ import logging +import math from datetime import datetime from typing import Dict, Optional @@ -96,7 +97,11 @@ 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['all_time_ratio']):.3f}") + + all_time_ratio = self.download_info['all_time_ratio'] + all_time_ratio = '∞' if all_time_ratio == math.inf else f'{all_time_ratio:.3f}' + self.setText(8, all_time_ratio) + 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'))