Skip to content

Commit

Permalink
Merge pull request #7319 from drew2a/fix/7318
Browse files Browse the repository at this point in the history
Fix GUI downloads status update
  • Loading branch information
drew2a authored Mar 14, 2023
2 parents 1fa206f + 504eb18 commit af701fe
Show file tree
Hide file tree
Showing 24 changed files with 253 additions and 276 deletions.
18 changes: 9 additions & 9 deletions doc/restapi/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,23 @@ Download states
There are various download states possible which are returned when fetching downloads. These states are explained in the table below.

+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_ALLOCATING_DISKSPACE | Libtorrent is allocating disk space for the download |
| ALLOCATING_DISKSPACE | Libtorrent is allocating disk space for the download |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_WAITING4HASHCHECK | The download is waiting for the hash check to be performed |
| WAITING_FOR_HASHCHECK | The download is waiting for the hash check to be performed |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_HASHCHECKING | Libtorrent is checking the hashes of the download |
| HASHCHECKING | Libtorrent is checking the hashes of the download |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_DOWNLOADING | The torrent is being downloaded |
| DOWNLOADING | The torrent is being downloaded |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_SEEDING | The torrent has been downloaded and is now being seeded to other peers |
| SEEDING | The torrent has been downloaded and is now being seeded to other peers |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_STOPPED | The torrent has stopped downloading, either because the downloading has completed or the user has stopped the download |
| STOPPED | The torrent has stopped downloading, either because the downloading has completed or the user has stopped the download |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_STOPPED_ON_ERROR | The torrent has stopped because an error occurred |
| STOPPED_ON_ERROR | The torrent has stopped because an error occurred |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_METADATA | The torrent information is being fetched from the DHT |
| METADATA | The torrent information is being fetched from the DHT |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+
| DLSTATUS_CIRCUITS | The (anonymous) download is building circuits |
| CIRCUITS | The (anonymous) download is building circuits |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------+

Endpoints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from pathlib import Path

from ipv8.taskmanager import TaskManager, task

from pony.orm import db_session

from tribler.core import notifications
Expand All @@ -15,7 +14,7 @@
from tribler.core.components.metadata_store.db.store import MetadataStore
from tribler.core.utilities.notifier import Notifier
from tribler.core.utilities.pony_utils import run_threaded
from tribler.core.utilities.simpledefs import DLSTATUS_SEEDING, NTFY
from tribler.core.utilities.simpledefs import DownloadStatus
from tribler.core.utilities.unicode import hexlify

