mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-02 13:48:05 -06:00
Revamp tracker list widget
Internally redesign tracker list widget using Qt Model/View architecture. Make tracker list sortable by any column. PR #19633. Closes #261.
This commit is contained in:
committed by
GitHub
parent
70b438e6d9
commit
c051ee9409
@@ -4815,7 +4815,6 @@ void SessionImpl::handleTorrentTrackersAdded(TorrentImpl *const torrent, const Q
|
||||
for (const TrackerEntry &newTracker : newTrackers)
|
||||
LogMsg(tr("Added tracker to torrent. Torrent: \"%1\". Tracker: \"%2\"").arg(torrent->name(), newTracker.url));
|
||||
emit trackersAdded(torrent, newTrackers);
|
||||
emit trackersChanged(torrent);
|
||||
}
|
||||
|
||||
void SessionImpl::handleTorrentTrackersRemoved(TorrentImpl *const torrent, const QStringList &deletedTrackers)
|
||||
@@ -4823,7 +4822,6 @@ void SessionImpl::handleTorrentTrackersRemoved(TorrentImpl *const torrent, const
|
||||
for (const QString &deletedTracker : deletedTrackers)
|
||||
LogMsg(tr("Removed tracker from torrent. Torrent: \"%1\". Tracker: \"%2\"").arg(torrent->name(), deletedTracker));
|
||||
emit trackersRemoved(torrent, deletedTrackers);
|
||||
emit trackersChanged(torrent);
|
||||
}
|
||||
|
||||
void SessionImpl::handleTorrentTrackersChanged(TorrentImpl *const torrent)
|
||||
@@ -6057,7 +6055,7 @@ void SessionImpl::loadStatistics()
|
||||
m_previouslyUploaded = value[u"AlltimeUL"_s].toLongLong();
|
||||
}
|
||||
|
||||
void SessionImpl::updateTrackerEntries(lt::torrent_handle torrentHandle, QHash<std::string, QHash<TrackerEntry::Endpoint, QMap<int, int>>> updatedTrackers)
|
||||
void SessionImpl::updateTrackerEntries(lt::torrent_handle torrentHandle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers)
|
||||
{
|
||||
invokeAsync([this, torrentHandle = std::move(torrentHandle), updatedTrackers = std::move(updatedTrackers)]() mutable
|
||||
{
|
||||
|
||||
@@ -576,7 +576,7 @@ namespace BitTorrent
|
||||
void saveStatistics() const;
|
||||
void loadStatistics();
|
||||
|
||||
void updateTrackerEntries(lt::torrent_handle torrentHandle, QHash<std::string, QHash<TrackerEntry::Endpoint, QMap<int, int>>> updatedTrackers);
|
||||
void updateTrackerEntries(lt::torrent_handle torrentHandle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers);
|
||||
|
||||
// BitTorrent
|
||||
lt::session *m_nativeSession = nullptr;
|
||||
@@ -753,7 +753,7 @@ namespace BitTorrent
|
||||
|
||||
// This field holds amounts of peers reported by trackers in their responses to announces
|
||||
// (torrent.tracker_name.tracker_local_endpoint.protocol_version.num_peers)
|
||||
QHash<lt::torrent_handle, QHash<std::string, QHash<TrackerEntry::Endpoint, QMap<int, int>>>> m_updatedTrackerEntries;
|
||||
QHash<lt::torrent_handle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>>> m_updatedTrackerEntries;
|
||||
|
||||
// I/O errored torrents
|
||||
QSet<TorrentID> m_recentErroredTorrents;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2022 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -49,6 +49,7 @@ namespace BitTorrent
|
||||
enum class DownloadPriority;
|
||||
class InfoHash;
|
||||
class PeerInfo;
|
||||
class Session;
|
||||
class TorrentID;
|
||||
class TorrentInfo;
|
||||
struct PeerAddress;
|
||||
@@ -131,6 +132,8 @@ namespace BitTorrent
|
||||
|
||||
using TorrentContentHandler::TorrentContentHandler;
|
||||
|
||||
virtual Session *session() const = 0;
|
||||
|
||||
virtual InfoHash infoHash() const = 0;
|
||||
virtual QString name() const = 0;
|
||||
virtual QDateTime creationDate() const = 0;
|
||||
|
||||
@@ -87,190 +87,167 @@ namespace
|
||||
return qNow.addSecs(secsSinceNow);
|
||||
}
|
||||
|
||||
#ifdef QBT_USES_LIBTORRENT2
|
||||
QString toString(const lt::tcp::endpoint <TCPEndpoint)
|
||||
{
|
||||
return QString::fromStdString((std::stringstream() << ltTCPEndpoint).str());
|
||||
}
|
||||
|
||||
void updateTrackerEntry(TrackerEntry &trackerEntry, const lt::announce_entry &nativeEntry
|
||||
, const lt::info_hash_t &hashes, const QHash<TrackerEntry::Endpoint, QMap<int, int>> &updateInfo)
|
||||
#else
|
||||
void updateTrackerEntry(TrackerEntry &trackerEntry, const lt::announce_entry &nativeEntry
|
||||
, const QHash<TrackerEntry::Endpoint, QMap<int, int>> &updateInfo)
|
||||
#endif
|
||||
, const QSet<int> &btProtocols, const QHash<lt::tcp::endpoint, QMap<int, int>> &updateInfo)
|
||||
{
|
||||
Q_ASSERT(trackerEntry.url == QString::fromStdString(nativeEntry.url));
|
||||
|
||||
trackerEntry.tier = nativeEntry.tier;
|
||||
|
||||
// remove outdated endpoints
|
||||
trackerEntry.stats.removeIf([&nativeEntry](const decltype(trackerEntry.stats)::iterator &iter)
|
||||
trackerEntry.endpointEntries.removeIf([&nativeEntry](const QHash<std::pair<QString, int>, TrackerEndpointEntry>::iterator &iter)
|
||||
{
|
||||
return std::none_of(nativeEntry.endpoints.cbegin(), nativeEntry.endpoints.cend()
|
||||
, [&endpoint = iter.key()](const auto &existingEndpoint)
|
||||
, [&endpointName = std::get<0>(iter.key())](const auto &existingEndpoint)
|
||||
{
|
||||
return (endpoint == existingEndpoint.local_endpoint);
|
||||
return (endpointName == toString(existingEndpoint.local_endpoint));
|
||||
});
|
||||
});
|
||||
|
||||
const auto numEndpoints = static_cast<qsizetype>(nativeEntry.endpoints.size()) * btProtocols.size();
|
||||
|
||||
int numUpdating = 0;
|
||||
int numWorking = 0;
|
||||
int numNotWorking = 0;
|
||||
int numTrackerError = 0;
|
||||
int numUnreachable = 0;
|
||||
#ifdef QBT_USES_LIBTORRENT2
|
||||
const auto numEndpoints = static_cast<qsizetype>(nativeEntry.endpoints.size()) * ((hashes.has_v1() && hashes.has_v2()) ? 2 : 1);
|
||||
for (const lt::announce_endpoint &endpoint : nativeEntry.endpoints)
|
||||
|
||||
for (const lt::announce_endpoint <AnnounceEndpoint : nativeEntry.endpoints)
|
||||
{
|
||||
const auto endpointName = QString::fromStdString((std::stringstream() << endpoint.local_endpoint).str());
|
||||
const auto endpointName = toString(ltAnnounceEndpoint.local_endpoint);
|
||||
|
||||
for (const auto protocolVersion : {lt::protocol_version::V1, lt::protocol_version::V2})
|
||||
for (const auto protocolVersion : btProtocols)
|
||||
{
|
||||
if (!hashes.has(protocolVersion))
|
||||
continue;
|
||||
#ifdef QBT_USES_LIBTORRENT2
|
||||
Q_ASSERT((protocolVersion == 1) || (protocolVersion == 2));
|
||||
const auto ltProtocolVersion = (protocolVersion == 1) ? lt::protocol_version::V1 : lt::protocol_version::V2;
|
||||
const lt::announce_infohash <AnnounceInfo = ltAnnounceEndpoint.info_hashes[ltProtocolVersion];
|
||||
#else
|
||||
Q_ASSERT(protocolVersion == 1);
|
||||
const lt::announce_endpoint <AnnounceInfo = ltAnnounceEndpoint;
|
||||
#endif
|
||||
const QMap<int, int> &endpointUpdateInfo = updateInfo[ltAnnounceEndpoint.local_endpoint];
|
||||
TrackerEndpointEntry &trackerEndpointEntry = trackerEntry.endpointEntries[std::make_pair(endpointName, protocolVersion)];
|
||||
|
||||
const lt::announce_infohash &infoHash = endpoint.info_hashes[protocolVersion];
|
||||
trackerEndpointEntry.name = endpointName;
|
||||
trackerEndpointEntry.btVersion = protocolVersion;
|
||||
trackerEndpointEntry.numPeers = endpointUpdateInfo.value(protocolVersion, trackerEndpointEntry.numPeers);
|
||||
trackerEndpointEntry.numSeeds = ltAnnounceInfo.scrape_complete;
|
||||
trackerEndpointEntry.numLeeches = ltAnnounceInfo.scrape_incomplete;
|
||||
trackerEndpointEntry.numDownloaded = ltAnnounceInfo.scrape_downloaded;
|
||||
trackerEndpointEntry.nextAnnounceTime = fromLTTimePoint32(ltAnnounceInfo.next_announce);
|
||||
trackerEndpointEntry.minAnnounceTime = fromLTTimePoint32(ltAnnounceInfo.min_announce);
|
||||
|
||||
const int protocolVersionNum = (protocolVersion == lt::protocol_version::V1) ? 1 : 2;
|
||||
const QMap<int, int> &endpointUpdateInfo = updateInfo[endpoint.local_endpoint];
|
||||
TrackerEntry::EndpointStats &trackerEndpoint = trackerEntry.stats[endpoint.local_endpoint][protocolVersionNum];
|
||||
|
||||
trackerEndpoint.name = endpointName;
|
||||
trackerEndpoint.numPeers = endpointUpdateInfo.value(protocolVersionNum, trackerEndpoint.numPeers);
|
||||
trackerEndpoint.numSeeds = infoHash.scrape_complete;
|
||||
trackerEndpoint.numLeeches = infoHash.scrape_incomplete;
|
||||
trackerEndpoint.numDownloaded = infoHash.scrape_downloaded;
|
||||
trackerEndpoint.nextAnnounceTime = fromLTTimePoint32(infoHash.next_announce);
|
||||
trackerEndpoint.minAnnounceTime = fromLTTimePoint32(infoHash.min_announce);
|
||||
|
||||
if (infoHash.updating)
|
||||
if (ltAnnounceInfo.updating)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::Updating;
|
||||
trackerEndpointEntry.status = TrackerEntryStatus::Updating;
|
||||
++numUpdating;
|
||||
}
|
||||
else if (infoHash.fails > 0)
|
||||
else if (ltAnnounceInfo.fails > 0)
|
||||
{
|
||||
if (infoHash.last_error == lt::errors::tracker_failure)
|
||||
if (ltAnnounceInfo.last_error == lt::errors::tracker_failure)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::TrackerError;
|
||||
trackerEndpointEntry.status = TrackerEntryStatus::TrackerError;
|
||||
++numTrackerError;
|
||||
}
|
||||
else if (infoHash.last_error == lt::errors::announce_skipped)
|
||||
else if (ltAnnounceInfo.last_error == lt::errors::announce_skipped)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::Unreachable;
|
||||
trackerEndpointEntry.status = TrackerEntryStatus::Unreachable;
|
||||
++numUnreachable;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::NotWorking;
|
||||
trackerEndpointEntry.status = TrackerEntryStatus::NotWorking;
|
||||
++numNotWorking;
|
||||
}
|
||||
}
|
||||
else if (nativeEntry.verified)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::Working;
|
||||
trackerEndpointEntry.status = TrackerEntryStatus::Working;
|
||||
++numWorking;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::NotContacted;
|
||||
trackerEndpointEntry.status = TrackerEntryStatus::NotContacted;
|
||||
}
|
||||
|
||||
if (!infoHash.message.empty())
|
||||
if (!ltAnnounceInfo.message.empty())
|
||||
{
|
||||
trackerEndpoint.message = QString::fromStdString(infoHash.message);
|
||||
trackerEndpointEntry.message = QString::fromStdString(ltAnnounceInfo.message);
|
||||
}
|
||||
else if (infoHash.last_error)
|
||||
else if (ltAnnounceInfo.last_error)
|
||||
{
|
||||
trackerEndpoint.message = QString::fromLocal8Bit(infoHash.last_error.message());
|
||||
trackerEndpointEntry.message = QString::fromLocal8Bit(ltAnnounceInfo.last_error.message());
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerEndpoint.message.clear();
|
||||
trackerEndpointEntry.message.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
const auto numEndpoints = static_cast<qsizetype>(nativeEntry.endpoints.size());
|
||||
for (const lt::announce_endpoint &endpoint : nativeEntry.endpoints)
|
||||
{
|
||||
const int protocolVersionNum = 1;
|
||||
const QMap<int, int> &endpointUpdateInfo = updateInfo[endpoint.local_endpoint];
|
||||
TrackerEntry::EndpointStats &trackerEndpoint = trackerEntry.stats[endpoint.local_endpoint][protocolVersionNum];
|
||||
|
||||
trackerEndpoint.name = QString::fromStdString((std::stringstream() << endpoint.local_endpoint).str());
|
||||
trackerEndpoint.numPeers = endpointUpdateInfo.value(protocolVersionNum, trackerEndpoint.numPeers);
|
||||
trackerEndpoint.numSeeds = endpoint.scrape_complete;
|
||||
trackerEndpoint.numLeeches = endpoint.scrape_incomplete;
|
||||
trackerEndpoint.numDownloaded = endpoint.scrape_downloaded;
|
||||
trackerEndpoint.nextAnnounceTime = fromLTTimePoint32(endpoint.next_announce);
|
||||
trackerEndpoint.minAnnounceTime = fromLTTimePoint32(endpoint.min_announce);
|
||||
|
||||
if (endpoint.updating)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::Updating;
|
||||
++numUpdating;
|
||||
}
|
||||
else if (endpoint.fails > 0)
|
||||
{
|
||||
if (endpoint.last_error == lt::errors::tracker_failure)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::TrackerError;
|
||||
++numTrackerError;
|
||||
}
|
||||
else if (endpoint.last_error == lt::errors::announce_skipped)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::Unreachable;
|
||||
++numUnreachable;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::NotWorking;
|
||||
++numNotWorking;
|
||||
}
|
||||
}
|
||||
else if (nativeEntry.verified)
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::Working;
|
||||
++numWorking;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerEndpoint.status = TrackerEntry::NotContacted;
|
||||
}
|
||||
|
||||
if (!endpoint.message.empty())
|
||||
{
|
||||
trackerEndpoint.message = QString::fromStdString(endpoint.message);
|
||||
}
|
||||
else if (endpoint.last_error)
|
||||
{
|
||||
trackerEndpoint.message = QString::fromLocal8Bit(endpoint.last_error.message());
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerEndpoint.message.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (numEndpoints > 0)
|
||||
{
|
||||
if (numUpdating > 0)
|
||||
{
|
||||
trackerEntry.status = TrackerEntry::Updating;
|
||||
trackerEntry.status = TrackerEntryStatus::Updating;
|
||||
}
|
||||
else if (numWorking > 0)
|
||||
{
|
||||
trackerEntry.status = TrackerEntry::Working;
|
||||
trackerEntry.status = TrackerEntryStatus::Working;
|
||||
}
|
||||
else if (numTrackerError > 0)
|
||||
{
|
||||
trackerEntry.status = TrackerEntry::TrackerError;
|
||||
trackerEntry.status = TrackerEntryStatus::TrackerError;
|
||||
}
|
||||
else if (numUnreachable == numEndpoints)
|
||||
{
|
||||
trackerEntry.status = TrackerEntry::Unreachable;
|
||||
trackerEntry.status = TrackerEntryStatus::Unreachable;
|
||||
}
|
||||
else if ((numUnreachable + numNotWorking) == numEndpoints)
|
||||
{
|
||||
trackerEntry.status = TrackerEntry::NotWorking;
|
||||
trackerEntry.status = TrackerEntryStatus::NotWorking;
|
||||
}
|
||||
}
|
||||
|
||||
trackerEntry.numPeers = -1;
|
||||
trackerEntry.numSeeds = -1;
|
||||
trackerEntry.numLeeches = -1;
|
||||
trackerEntry.numDownloaded = -1;
|
||||
trackerEntry.nextAnnounceTime = QDateTime();
|
||||
trackerEntry.minAnnounceTime = QDateTime();
|
||||
trackerEntry.message.clear();
|
||||
|
||||
for (const TrackerEndpointEntry &endpointEntry : asConst(trackerEntry.endpointEntries))
|
||||
{
|
||||
trackerEntry.numPeers = std::max(trackerEntry.numPeers, endpointEntry.numPeers);
|
||||
trackerEntry.numSeeds = std::max(trackerEntry.numSeeds, endpointEntry.numSeeds);
|
||||
trackerEntry.numLeeches = std::max(trackerEntry.numLeeches, endpointEntry.numLeeches);
|
||||
trackerEntry.numDownloaded = std::max(trackerEntry.numDownloaded, endpointEntry.numDownloaded);
|
||||
|
||||
if (endpointEntry.status == trackerEntry.status)
|
||||
{
|
||||
if (!trackerEntry.nextAnnounceTime.isValid() || (trackerEntry.nextAnnounceTime > endpointEntry.nextAnnounceTime))
|
||||
{
|
||||
trackerEntry.nextAnnounceTime = endpointEntry.nextAnnounceTime;
|
||||
trackerEntry.minAnnounceTime = endpointEntry.minAnnounceTime;
|
||||
if ((endpointEntry.status != TrackerEntryStatus::Working)
|
||||
|| !endpointEntry.message.isEmpty())
|
||||
{
|
||||
trackerEntry.message = endpointEntry.message;
|
||||
}
|
||||
}
|
||||
|
||||
if (endpointEntry.status == TrackerEntryStatus::Working)
|
||||
{
|
||||
if (trackerEntry.message.isEmpty())
|
||||
trackerEntry.message = endpointEntry.message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,6 +382,11 @@ bool TorrentImpl::isValid() const
|
||||
return m_nativeHandle.is_valid();
|
||||
}
|
||||
|
||||
Session *TorrentImpl::session() const
|
||||
{
|
||||
return m_session;
|
||||
}
|
||||
|
||||
InfoHash TorrentImpl::infoHash() const
|
||||
{
|
||||
return m_infoHash;
|
||||
@@ -1667,7 +1649,7 @@ void TorrentImpl::fileSearchFinished(const Path &savePath, const PathList &fileN
|
||||
endReceivedMetadataHandling(savePath, fileNames);
|
||||
}
|
||||
|
||||
TrackerEntry TorrentImpl::updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash<TrackerEntry::Endpoint, QMap<int, int>> &updateInfo)
|
||||
TrackerEntry TorrentImpl::updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash<lt::tcp::endpoint, QMap<int, int>> &updateInfo)
|
||||
{
|
||||
const auto it = std::find_if(m_trackerEntries.begin(), m_trackerEntries.end()
|
||||
, [&announceEntry](const TrackerEntry &trackerEntry)
|
||||
@@ -1680,10 +1662,16 @@ TrackerEntry TorrentImpl::updateTrackerEntry(const lt::announce_entry &announceE
|
||||
return {};
|
||||
|
||||
#ifdef QBT_USES_LIBTORRENT2
|
||||
::updateTrackerEntry(*it, announceEntry, nativeHandle().info_hashes(), updateInfo);
|
||||
QSet<int> btProtocols;
|
||||
const auto &infoHashes = nativeHandle().info_hashes();
|
||||
if (infoHashes.has(lt::protocol_version::V1))
|
||||
btProtocols.insert(1);
|
||||
if (infoHashes.has(lt::protocol_version::V2))
|
||||
btProtocols.insert(2);
|
||||
#else
|
||||
::updateTrackerEntry(*it, announceEntry, updateInfo);
|
||||
const QSet<int> btProtocols {1};
|
||||
#endif
|
||||
::updateTrackerEntry(*it, announceEntry, btProtocols, updateInfo);
|
||||
return *it;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,8 @@ namespace BitTorrent
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
Session *session() const override;
|
||||
|
||||
InfoHash infoHash() const override;
|
||||
QString name() const override;
|
||||
QDateTime creationDate() const override;
|
||||
@@ -264,7 +266,7 @@ namespace BitTorrent
|
||||
void saveResumeData(lt::resume_data_flags_t flags = {});
|
||||
void handleMoveStorageJobFinished(const Path &path, MoveStorageContext context, bool hasOutstandingJob);
|
||||
void fileSearchFinished(const Path &savePath, const PathList &fileNames);
|
||||
TrackerEntry updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash<TrackerEntry::Endpoint, QMap<int, int>> &updateInfo);
|
||||
TrackerEntry updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash<lt::tcp::endpoint, QMap<int, int>> &updateInfo);
|
||||
void resetTrackerEntries();
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2022 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,13 +29,12 @@
|
||||
#include "trackerentry.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
|
||||
QVector<BitTorrent::TrackerEntry> BitTorrent::parseTrackerEntries(const QStringView str)
|
||||
QList<BitTorrent::TrackerEntry> BitTorrent::parseTrackerEntries(const QStringView str)
|
||||
{
|
||||
const QList<QStringView> trackers = str.split(u'\n'); // keep the empty parts to track tracker tier
|
||||
|
||||
QVector<BitTorrent::TrackerEntry> entries;
|
||||
QList<BitTorrent::TrackerEntry> entries;
|
||||
entries.reserve(trackers.size());
|
||||
|
||||
int trackerTier = 0;
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libtorrent/socket.hpp>
|
||||
|
||||
#include <QtContainerFwd>
|
||||
#include <QDateTime>
|
||||
#include <QHash>
|
||||
@@ -38,44 +36,52 @@
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
struct TrackerEntry
|
||||
enum class TrackerEntryStatus
|
||||
{
|
||||
using Endpoint = lt::tcp::endpoint;
|
||||
NotContacted = 1,
|
||||
Working = 2,
|
||||
Updating = 3,
|
||||
NotWorking = 4,
|
||||
TrackerError = 5,
|
||||
Unreachable = 6
|
||||
};
|
||||
struct TrackerEndpointEntry
|
||||
{
|
||||
QString name {};
|
||||
int btVersion = 1;
|
||||
|
||||
enum Status
|
||||
{
|
||||
NotContacted = 1,
|
||||
Working = 2,
|
||||
Updating = 3,
|
||||
NotWorking = 4,
|
||||
TrackerError = 5,
|
||||
Unreachable = 6
|
||||
};
|
||||
TrackerEntryStatus status = TrackerEntryStatus::NotContacted;
|
||||
QString message {};
|
||||
|
||||
struct EndpointStats
|
||||
{
|
||||
QString name {};
|
||||
int numPeers = -1;
|
||||
int numSeeds = -1;
|
||||
int numLeeches = -1;
|
||||
int numDownloaded = -1;
|
||||
|
||||
Status status = NotContacted;
|
||||
QString message {};
|
||||
|
||||
int numPeers = -1;
|
||||
int numSeeds = -1;
|
||||
int numLeeches = -1;
|
||||
int numDownloaded = -1;
|
||||
|
||||
QDateTime nextAnnounceTime;
|
||||
QDateTime minAnnounceTime;
|
||||
};
|
||||
|
||||
QString url {};
|
||||
int tier = 0;
|
||||
Status status = NotContacted;
|
||||
|
||||
QHash<Endpoint, QHash<int, EndpointStats>> stats {};
|
||||
QDateTime nextAnnounceTime {};
|
||||
QDateTime minAnnounceTime {};
|
||||
};
|
||||
|
||||
QVector<TrackerEntry> parseTrackerEntries(QStringView str);
|
||||
struct TrackerEntry
|
||||
{
|
||||
QString url {};
|
||||
int tier = 0;
|
||||
|
||||
TrackerEntryStatus status = TrackerEntryStatus::NotContacted;
|
||||
QString message {};
|
||||
|
||||
int numPeers = -1;
|
||||
int numSeeds = -1;
|
||||
int numLeeches = -1;
|
||||
int numDownloaded = -1;
|
||||
|
||||
QDateTime nextAnnounceTime {};
|
||||
QDateTime minAnnounceTime {};
|
||||
|
||||
QHash<std::pair<QString, int>, TrackerEndpointEntry> endpointEntries {};
|
||||
};
|
||||
|
||||
QList<TrackerEntry> parseTrackerEntries(QStringView str);
|
||||
|
||||
bool operator==(const TrackerEntry &left, const TrackerEntry &right);
|
||||
std::size_t qHash(const TrackerEntry &key, std::size_t seed = 0);
|
||||
|
||||
@@ -1754,14 +1754,14 @@ void Preferences::setPropVisible(const bool visible)
|
||||
setValue(u"TorrentProperties/Visible"_s, visible);
|
||||
}
|
||||
|
||||
QByteArray Preferences::getPropTrackerListState() const
|
||||
QByteArray Preferences::getTrackerListState() const
|
||||
{
|
||||
return value<QByteArray>(u"GUI/Qt6/TorrentProperties/TrackerListState"_s);
|
||||
}
|
||||
|
||||
void Preferences::setPropTrackerListState(const QByteArray &state)
|
||||
void Preferences::setTrackerListState(const QByteArray &state)
|
||||
{
|
||||
if (state == getPropTrackerListState())
|
||||
if (state == getTrackerListState())
|
||||
return;
|
||||
|
||||
setValue(u"GUI/Qt6/TorrentProperties/TrackerListState"_s, state);
|
||||
|
||||
@@ -370,8 +370,8 @@ public:
|
||||
void setPropCurTab(int tab);
|
||||
bool getPropVisible() const;
|
||||
void setPropVisible(bool visible);
|
||||
QByteArray getPropTrackerListState() const;
|
||||
void setPropTrackerListState(const QByteArray &state);
|
||||
QByteArray getTrackerListState() const;
|
||||
void setTrackerListState(const QByteArray &state);
|
||||
QStringList getRssOpenFolders() const;
|
||||
void setRssOpenFolders(const QStringList &folders);
|
||||
QByteArray getRssSideSplitterState() const;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Utils::Misc
|
||||
// YobiByte, // 1024^8
|
||||
};
|
||||
|
||||
enum class TimeResolution
|
||||
enum class TimeResolution
|
||||
{
|
||||
Seconds,
|
||||
Minutes
|
||||
|
||||
Reference in New Issue
Block a user