From 62a6c725d6050813728f372985baffaf5c753c7f Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Sat, 17 Apr 2021 11:40:41 +0300 Subject: [PATCH 1/2] Don't overwrite tracker message Use one of the tracker endpoint messages. --- src/base/bittorrent/torrent.h | 1 - src/base/bittorrent/torrentimpl.cpp | 58 +++++++++++++++++------- src/base/bittorrent/trackerentry.h | 2 + src/gui/properties/trackerlistwidget.cpp | 6 +-- src/webui/api/torrentscontroller.cpp | 2 +- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index 97a051c63..41b070f4d 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -86,7 +86,6 @@ namespace BitTorrent struct TrackerInfo { - QString lastMessage; int numPeers = 0; }; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index f653b7f71..804aa23ed 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -107,6 +107,8 @@ namespace int numUpdating = 0; int numWorking = 0; int numNotWorking = 0; + QString firstTrackerMessage; + QString firstErrorMessage; #if (LIBTORRENT_VERSION_NUM >= 20000) const int numEndpoints = nativeEntry.endpoints.size() * ((hashes.has_v1() && hashes.has_v2()) ? 2 : 1); trackerEntry.endpoints.reserve(numEndpoints); @@ -123,6 +125,7 @@ namespace trackerEndpoint.numSeeds = infoHash.scrape_complete; trackerEndpoint.numLeeches = infoHash.scrape_incomplete; trackerEndpoint.numDownloaded = infoHash.scrape_downloaded; + if (infoHash.updating) { trackerEndpoint.status = TrackerEntry::Updating; @@ -142,11 +145,20 @@ namespace { trackerEndpoint.status = TrackerEntry::NotContacted; } - trackerEntry.endpoints.append(trackerEndpoint); - trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, infoHash.scrape_complete); - trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, infoHash.scrape_incomplete); - trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, infoHash.scrape_downloaded); + const QString trackerMessage = QString::fromStdString(infoHash.message); + const QString errorMessage = QString::fromLocal8Bit(infoHash.last_error.message().c_str()); + trackerEndpoint.message = (!trackerMessage.isEmpty() ? trackerMessage : errorMessage); + + trackerEntry.endpoints.append(trackerEndpoint); + trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, trackerEndpoint.numSeeds); + trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, trackerEndpoint.numLeeches); + trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, trackerEndpoint.numDownloaded); + + if (firstTrackerMessage.isEmpty()) + firstTrackerMessage = trackerMessage; + if (firstErrorMessage.isEmpty()) + firstErrorMessage = errorMessage; } } } @@ -159,6 +171,7 @@ namespace trackerEndpoint.numSeeds = endpoint.scrape_complete; trackerEndpoint.numLeeches = endpoint.scrape_incomplete; trackerEndpoint.numDownloaded = endpoint.scrape_downloaded; + if (endpoint.updating) { trackerEndpoint.status = TrackerEntry::Updating; @@ -178,22 +191,39 @@ namespace { trackerEndpoint.status = TrackerEntry::NotContacted; } - trackerEntry.endpoints.append(trackerEndpoint); - trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, endpoint.scrape_complete); - trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, endpoint.scrape_incomplete); - trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, endpoint.scrape_downloaded); + const QString trackerMessage = QString::fromStdString(endpoint.message); + const QString errorMessage = QString::fromLocal8Bit(endpoint.last_error.message().c_str()); + trackerEndpoint.message = (!trackerMessage.isEmpty() ? trackerMessage : errorMessage); + + trackerEntry.endpoints.append(trackerEndpoint); + trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, trackerEndpoint.numSeeds); + trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, trackerEndpoint.numLeeches); + trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, trackerEndpoint.numDownloaded); + + if (firstTrackerMessage.isEmpty()) + firstTrackerMessage = trackerMessage; + if (firstErrorMessage.isEmpty()) + firstErrorMessage = errorMessage; } #endif if (numEndpoints > 0) { if (numUpdating > 0) + { trackerEntry.status = TrackerEntry::Updating; + } else if (numWorking > 0) + { trackerEntry.status = TrackerEntry::Working; + trackerEntry.message = firstTrackerMessage; + } else if (numNotWorking == numEndpoints) + { trackerEntry.status = TrackerEntry::NotWorking; + trackerEntry.message = (!firstTrackerMessage.isEmpty() ? firstTrackerMessage : firstErrorMessage); + } } return trackerEntry; @@ -440,11 +470,13 @@ QVector TorrentImpl::trackers() const entries.reserve(nativeTrackers.size()); for (const lt::announce_entry &tracker : nativeTrackers) + { #if (LIBTORRENT_VERSION_NUM >= 20000) entries << fromNativeAnnouncerEntry(tracker, m_nativeHandle.info_hashes()); #else entries << fromNativeAnnouncerEntry(tracker); #endif + } return entries; } @@ -1617,7 +1649,7 @@ void TorrentImpl::handleTrackerReplyAlert(const lt::tracker_reply_alert *p) const QString trackerUrl(p->tracker_url()); qDebug("Received a tracker reply from %s (Num_peers = %d)", qUtf8Printable(trackerUrl), p->num_peers); // Connection was successful now. Remove possible old errors - m_trackerInfos[trackerUrl] = {{}, p->num_peers}; + m_trackerInfos[trackerUrl] = {p->num_peers}; m_session->handleTorrentTrackerReply(this, trackerUrl); } @@ -1625,20 +1657,12 @@ void TorrentImpl::handleTrackerReplyAlert(const lt::tracker_reply_alert *p) void TorrentImpl::handleTrackerWarningAlert(const lt::tracker_warning_alert *p) { const QString trackerUrl = p->tracker_url(); - const QString message = p->warning_message(); - - // Connection was successful now but there is a warning message - m_trackerInfos[trackerUrl].lastMessage = message; // Store warning message - m_session->handleTorrentTrackerWarning(this, trackerUrl); } void TorrentImpl::handleTrackerErrorAlert(const lt::tracker_error_alert *p) { const QString trackerUrl = p->tracker_url(); - const QString message = p->error_message(); - - m_trackerInfos[trackerUrl].lastMessage = message; // Starting with libtorrent 1.2.x each tracker has multiple local endpoints from which // an announce is attempted. Some endpoints might succeed while others might fail. diff --git a/src/base/bittorrent/trackerentry.h b/src/base/bittorrent/trackerentry.h index e4bdd5538..fe9fe7090 100644 --- a/src/base/bittorrent/trackerentry.h +++ b/src/base/bittorrent/trackerentry.h @@ -52,6 +52,7 @@ namespace BitTorrent int numSeeds = -1; int numLeeches = -1; int numDownloaded = -1; + QString message; }; QString url; @@ -64,6 +65,7 @@ namespace BitTorrent int numSeeds = -1; int numLeeches = -1; int numDownloaded = -1; + QString message; }; bool operator==(const TrackerEntry &left, const TrackerEntry &right); diff --git a/src/gui/properties/trackerlistwidget.cpp b/src/gui/properties/trackerlistwidget.cpp index fd3237612..5e49b0d01 100644 --- a/src/gui/properties/trackerlistwidget.cpp +++ b/src/gui/properties/trackerlistwidget.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -391,22 +390,19 @@ void TrackerListWidget::loadTrackers() { case BitTorrent::TrackerEntry::Working: item->setText(COL_STATUS, tr("Working")); - item->setText(COL_MSG, ""); break; case BitTorrent::TrackerEntry::Updating: item->setText(COL_STATUS, tr("Updating...")); - item->setText(COL_MSG, ""); break; case BitTorrent::TrackerEntry::NotWorking: item->setText(COL_STATUS, tr("Not working")); - item->setText(COL_MSG, data.lastMessage.trimmed()); break; case BitTorrent::TrackerEntry::NotContacted: item->setText(COL_STATUS, tr("Not contacted yet")); - item->setText(COL_MSG, ""); break; } + item->setText(COL_MSG, entry.message); item->setText(COL_PEERS, QString::number(data.numPeers)); item->setText(COL_SEEDS, ((entry.numSeeds > -1) ? QString::number(entry.numSeeds) diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 98f65895c..3f88854cc 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -464,7 +464,7 @@ void TorrentsController::trackersAction() {KEY_TRACKER_TIER, tracker.tier}, {KEY_TRACKER_STATUS, static_cast(tracker.status)}, {KEY_TRACKER_PEERS_COUNT, data.numPeers}, - {KEY_TRACKER_MSG, data.lastMessage.trimmed()}, + {KEY_TRACKER_MSG, tracker.message}, {KEY_TRACKER_SEEDS_COUNT, tracker.numSeeds}, {KEY_TRACKER_LEECHES_COUNT, tracker.numLeeches}, {KEY_TRACKER_DOWNLOADED_COUNT, tracker.numDownloaded} From 75e0990eb37202c8c11d964059e5de29b486cdbe Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Mon, 19 Apr 2021 09:40:15 +0300 Subject: [PATCH 2/2] Provide tracker peers count via TrackerEntry Don't expose additional accessor in Torrent interface. --- src/base/bittorrent/torrent.h | 6 ------ src/base/bittorrent/torrentimpl.cpp | 26 ++++++++++++------------ src/base/bittorrent/torrentimpl.h | 5 +++-- src/base/bittorrent/trackerentry.h | 2 ++ src/gui/properties/trackerlistwidget.cpp | 7 +++---- src/webui/api/torrentscontroller.cpp | 5 +---- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index 41b070f4d..e1416c063 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -84,11 +84,6 @@ namespace BitTorrent Error }; - struct TrackerInfo - { - int numPeers = 0; - }; - uint qHash(TorrentState key, uint seed); class Torrent : public AbstractFileStorage @@ -210,7 +205,6 @@ namespace BitTorrent virtual bool hasFilteredPieces() const = 0; virtual int queuePosition() const = 0; virtual QVector trackers() const = 0; - virtual QHash trackerInfos() const = 0; virtual QVector urlSeeds() const = 0; virtual QString error() const = 0; virtual qlonglong totalDownload() const = 0; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 804aa23ed..2bc160745 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -97,9 +97,11 @@ namespace } #if (LIBTORRENT_VERSION_NUM >= 20000) - TrackerEntry fromNativeAnnouncerEntry(const lt::announce_entry &nativeEntry, const lt::info_hash_t &hashes) + TrackerEntry fromNativeAnnouncerEntry(const lt::announce_entry &nativeEntry + , const lt::info_hash_t &hashes, const QMap &trackerPeerCounts) #else - TrackerEntry fromNativeAnnouncerEntry(const lt::announce_entry &nativeEntry) + TrackerEntry fromNativeAnnouncerEntry(const lt::announce_entry &nativeEntry + , const QMap &trackerPeerCounts) #endif { TrackerEntry trackerEntry {QString::fromStdString(nativeEntry.url), nativeEntry.tier}; @@ -122,6 +124,7 @@ namespace TrackerEntry::EndpointStats trackerEndpoint; trackerEndpoint.protocolVersion = (protocolVersion == lt::protocol_version::V1) ? 1 : 2; + trackerEndpoint.numPeers = trackerPeerCounts.value(endpoint.local_endpoint, -1); trackerEndpoint.numSeeds = infoHash.scrape_complete; trackerEndpoint.numLeeches = infoHash.scrape_incomplete; trackerEndpoint.numDownloaded = infoHash.scrape_downloaded; @@ -151,6 +154,7 @@ namespace trackerEndpoint.message = (!trackerMessage.isEmpty() ? trackerMessage : errorMessage); trackerEntry.endpoints.append(trackerEndpoint); + trackerEntry.numPeers = std::max(trackerEntry.numPeers, trackerEndpoint.numPeers); trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, trackerEndpoint.numSeeds); trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, trackerEndpoint.numLeeches); trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, trackerEndpoint.numDownloaded); @@ -168,6 +172,7 @@ namespace for (const lt::announce_endpoint &endpoint : nativeEntry.endpoints) { TrackerEntry::EndpointStats trackerEndpoint; + trackerEndpoint.numPeers = trackerPeerCounts.value(endpoint.local_endpoint, -1); trackerEndpoint.numSeeds = endpoint.scrape_complete; trackerEndpoint.numLeeches = endpoint.scrape_incomplete; trackerEndpoint.numDownloaded = endpoint.scrape_downloaded; @@ -197,6 +202,7 @@ namespace trackerEndpoint.message = (!trackerMessage.isEmpty() ? trackerMessage : errorMessage); trackerEntry.endpoints.append(trackerEndpoint); + trackerEntry.numPeers = std::max(trackerEntry.numPeers, trackerEndpoint.numPeers); trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, trackerEndpoint.numSeeds); trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, trackerEndpoint.numLeeches); trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, trackerEndpoint.numDownloaded); @@ -471,21 +477,17 @@ QVector TorrentImpl::trackers() const for (const lt::announce_entry &tracker : nativeTrackers) { + const QString trackerURL = QString::fromStdString(tracker.url); #if (LIBTORRENT_VERSION_NUM >= 20000) - entries << fromNativeAnnouncerEntry(tracker, m_nativeHandle.info_hashes()); + entries << fromNativeAnnouncerEntry(tracker, m_nativeHandle.info_hashes(), m_trackerPeerCounts[trackerURL]); #else - entries << fromNativeAnnouncerEntry(tracker); + entries << fromNativeAnnouncerEntry(tracker, m_trackerPeerCounts[trackerURL]); #endif } return entries; } -QHash TorrentImpl::trackerInfos() const -{ - return m_trackerInfos; -} - void TorrentImpl::addTrackers(const QVector &trackers) { QSet currentTrackers; @@ -1646,10 +1648,8 @@ void TorrentImpl::handleMoveStorageJobFinished(const bool hasOutstandingJob) void TorrentImpl::handleTrackerReplyAlert(const lt::tracker_reply_alert *p) { - const QString trackerUrl(p->tracker_url()); - qDebug("Received a tracker reply from %s (Num_peers = %d)", qUtf8Printable(trackerUrl), p->num_peers); - // Connection was successful now. Remove possible old errors - m_trackerInfos[trackerUrl] = {p->num_peers}; + const QString trackerUrl = p->tracker_url(); + m_trackerPeerCounts[trackerUrl][p->local_endpoint] = p->num_peers; m_session->handleTorrentTrackerReply(this, trackerUrl); } diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index c97444e8f..8f59e722f 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -33,11 +33,13 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -154,7 +156,6 @@ namespace BitTorrent bool hasFilteredPieces() const override; int queuePosition() const override; QVector trackers() const override; - QHash trackerInfos() const override; QVector urlSeeds() const override; QString error() const override; qlonglong totalDownload() const override; @@ -308,7 +309,7 @@ namespace BitTorrent // we will rely on this workaround to remove empty leftover folders QHash> m_oldPath; - QHash m_trackerInfos; + QHash> m_trackerPeerCounts; // Persistent data QString m_name; diff --git a/src/base/bittorrent/trackerentry.h b/src/base/bittorrent/trackerentry.h index fe9fe7090..63f7434db 100644 --- a/src/base/bittorrent/trackerentry.h +++ b/src/base/bittorrent/trackerentry.h @@ -49,6 +49,7 @@ namespace BitTorrent int protocolVersion = 1; Status status = NotContacted; + int numPeers = -1; int numSeeds = -1; int numLeeches = -1; int numDownloaded = -1; @@ -62,6 +63,7 @@ namespace BitTorrent // Deprecated fields Status status = NotContacted; + int numPeers = -1; int numSeeds = -1; int numLeeches = -1; int numDownloaded = -1; diff --git a/src/gui/properties/trackerlistwidget.cpp b/src/gui/properties/trackerlistwidget.cpp index 5e49b0d01..a1d00af09 100644 --- a/src/gui/properties/trackerlistwidget.cpp +++ b/src/gui/properties/trackerlistwidget.cpp @@ -362,7 +362,6 @@ void TrackerListWidget::loadTrackers() loadStickyItems(torrent); // Load actual trackers information - const QHash trackerData = torrent->trackerInfos(); QStringList oldTrackerURLs = m_trackerItems.keys(); for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers())) @@ -384,8 +383,6 @@ void TrackerListWidget::loadTrackers() item->setText(COL_TIER, QString::number(entry.tier)); - const BitTorrent::TrackerInfo data = trackerData.value(trackerURL); - switch (entry.status) { case BitTorrent::TrackerEntry::Working: @@ -403,7 +400,9 @@ void TrackerListWidget::loadTrackers() } item->setText(COL_MSG, entry.message); - item->setText(COL_PEERS, QString::number(data.numPeers)); + item->setText(COL_PEERS, ((entry.numPeers > -1) + ? QString::number(entry.numPeers) + : tr("N/A"))); item->setText(COL_SEEDS, ((entry.numSeeds > -1) ? QString::number(entry.numSeeds) : tr("N/A"))); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 3f88854cc..8596b112f 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -453,18 +453,15 @@ void TorrentsController::trackersAction() QJsonArray trackerList = getStickyTrackers(torrent); - QHash trackersData = torrent->trackerInfos(); for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers())) { - const BitTorrent::TrackerInfo data = trackersData.value(tracker.url); - trackerList << QJsonObject { {KEY_TRACKER_URL, tracker.url}, {KEY_TRACKER_TIER, tracker.tier}, {KEY_TRACKER_STATUS, static_cast(tracker.status)}, - {KEY_TRACKER_PEERS_COUNT, data.numPeers}, {KEY_TRACKER_MSG, tracker.message}, + {KEY_TRACKER_PEERS_COUNT, tracker.numPeers}, {KEY_TRACKER_SEEDS_COUNT, tracker.numSeeds}, {KEY_TRACKER_LEECHES_COUNT, tracker.numLeeches}, {KEY_TRACKER_DOWNLOADED_COUNT, tracker.numDownloaded}