PROCESS_CHANNEL_DIR = 1
Expand All @@ -30,11 +29,11 @@ class GigaChannelManager(TaskManager):
"""

def __init__(
self,
state_dir: Path = None,
metadata_store: MetadataStore = None,
notifier: Notifier = None,
download_manager: DownloadManager = None,
self,
state_dir: Path = None,
metadata_store: MetadataStore = None,
notifier: Notifier = None,
download_manager: DownloadManager = None,
):
super().__init__()
self.notifier = notifier
Expand Down Expand Up @@ -108,7 +107,7 @@ async def regenerate_channel_torrent(self, channel_pk, channel_id):

async def check_and_regen_personal_channel_torrent(self, channel_pk, channel_id, channel_download, timeout=60):
try:
await wait_for(channel_download.wait_for_status(DLSTATUS_SEEDING), timeout=timeout)
await wait_for(channel_download.wait_for_status(DownloadStatus.SEEDING), timeout=timeout)
except asyncio.TimeoutError:
self._logger.warning("Time out waiting for personal channel %s %i to seed", hexlify(channel_pk), channel_id)
await self.regenerate_channel_torrent(channel_pk, channel_id)
Expand Down Expand Up @@ -189,20 +188,19 @@ def check_channels_updates(self):

for channel in channels:
try:
if self.download_manager.metainfo_requests.get(bytes(channel.infohash)):
infohash = bytes(channel.infohash)
if self.download_manager.metainfo_requests.get(infohash):
continue
if not self.download_manager.download_exists(bytes(channel.infohash)):
status = self.download_manager.get_download(infohash).get_state().get_status()
if not self.download_manager.download_exists(infohash):
self._logger.info(
"Downloading new channel version %s ver %i->%i",
channel.dirname,
channel.local_version,
channel.timestamp,
)
self.download_channel(channel)
elif (
self.download_manager.get_download(bytes(channel.infohash)).get_state().get_status()
== DLSTATUS_SEEDING
):
elif status == DownloadStatus.SEEDING:
self._logger.info(
"Processing previously downloaded, but unprocessed channel torrent %s ver %i->%i",
channel.dirname,
Expand Down Expand Up @@ -301,9 +299,9 @@ def updated_my_channel(self, tdef):
with db_session:
my_channel = self.mds.ChannelMetadata.get(infohash=tdef.get_infohash())
if (
my_channel
and my_channel.status == COMMITTED
and not self.download_manager.download_exists(bytes(my_channel.infohash))
my_channel
and my_channel.status == COMMITTED
and not self.download_manager.download_exists(bytes(my_channel.infohash))
):
dcfg = DownloadConfig(state_dir=self.state_dir)
dcfg.set_dest_dir(self.mds.channels_dir)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from tribler.core.components.metadata_store.db.orm_bindings.channel_node import NEW
from tribler.core.tests.tools.base_test import MockObject
from tribler.core.tests.tools.common import TORRENT_UBUNTU_FILE
from tribler.core.utilities.simpledefs import DLSTATUS_SEEDING
from tribler.core.utilities.simpledefs import DownloadStatus
from tribler.core.utilities.utilities import random_infohash

update_metainfo = None
Expand Down Expand Up @@ -204,7 +204,7 @@ def fake_get_metainfo(infohash, **_):
gigachannel_manager.download_manager.download_exists = lambda _: True

mock_download = MagicMock()
mock_download.get_state.get_status = DLSTATUS_SEEDING
mock_download.get_state.get_status = DownloadStatus.SEEDING

gigachannel_manager.download_manager.get_download = lambda _: mock_download

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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 DLSTATUS_SEEDING, DLSTATUS_STOPPED, DOWNLOAD
from tribler.core.utilities.simpledefs import DOWNLOAD, DownloadStatus
from tribler.core.utilities.unicode import ensure_unicode, hexlify
from tribler.core.utilities.utilities import bdecode_compat

Expand Down Expand Up @@ -436,7 +436,7 @@ def update_lt_status(self, lt_status: lt.torrent_status):

def _stop_if_finished(self):
state = self.get_state()
if state.get_status() == DLSTATUS_SEEDING:
if state.get_status() == DownloadStatus.SEEDING:
mode = self.download_defaults.seeding_mode
seeding_ratio = self.download_defaults.seeding_ratio
seeding_time = self.download_defaults.seeding_time
Expand Down Expand Up @@ -475,7 +475,7 @@ def move_storage(self, new_dir: Path):
@check_handle()
def force_recheck(self):
if not isinstance(self.tdef, TorrentDefNoMetainfo):
if self.get_state().get_status() == DLSTATUS_STOPPED:
if self.get_state().get_status() == DownloadStatus.STOPPED:
self.pause_after_next_hashcheck = True
self.checkpoint_after_next_hashcheck = True
self.handle.resume()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
scheme_from_url,
url_to_path,
)
from tribler.core.utilities.simpledefs import DLSTATUS_SEEDING, MAX_LIBTORRENT_RATE_LIMIT, STATEDIR_CHECKPOINT_DIR
from tribler.core.utilities.simpledefs import MAX_LIBTORRENT_RATE_LIMIT, STATEDIR_CHECKPOINT_DIR, \
DownloadStatus
from tribler.core.utilities.unicode import hexlify
from tribler.core.utilities.utilities import bdecode_compat, has_bep33_support, parse_magnetlink
from tribler.core.version import version_id
Expand Down Expand Up @@ -104,7 +105,7 @@ def __init__(self,
self.set_upload_rate_limit(0)
self.set_download_rate_limit(0)

self.downloads = {}
self.downloads: Dict[bytes, Download] = {}

self.checkpoints_count = None
self.checkpoints_loaded = 0
Expand Down Expand Up @@ -742,10 +743,10 @@ async def remove_download(self, download, remove_content=False, remove_checkpoin
else:
self._logger.debug("Cannot remove unknown download")

def get_download(self, infohash):
def get_download(self, infohash: bytes) -> Download:
return self.downloads.get(infohash, None)

def get_downloads(self):
def get_downloads(self) -> List[Download]:
return list(self.downloads.values())

def get_channel_downloads(self):
Expand Down Expand Up @@ -838,7 +839,7 @@ async def sesscb_states_callback(self, states_list):
download = ds.get_download()
infohash = download.get_def().get_infohash()

if ds.get_status() == DLSTATUS_SEEDING:
if ds.get_status() == DownloadStatus.SEEDING:
if download.config.get_hops() == 0 and download.config.get_safe_seeding():
# Re-add the download with anonymity enabled
hops = self.download_defaults.number_hops
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,20 @@
import logging

from tribler.core.utilities.simpledefs import (
DLSTATUS_ALLOCATING_DISKSPACE,
DLSTATUS_DOWNLOADING,
DLSTATUS_HASHCHECKING,
DLSTATUS_METADATA,
DLSTATUS_SEEDING,
DLSTATUS_STOPPED,
DLSTATUS_STOPPED_ON_ERROR,
DLSTATUS_WAITING4HASHCHECK,
UPLOAD,
DownloadStatus, UPLOAD,
)

# Map used to convert libtorrent -> Tribler download status
DLSTATUS_MAP = [DLSTATUS_WAITING4HASHCHECK,
DLSTATUS_HASHCHECKING,
DLSTATUS_METADATA,
DLSTATUS_DOWNLOADING,
DLSTATUS_SEEDING,
DLSTATUS_SEEDING,
DLSTATUS_ALLOCATING_DISKSPACE,
DLSTATUS_HASHCHECKING]
DOWNLOAD_STATUS_MAP = [
DownloadStatus.WAITING_FOR_HASHCHECK,
DownloadStatus.HASHCHECKING,
DownloadStatus.METADATA,
DownloadStatus.DOWNLOADING,
DownloadStatus.SEEDING,
DownloadStatus.SEEDING,
DownloadStatus.ALLOCATING_DISKSPACE,
DownloadStatus.HASHCHECKING,
]


class DownloadState:
Expand Down Expand Up @@ -56,27 +50,27 @@ def get_download(self):

def get_progress(self):
""" The general progress of the Download as a percentage. When status is
* DLSTATUS_HASHCHECKING it is the percentage of already downloaded
* HASHCHECKING it is the percentage of already downloaded
content checked for integrity.
* DLSTATUS_DOWNLOADING/SEEDING it is the percentage downloaded.
* DOWNLOADING/SEEDING it is the percentage downloaded.
@return Progress as a float (0..1).
"""
return self.lt_status.progress if self.lt_status else 0

def get_status(self):
def get_status(self) -> DownloadStatus:
""" Returns the status of the torrent.
@return DLSTATUS_* """
@return DownloadStatus* """

