From a9213627a9ebe38cc02200244c43df7b121e10a8 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Fri, 30 May 2025 08:34:26 +0300 Subject: [PATCH] Interpret tracker "updating" status as a separate property PR #22787. --- src/base/bittorrent/torrentimpl.cpp | 90 ++++++++++--------- src/base/bittorrent/trackerentrystatus.h | 5 +- src/gui/trackerlist/trackerlistmodel.cpp | 53 ++++++----- .../trackersfilterwidget.cpp | 3 - src/webui/api/torrentscontroller.cpp | 2 + .../www/private/scripts/prop-trackers.js | 35 ++++---- 6 files changed, 104 insertions(+), 84 deletions(-) diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 773d544be..ca1a7cac4 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -152,35 +152,40 @@ namespace if (ltAnnounceInfo.updating) { - trackerEndpointStatus.state = TrackerEndpointState::Updating; + trackerEndpointStatus.isUpdating = true; ++numUpdating; } - else if (ltAnnounceInfo.fails > 0) - { - if (ltAnnounceInfo.last_error == lt::errors::tracker_failure) - { - trackerEndpointStatus.state = TrackerEndpointState::TrackerError; - ++numTrackerError; - } - else if (ltAnnounceInfo.last_error == lt::errors::announce_skipped) - { - trackerEndpointStatus.state = TrackerEndpointState::Unreachable; - ++numUnreachable; - } - else - { - trackerEndpointStatus.state = TrackerEndpointState::NotWorking; - ++numNotWorking; - } - } - else if (nativeEntry.verified) - { - trackerEndpointStatus.state = TrackerEndpointState::Working; - ++numWorking; - } else { - trackerEndpointStatus.state = TrackerEndpointState::NotContacted; + trackerEndpointStatus.isUpdating = false; + + if (ltAnnounceInfo.fails > 0) + { + if (ltAnnounceInfo.last_error == lt::errors::tracker_failure) + { + trackerEndpointStatus.state = TrackerEndpointState::TrackerError; + ++numTrackerError; + } + else if (ltAnnounceInfo.last_error == lt::errors::announce_skipped) + { + trackerEndpointStatus.state = TrackerEndpointState::Unreachable; + ++numUnreachable; + } + else + { + trackerEndpointStatus.state = TrackerEndpointState::NotWorking; + ++numNotWorking; + } + } + else if (nativeEntry.verified) + { + trackerEndpointStatus.state = TrackerEndpointState::Working; + ++numWorking; + } + else + { + trackerEndpointStatus.state = TrackerEndpointState::NotContacted; + } } if (!ltAnnounceInfo.message.empty()) @@ -215,23 +220,28 @@ namespace { if (numUpdating > 0) { - trackerEntryStatus.state = TrackerEndpointState::Updating; + trackerEntryStatus.isUpdating = true; } - else if (numWorking > 0) + else { - trackerEntryStatus.state = TrackerEndpointState::Working; - } - else if (numTrackerError > 0) - { - trackerEntryStatus.state = TrackerEndpointState::TrackerError; - } - else if (numUnreachable == numEndpoints) - { - trackerEntryStatus.state = TrackerEndpointState::Unreachable; - } - else if ((numUnreachable + numNotWorking) == numEndpoints) - { - trackerEntryStatus.state = TrackerEndpointState::NotWorking; + trackerEntryStatus.isUpdating = false; + + if (numWorking > 0) + { + trackerEntryStatus.state = TrackerEndpointState::Working; + } + else if (numTrackerError > 0) + { + trackerEntryStatus.state = TrackerEndpointState::TrackerError; + } + else if (numUnreachable == numEndpoints) + { + trackerEntryStatus.state = TrackerEndpointState::Unreachable; + } + else if ((numUnreachable + numNotWorking) == numEndpoints) + { + trackerEntryStatus.state = TrackerEndpointState::NotWorking; + } } } diff --git a/src/base/bittorrent/trackerentrystatus.h b/src/base/bittorrent/trackerentrystatus.h index fa5998a58..026580623 100644 --- a/src/base/bittorrent/trackerentrystatus.h +++ b/src/base/bittorrent/trackerentrystatus.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2024 Vladimir Golovnev + * Copyright (C) 2015-2025 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -41,7 +41,6 @@ namespace BitTorrent { NotContacted = 1, Working = 2, - Updating = 3, NotWorking = 4, TrackerError = 5, Unreachable = 6 @@ -52,6 +51,7 @@ namespace BitTorrent QString name {}; int btVersion = 1; + bool isUpdating = false; TrackerEndpointState state = TrackerEndpointState::NotContacted; QString message {}; @@ -69,6 +69,7 @@ namespace BitTorrent QString url {}; int tier = 0; + bool isUpdating = false; TrackerEndpointState state = TrackerEndpointState::NotContacted; QString message {}; diff --git a/src/gui/trackerlist/trackerlistmodel.cpp b/src/gui/trackerlist/trackerlistmodel.cpp index 4c90e0a6a..684bef069 100644 --- a/src/gui/trackerlist/trackerlistmodel.cpp +++ b/src/gui/trackerlist/trackerlistmodel.cpp @@ -73,26 +73,6 @@ namespace return (val > -1) ? QString::number(val) : TrackerListModel::tr("N/A"); } - QString toString(const BitTorrent::TrackerEndpointState state) - { - switch (state) - { - case BitTorrent::TrackerEndpointState::Working: - return TrackerListModel::tr(STR_WORKING); - case BitTorrent::TrackerEndpointState::Updating: - return TrackerListModel::tr("Updating..."); - case BitTorrent::TrackerEndpointState::NotWorking: - return TrackerListModel::tr("Not working"); - case BitTorrent::TrackerEndpointState::TrackerError: - return TrackerListModel::tr("Tracker error"); - case BitTorrent::TrackerEndpointState::Unreachable: - return TrackerListModel::tr("Unreachable"); - case BitTorrent::TrackerEndpointState::NotContacted: - return TrackerListModel::tr("Not contacted yet"); - } - return TrackerListModel::tr("Invalid state!"); - } - QString statusDHT(const BitTorrent::Torrent *torrent) { if (!torrent->session()->isDHTEnabled()) @@ -137,6 +117,7 @@ struct TrackerListModel::Item final QString name {}; int tier = -1; int btVersion = -1; + bool isUpdating = false; BitTorrent::TrackerEndpointState status = BitTorrent::TrackerEndpointState::NotContacted; QString message {}; @@ -169,6 +150,8 @@ struct TrackerListModel::Item final void fillFrom(const BitTorrent::TrackerEntryStatus &trackerEntryStatus); void fillFrom(const BitTorrent::TrackerEndpointStatus &endpointStatus); + + QString statusText() const; }; class TrackerListModel::Items final : public multi_index_container< @@ -205,6 +188,7 @@ void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEntryStatus &trac Q_ASSERT(trackerEntryStatus.url == name); tier = trackerEntryStatus.tier; + isUpdating = trackerEntryStatus.isUpdating; status = trackerEntryStatus.state; message = trackerEntryStatus.message; numPeers = trackerEntryStatus.numPeers; @@ -224,6 +208,7 @@ void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEndpointStatus &e Q_ASSERT(endpointStatus.name == name); Q_ASSERT(endpointStatus.btVersion == btVersion); + isUpdating = endpointStatus.isUpdating; status = endpointStatus.state; message = endpointStatus.message; numPeers = endpointStatus.numPeers; @@ -237,6 +222,28 @@ void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEndpointStatus &e announceTimestamp = {}; } +QString TrackerListModel::Item::statusText() const +{ + if (isUpdating) + return TrackerListModel::tr("Updating..."); + + switch (status) + { + case BitTorrent::TrackerEndpointState::Working: + return TrackerListModel::tr(STR_WORKING); + case BitTorrent::TrackerEndpointState::NotWorking: + return TrackerListModel::tr("Not working"); + case BitTorrent::TrackerEndpointState::TrackerError: + return TrackerListModel::tr("Tracker error"); + case BitTorrent::TrackerEndpointState::Unreachable: + return TrackerListModel::tr("Unreachable"); + case BitTorrent::TrackerEndpointState::NotContacted: + return TrackerListModel::tr("Not contacted yet"); + } + + return TrackerListModel::tr("Invalid state!"); +} + TrackerListModel::TrackerListModel(BitTorrent::Session *btSession, QObject *parent) : QAbstractItemModel(parent) , m_btSession {btSession} @@ -596,14 +603,14 @@ QVariant TrackerListModel::data(const QModelIndex &index, const int role) const return isEndpoint ? (u'v' + QString::number(itemPtr->btVersion)) : QString(); case COL_STATUS: if (isEndpoint) - return toString(itemPtr->status); + return itemPtr->statusText(); if (index.row() == ROW_DHT) return statusDHT(m_torrent); if (index.row() == ROW_PEX) return statusPeX(m_torrent); if (index.row() == ROW_LSD) return statusLSD(m_torrent); - return toString(itemPtr->status); + return itemPtr->statusText(); case COL_PEERS: return prettyCount(itemPtr->numPeers); case COL_SEEDS: @@ -632,7 +639,7 @@ QVariant TrackerListModel::data(const QModelIndex &index, const int role) const case COL_PROTOCOL: return isEndpoint ? itemPtr->btVersion : -1; case COL_STATUS: - return toString(itemPtr->status); + return itemPtr->statusText(); case COL_PEERS: return itemPtr->numPeers; case COL_SEEDS: diff --git a/src/gui/transferlistfilters/trackersfilterwidget.cpp b/src/gui/transferlistfilters/trackersfilterwidget.cpp index 60f8a08b8..894c1b578 100644 --- a/src/gui/transferlistfilters/trackersfilterwidget.cpp +++ b/src/gui/transferlistfilters/trackersfilterwidget.cpp @@ -463,9 +463,6 @@ void TrackersFilterWidget::handleTrackerStatusesUpdated(const BitTorrent::Torren trackerErrorHashesIt->remove(trackerEntryStatus.url); } break; - - case BitTorrent::TrackerEndpointState::Updating: - break; }; } diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 83459a892..3e18f6e30 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -64,6 +64,7 @@ // Tracker keys const QString KEY_TRACKER_URL = u"url"_s; +const QString KEY_TRACKER_UPDATING = u"updating"_s; const QString KEY_TRACKER_STATUS = u"status"_s; const QString KEY_TRACKER_TIER = u"tier"_s; const QString KEY_TRACKER_MSG = u"msg"_s; @@ -265,6 +266,7 @@ namespace { {KEY_TRACKER_URL, tracker.url}, {KEY_TRACKER_TIER, tracker.tier}, + {KEY_TRACKER_UPDATING, tracker.isUpdating}, {KEY_TRACKER_STATUS, static_cast((isNotWorking ? BitTorrent::TrackerEndpointState::NotWorking : tracker.state))}, {KEY_TRACKER_MSG, tracker.message}, {KEY_TRACKER_PEERS_COUNT, tracker.numPeers}, diff --git a/src/webui/www/private/scripts/prop-trackers.js b/src/webui/www/private/scripts/prop-trackers.js index b95bef5e7..5261a7db2 100644 --- a/src/webui/www/private/scripts/prop-trackers.js +++ b/src/webui/www/private/scripts/prop-trackers.js @@ -81,22 +81,25 @@ window.qBittorrent.PropTrackers ??= (() => { trackers.each((tracker) => { let status; - switch (tracker.status) { - case 0: - status = "QBT_TR(Disabled)QBT_TR[CONTEXT=TrackerListWidget]"; - break; - case 1: - status = "QBT_TR(Not contacted yet)QBT_TR[CONTEXT=TrackerListWidget]"; - break; - case 2: - status = "QBT_TR(Working)QBT_TR[CONTEXT=TrackerListWidget]"; - break; - case 3: - status = "QBT_TR(Updating...)QBT_TR[CONTEXT=TrackerListWidget]"; - break; - case 4: - status = "QBT_TR(Not working)QBT_TR[CONTEXT=TrackerListWidget]"; - break; + + if (tracker.updating) { + status = "QBT_TR(Updating...)QBT_TR[CONTEXT=TrackerListWidget]"; + } + else { + switch (tracker.status) { + case 0: + status = "QBT_TR(Disabled)QBT_TR[CONTEXT=TrackerListWidget]"; + break; + case 1: + status = "QBT_TR(Not contacted yet)QBT_TR[CONTEXT=TrackerListWidget]"; + break; + case 2: + status = "QBT_TR(Working)QBT_TR[CONTEXT=TrackerListWidget]"; + break; + case 4: + status = "QBT_TR(Not working)QBT_TR[CONTEXT=TrackerListWidget]"; + break; + } } const row = {