if self.lt_status:
if self.lt_status.paused:
return DLSTATUS_STOPPED
return DLSTATUS_MAP[self.lt_status.state]
return DownloadStatus.STOPPED
return DOWNLOAD_STATUS_MAP[self.lt_status.state]
if self.get_error():
return DLSTATUS_STOPPED_ON_ERROR
return DLSTATUS_STOPPED
return DownloadStatus.STOPPED_ON_ERROR
return DownloadStatus.STOPPED

def get_error(self):
""" Returns the Exception that caused the download to be moved to DLSTATUS_STOPPED_ON_ERROR status.
""" Returns the Exception that caused the download to be moved to STOPPED_ON_ERROR status.
@return An error message
"""
return self.error or (self.lt_status.error if self.lt_status and self.lt_status.error else None)
Expand All @@ -86,9 +80,9 @@ def get_current_speed(self, direct):
Returns the current up or download speed.
@return The speed in bytes/s.
"""
if not self.lt_status or self.get_status() not in [DLSTATUS_DOWNLOADING, DLSTATUS_SEEDING]:
if not self.lt_status or self.get_status() not in [DownloadStatus.DOWNLOADING, DownloadStatus.SEEDING]:
return 0
elif direct == UPLOAD:
if direct == UPLOAD:
return self.lt_status.upload_rate
return self.lt_status.download_rate

Expand All @@ -97,9 +91,9 @@ def get_current_payload_speed(self, direct):
Returns the current up or download payload speed.
@return The speed in bytes/s.
"""
if not self.lt_status or self.get_status() not in [DLSTATUS_DOWNLOADING, DLSTATUS_SEEDING]:
if not self.lt_status or self.get_status() not in [DownloadStatus.DOWNLOADING, DownloadStatus.SEEDING]:
return 0
elif direct == UPLOAD:
if direct == UPLOAD:
return self.lt_status.upload_payload_rate
return self.lt_status.download_payload_rate

Expand Down Expand Up @@ -136,7 +130,7 @@ def get_num_seeds_peers(self):
Returns the sum of the number of seeds and peers.
@return A tuple (num seeds, num peers)
"""
if not self.lt_status or self.get_status() not in [DLSTATUS_DOWNLOADING, DLSTATUS_SEEDING]:
if not self.lt_status or self.get_status() not in [DownloadStatus.DOWNLOADING, DownloadStatus.SEEDING]:
return 0, 0

total = self.lt_status.list_peers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from asyncio import sleep

from tribler.core.components.libtorrent.utils.torrent_utils import check_vod, get_info_from_handle
from tribler.core.utilities.simpledefs import DLSTATUS_DOWNLOADING, DLSTATUS_SEEDING
from tribler.core.utilities.simpledefs import DownloadStatus

# Header and footer sizes are necessary for video client to detect file codecs and muxer metadata.
# Without below pieces are ready, streamer should not start
Expand Down Expand Up @@ -140,7 +140,7 @@ async def enable(self, fileindex=0, prebufpos=None):
# wait until dlstate is downloading or seeding
while True:
status = self.__lt_state().get_status()
if status in [DLSTATUS_DOWNLOADING, DLSTATUS_SEEDING]:
if status in [DownloadStatus.DOWNLOADING, DownloadStatus.SEEDING]:
break
await sleep(1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@
from tribler.core.components.restapi.rest.util import return_handled_exception
from tribler.core.utilities.path_util import Path
from tribler.core.utilities.simpledefs import (
DLSTATUS_CIRCUITS,
DLSTATUS_EXIT_NODES,
DLSTATUS_STOPPED,
DOWNLOAD,
UPLOAD,
dlstatus_strings,
DownloadStatus, UPLOAD,
)
from tribler.core.utilities.unicode import ensure_unicode, hexlify
from tribler.core.utilities.utilities import froze_it
Expand Down Expand Up @@ -57,25 +53,25 @@ def _safe_extended_peer_info(ext_peer_info):
return ''.join([chr(c) for c in ext_peer_info])


def get_extended_status(tunnel_community, download):
def get_extended_status(tunnel_community, download) -> DownloadStatus:
"""
This function filters the original download status to possibly add tunnel-related status.
Extracted from DownloadState to remove coupling between DownloadState and Tunnels.
"""
state = download.get_state()
dlstatus = state.get_status()
status = state.get_status()

# Nothing to do with tunnels. If stopped - it happened by the user or libtorrent-only reason
stopped_by_user = state.lt_status and state.lt_status.paused

if dlstatus is DLSTATUS_STOPPED and not stopped_by_user:
if status == DownloadStatus.STOPPED and not stopped_by_user:
if download.config.get_hops() > 0:
if tunnel_community.get_candidates(PEER_FLAG_EXIT_BT):
return DLSTATUS_CIRCUITS
return DownloadStatus.CIRCUITS
else:
return DLSTATUS_EXIT_NODES
return DLSTATUS_STOPPED
return dlstatus
return DownloadStatus.EXIT_NODES
return DownloadStatus.STOPPED
return status


@froze_it
Expand Down Expand Up @@ -192,6 +188,7 @@ def get_files_info_json(download):
'speed_down': Float,
'speed_up': Float,
'status': String,
'status_code': Integer,
'size': Integer,
'eta': Integer,
'num_peers': Integer,
Expand Down Expand Up @@ -282,7 +279,8 @@ async def get_downloads(self, request):
"infohash": hexlify(tdef.get_infohash()),
"speed_down": state.get_current_payload_speed(DOWNLOAD),
"speed_up": state.get_current_payload_speed(UPLOAD),
"status": dlstatus_strings[download_status],
"status": download_status.name,
"status_code": download_status.value,
"size": tdef.get_length(),
"eta": state.get_eta(),
"num_peers": num_peers,
Expand Down
Loading

0 comments on commit af701fe

Please sign in to comment.