Revise Tracker related classes

And also rename them.

PR #20489.
This commit is contained in:
Chocobo1
2024-04-01 19:17:35 +08:00
committed by GitHub
parent 4967f977c5
commit 90383567b2
24 changed files with 529 additions and 345 deletions

View File

@@ -1386,7 +1386,7 @@ void MainWindow::showFiltersSidebar(const bool show)
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackersAdded, m_transferListFiltersWidget, &TransferListFiltersWidget::addTrackers);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackersRemoved, m_transferListFiltersWidget, &TransferListFiltersWidget::removeTrackers);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackersChanged, m_transferListFiltersWidget, &TransferListFiltersWidget::refreshTrackers);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerEntriesUpdated, m_transferListFiltersWidget, &TransferListFiltersWidget::trackerEntriesUpdated);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerEntryStatusesUpdated, m_transferListFiltersWidget, &TransferListFiltersWidget::trackerEntryStatusesUpdated);
m_splitter->insertWidget(0, m_transferListFiltersWidget);
m_splitter->setCollapsible(0, true);

View File

@@ -48,6 +48,7 @@
#include "base/bittorrent/peerinfo.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentry.h"
#include "base/global.h"
#include "base/utils/misc.h"
@@ -68,24 +69,24 @@ namespace
return (val > -1) ? QString::number(val) : TrackerListModel::tr("N/A");
}
QString toString(const BitTorrent::TrackerEntryStatus status)
QString toString(const BitTorrent::TrackerEndpointState state)
{
switch (status)
switch (state)
{
case BitTorrent::TrackerEntryStatus::Working:
case BitTorrent::TrackerEndpointState::Working:
return TrackerListModel::tr(STR_WORKING);
case BitTorrent::TrackerEntryStatus::Updating:
case BitTorrent::TrackerEndpointState::Updating:
return TrackerListModel::tr("Updating...");
case BitTorrent::TrackerEntryStatus::NotWorking:
case BitTorrent::TrackerEndpointState::NotWorking:
return TrackerListModel::tr("Not working");
case BitTorrent::TrackerEntryStatus::TrackerError:
case BitTorrent::TrackerEndpointState::TrackerError:
return TrackerListModel::tr("Tracker error");
case BitTorrent::TrackerEntryStatus::Unreachable:
case BitTorrent::TrackerEndpointState::Unreachable:
return TrackerListModel::tr("Unreachable");
case BitTorrent::TrackerEntryStatus::NotContacted:
case BitTorrent::TrackerEndpointState::NotContacted:
return TrackerListModel::tr("Not contacted yet");
}
return TrackerListModel::tr("Invalid status!");
return TrackerListModel::tr("Invalid state!");
}
QString statusDHT(const BitTorrent::Torrent *torrent)
@@ -132,7 +133,7 @@ struct TrackerListModel::Item final
QString name {};
int tier = -1;
int btVersion = -1;
BitTorrent::TrackerEntryStatus status = BitTorrent::TrackerEntryStatus::NotContacted;
BitTorrent::TrackerEndpointState status = BitTorrent::TrackerEndpointState::NotContacted;
QString message {};
int numPeers = -1;
@@ -159,11 +160,11 @@ struct TrackerListModel::Item final
>> childItems {};
Item(QStringView name, QStringView message);
explicit Item(const BitTorrent::TrackerEntry &trackerEntry);
Item(const std::shared_ptr<Item> &parentItem, const BitTorrent::TrackerEndpointEntry &endpointEntry);
explicit Item(const BitTorrent::TrackerEntryStatus &trackerEntryStatus);
Item(const std::shared_ptr<Item> &parentItem, const BitTorrent::TrackerEndpointStatus &endpointStatus);
void fillFrom(const BitTorrent::TrackerEntry &trackerEntry);
void fillFrom(const BitTorrent::TrackerEndpointEntry &endpointEntry);
void fillFrom(const BitTorrent::TrackerEntryStatus &trackerEntryStatus);
void fillFrom(const BitTorrent::TrackerEndpointStatus &endpointStatus);
};
class TrackerListModel::Items final : public multi_index_container<
@@ -180,53 +181,53 @@ TrackerListModel::Item::Item(const QStringView name, const QStringView message)
{
}
TrackerListModel::Item::Item(const BitTorrent::TrackerEntry &trackerEntry)
: name {trackerEntry.url}
TrackerListModel::Item::Item(const BitTorrent::TrackerEntryStatus &trackerEntryStatus)
: name {trackerEntryStatus.url}
{
fillFrom(trackerEntry);
fillFrom(trackerEntryStatus);
}
TrackerListModel::Item::Item(const std::shared_ptr<Item> &parentItem, const BitTorrent::TrackerEndpointEntry &endpointEntry)
: name {endpointEntry.name}
, btVersion {endpointEntry.btVersion}
TrackerListModel::Item::Item(const std::shared_ptr<Item> &parentItem, const BitTorrent::TrackerEndpointStatus &endpointStatus)
: name {endpointStatus.name}
, btVersion {endpointStatus.btVersion}
, parentItem {parentItem}
{
fillFrom(endpointEntry);
fillFrom(endpointStatus);
}
void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEntry &trackerEntry)
void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEntryStatus &trackerEntryStatus)
{
Q_ASSERT(parentItem.expired());
Q_ASSERT(trackerEntry.url == name);
Q_ASSERT(trackerEntryStatus.url == name);
tier = trackerEntry.tier;
status = trackerEntry.status;
message = trackerEntry.message;
numPeers = trackerEntry.numPeers;
numSeeds = trackerEntry.numSeeds;
numLeeches = trackerEntry.numLeeches;
numDownloaded = trackerEntry.numDownloaded;
nextAnnounceTime = trackerEntry.nextAnnounceTime;
minAnnounceTime = trackerEntry.minAnnounceTime;
tier = trackerEntryStatus.tier;
status = trackerEntryStatus.state;
message = trackerEntryStatus.message;
numPeers = trackerEntryStatus.numPeers;
numSeeds = trackerEntryStatus.numSeeds;
numLeeches = trackerEntryStatus.numLeeches;
numDownloaded = trackerEntryStatus.numDownloaded;
nextAnnounceTime = trackerEntryStatus.nextAnnounceTime;
minAnnounceTime = trackerEntryStatus.minAnnounceTime;
secsToNextAnnounce = 0;
secsToMinAnnounce = 0;
announceTimestamp = QDateTime();
}
void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEndpointEntry &endpointEntry)
void TrackerListModel::Item::fillFrom(const BitTorrent::TrackerEndpointStatus &endpointStatus)
{
Q_ASSERT(!parentItem.expired());
Q_ASSERT(endpointEntry.name == name);
Q_ASSERT(endpointEntry.btVersion == btVersion);
Q_ASSERT(endpointStatus.name == name);
Q_ASSERT(endpointStatus.btVersion == btVersion);
status = endpointEntry.status;
message = endpointEntry.message;
numPeers = endpointEntry.numPeers;
numSeeds = endpointEntry.numSeeds;
numLeeches = endpointEntry.numLeeches;
numDownloaded = endpointEntry.numDownloaded;
nextAnnounceTime = endpointEntry.nextAnnounceTime;
minAnnounceTime = endpointEntry.minAnnounceTime;
status = endpointStatus.state;
message = endpointStatus.message;
numPeers = endpointStatus.numPeers;
numSeeds = endpointStatus.numSeeds;
numLeeches = endpointStatus.numLeeches;
numDownloaded = endpointStatus.numDownloaded;
nextAnnounceTime = endpointStatus.nextAnnounceTime;
minAnnounceTime = endpointStatus.minAnnounceTime;
secsToNextAnnounce = 0;
secsToMinAnnounce = 0;
announceTimestamp = QDateTime();
@@ -261,8 +262,8 @@ TrackerListModel::TrackerListModel(BitTorrent::Session *btSession, QObject *pare
if (torrent == m_torrent)
onTrackersChanged();
});
connect(m_btSession, &BitTorrent::Session::trackerEntriesUpdated, this
, [this](BitTorrent::Torrent *torrent, const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackers)
connect(m_btSession, &BitTorrent::Session::trackerEntryStatusesUpdated, this
, [this](BitTorrent::Torrent *torrent, const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers)
{
if (torrent == m_torrent)
onTrackersUpdated(updatedTrackers);
@@ -296,8 +297,8 @@ void TrackerListModel::populate()
{
Q_ASSERT(m_torrent);
const QList<BitTorrent::TrackerEntry> trackerEntries = m_torrent->trackers();
m_items->reserve(trackerEntries.size() + STICKY_ROW_COUNT);
const QList<BitTorrent::TrackerEntryStatus> trackers = m_torrent->trackers();
m_items->reserve(trackers.size() + STICKY_ROW_COUNT);
const QString &privateTorrentMessage = m_torrent->isPrivate() ? tr(STR_PRIVATE_MSG) : u""_s;
m_items->emplace_back(std::make_shared<Item>(u"** [DHT] **", privateTorrentMessage));
@@ -365,46 +366,44 @@ void TrackerListModel::populate()
emit dataChanged(index(ROW_DHT, COL_SEEDS), index(ROW_LSD, COL_LEECHES));
});
for (const BitTorrent::TrackerEntry &trackerEntry : trackerEntries)
addTrackerItem(trackerEntry);
for (const BitTorrent::TrackerEntryStatus &status : trackers)
addTrackerItem(status);
m_announceTimestamp = QDateTime::currentDateTime();
m_announceRefreshTimer->start(ANNOUNCE_TIME_REFRESH_INTERVAL);
}
std::shared_ptr<TrackerListModel::Item> TrackerListModel::createTrackerItem(const BitTorrent::TrackerEntry &trackerEntry)
std::shared_ptr<TrackerListModel::Item> TrackerListModel::createTrackerItem(const BitTorrent::TrackerEntryStatus &trackerEntryStatus)
{
auto item = std::make_shared<Item>(trackerEntry);
for (const auto &[id, endpointEntry] : trackerEntry.endpointEntries.asKeyValueRange())
{
item->childItems.emplace_back(std::make_shared<Item>(item, endpointEntry));
}
const auto item = std::make_shared<Item>(trackerEntryStatus);
for (const auto &[id, endpointStatus] : trackerEntryStatus.endpoints.asKeyValueRange())
item->childItems.emplace_back(std::make_shared<Item>(item, endpointStatus));
return item;
}
void TrackerListModel::addTrackerItem(const BitTorrent::TrackerEntry &trackerEntry)
void TrackerListModel::addTrackerItem(const BitTorrent::TrackerEntryStatus &trackerEntryStatus)
{
[[maybe_unused]] const auto &[iter, res] = m_items->emplace_back(createTrackerItem(trackerEntry));
[[maybe_unused]] const auto &[iter, res] = m_items->emplace_back(createTrackerItem(trackerEntryStatus));
Q_ASSERT(res);
}
void TrackerListModel::updateTrackerItem(const std::shared_ptr<Item> &item, const BitTorrent::TrackerEntry &trackerEntry)
void TrackerListModel::updateTrackerItem(const std::shared_ptr<Item> &item, const BitTorrent::TrackerEntryStatus &trackerEntryStatus)
{
QSet<std::pair<QString, int>> endpointItemIDs;
QList<std::shared_ptr<Item>> newEndpointItems;
for (const auto &[id, endpointEntry] : trackerEntry.endpointEntries.asKeyValueRange())
for (const auto &[id, endpointStatus] : trackerEntryStatus.endpoints.asKeyValueRange())
{
endpointItemIDs.insert(id);
auto &itemsByID = item->childItems.get<ByID>();
if (const auto &iter = itemsByID.find(std::make_tuple(id.first, id.second)); iter != itemsByID.end())
{
(*iter)->fillFrom(endpointEntry);
(*iter)->fillFrom(endpointStatus);
}
else
{
newEndpointItems.emplace_back(std::make_shared<Item>(item, endpointEntry));
newEndpointItems.emplace_back(std::make_shared<Item>(item, endpointStatus));
}
}
@@ -429,7 +428,7 @@ void TrackerListModel::updateTrackerItem(const std::shared_ptr<Item> &item, cons
}
}
const auto numRows = rowCount(trackerIndex);
const int numRows = rowCount(trackerIndex);
emit dataChanged(index(0, 0, trackerIndex), index((numRows - 1), (columnCount(trackerIndex) - 1), trackerIndex));
if (!newEndpointItems.isEmpty())
@@ -440,7 +439,7 @@ void TrackerListModel::updateTrackerItem(const std::shared_ptr<Item> &item, cons
endInsertRows();
}
item->fillFrom(trackerEntry);
item->fillFrom(trackerEntryStatus);
emit dataChanged(trackerIndex, index(trackerRow, (columnCount() - 1)));
}
@@ -697,10 +696,10 @@ QModelIndex TrackerListModel::parent(const QModelIndex &index) const
void TrackerListModel::onTrackersAdded(const QList<BitTorrent::TrackerEntry> &newTrackers)
{
const auto row = rowCount();
const int row = rowCount();
beginInsertRows({}, row, (row + newTrackers.size() - 1));
for (const BitTorrent::TrackerEntry &trackerEntry : newTrackers)
addTrackerItem(trackerEntry);
for (const BitTorrent::TrackerEntry &entry : newTrackers)
addTrackerItem({entry.url, entry.tier});
endInsertRows();
}
@@ -727,18 +726,18 @@ void TrackerListModel::onTrackersChanged()
trackerItemIDs.insert(m_items->at(i)->name);
QList<std::shared_ptr<Item>> newTrackerItems;
for (const BitTorrent::TrackerEntry &trackerEntry : m_torrent->trackers())
for (const BitTorrent::TrackerEntryStatus &trackerEntryStatus : m_torrent->trackers())
{
trackerItemIDs.insert(trackerEntry.url);
trackerItemIDs.insert(trackerEntryStatus.url);
auto &itemsByName = m_items->get<ByName>();
if (const auto &iter = itemsByName.find(trackerEntry.url); iter != itemsByName.end())
if (const auto &iter = itemsByName.find(trackerEntryStatus.url); iter != itemsByName.end())
{
updateTrackerItem(*iter, trackerEntry);
updateTrackerItem(*iter, trackerEntryStatus);
}
else
{
newTrackerItems.emplace_back(createTrackerItem(trackerEntry));
newTrackerItems.emplace_back(createTrackerItem(trackerEntryStatus));
}
}
@@ -760,7 +759,7 @@ void TrackerListModel::onTrackersChanged()
if (!newTrackerItems.isEmpty())
{
const auto numRows = rowCount();
const int numRows = rowCount();
beginInsertRows({}, numRows, (numRows + newTrackerItems.size() - 1));
for (const auto &newTrackerItem : asConst(newTrackerItems))
m_items->get<0>().push_back(newTrackerItem);
@@ -768,14 +767,14 @@ void TrackerListModel::onTrackersChanged()
}
}
void TrackerListModel::onTrackersUpdated(const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackers)
void TrackerListModel::onTrackersUpdated(const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers)
{
for (const auto &[url, entry] : updatedTrackers.asKeyValueRange())
for (const auto &[url, tracker] : updatedTrackers.asKeyValueRange())
{
auto &itemsByName = m_items->get<ByName>();
if (const auto &iter = itemsByName.find(entry.url); iter != itemsByName.end()) [[likely]]
if (const auto &iter = itemsByName.find(tracker.url); iter != itemsByName.end()) [[likely]]
{
updateTrackerItem(*iter, entry);
updateTrackerItem(*iter, tracker);
}
}
}

View File

@@ -35,7 +35,7 @@
#include <QAbstractItemModel>
#include <QDateTime>
#include "base/bittorrent/trackerentry.h"
#include "base/bittorrent/trackerentrystatus.h"
class QTimer;
@@ -43,6 +43,7 @@ namespace BitTorrent
{
class Session;
class Torrent;
struct TrackerEntry;
}
class TrackerListModel final : public QAbstractItemModel
@@ -99,14 +100,14 @@ private:
struct Item;
void populate();
std::shared_ptr<Item> createTrackerItem(const BitTorrent::TrackerEntry &trackerEntry);
void addTrackerItem(const BitTorrent::TrackerEntry &trackerEntry);
void updateTrackerItem(const std::shared_ptr<Item> &item, const BitTorrent::TrackerEntry &trackerEntry);
std::shared_ptr<Item> createTrackerItem(const BitTorrent::TrackerEntryStatus &trackerEntryStatus);
void addTrackerItem(const BitTorrent::TrackerEntryStatus &trackerEntryStatus);
void updateTrackerItem(const std::shared_ptr<Item> &item, const BitTorrent::TrackerEntryStatus &trackerEntryStatus);
void refreshAnnounceTimes();
void onTrackersAdded(const QList<BitTorrent::TrackerEntry> &newTrackers);
void onTrackersRemoved(const QStringList &deletedTrackers);
void onTrackersChanged();
void onTrackersUpdated(const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackers);
void onTrackersUpdated(const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers);
BitTorrent::Session *m_btSession = nullptr;
BitTorrent::Torrent *m_torrent = nullptr;

View File

@@ -47,7 +47,7 @@
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentry.h"
#include "base/bittorrent/trackerentrystatus.h"
#include "base/global.h"
#include "base/preferences.h"
#include "gui/autoexpandabledialog.h"
@@ -142,52 +142,68 @@ QModelIndexList TrackerListWidget::getSelectedTrackerRows() const
void TrackerListWidget::decreaseSelectedTrackerTiers()
{
const auto &trackerIndexes = getSelectedTrackerRows();
const QModelIndexList trackerIndexes = getSelectedTrackerRows();
if (trackerIndexes.isEmpty())
return;
QSet<QString> trackerURLs;
trackerURLs.reserve(trackerIndexes.size());
for (const QModelIndex &index : trackerIndexes)
{
trackerURLs.insert(index.siblingAtColumn(TrackerListModel::COL_URL).data().toString());
}
QList<BitTorrent::TrackerEntry> trackers = m_model->torrent()->trackers();
for (BitTorrent::TrackerEntry &trackerEntry : trackers)
const QList<BitTorrent::TrackerEntryStatus> trackers = m_model->torrent()->trackers();
QList<BitTorrent::TrackerEntry> adjustedTrackers;
adjustedTrackers.reserve(trackers.size());
for (const BitTorrent::TrackerEntryStatus &status : trackers)
{
if (trackerURLs.contains(trackerEntry.url))
BitTorrent::TrackerEntry entry
{
if (trackerEntry.tier > 0)
--trackerEntry.tier;
.url = status.url,
.tier = status.tier
};
if (trackerURLs.contains(entry.url))
{
if (entry.tier > 0)
--entry.tier;
}
adjustedTrackers.append(entry);
}
m_model->torrent()->replaceTrackers(trackers);
m_model->torrent()->replaceTrackers(adjustedTrackers);
}
void TrackerListWidget::increaseSelectedTrackerTiers()
{
const auto &trackerIndexes = getSelectedTrackerRows();
const QModelIndexList trackerIndexes = getSelectedTrackerRows();
if (trackerIndexes.isEmpty())
return;
QSet<QString> trackerURLs;
trackerURLs.reserve(trackerIndexes.size());
for (const QModelIndex &index : trackerIndexes)
{
trackerURLs.insert(index.siblingAtColumn(TrackerListModel::COL_URL).data().toString());
}
QList<BitTorrent::TrackerEntry> trackers = m_model->torrent()->trackers();
for (BitTorrent::TrackerEntry &trackerEntry : trackers)
const QList<BitTorrent::TrackerEntryStatus> trackers = m_model->torrent()->trackers();
QList<BitTorrent::TrackerEntry> adjustedTrackers;
adjustedTrackers.reserve(trackers.size());
for (const BitTorrent::TrackerEntryStatus &status : trackers)
{
if (trackerURLs.contains(trackerEntry.url))
BitTorrent::TrackerEntry entry
{
if (trackerEntry.tier < std::numeric_limits<decltype(trackerEntry.tier)>::max())
++trackerEntry.tier;
.url = status.url,
.tier = status.tier
};
if (trackerURLs.contains(entry.url))
{
if (entry.tier < std::numeric_limits<decltype(entry.tier)>::max())
++entry.tier;
}
adjustedTrackers.append(entry);
}
m_model->torrent()->replaceTrackers(trackers);
m_model->torrent()->replaceTrackers(adjustedTrackers);
}
void TrackerListWidget::openAddTrackersDialog()
@@ -205,7 +221,7 @@ void TrackerListWidget::copyTrackerUrl()
if (!torrent())
return;
const auto &selectedTrackerIndexes = getSelectedTrackerRows();
const QModelIndexList selectedTrackerIndexes = getSelectedTrackerRows();
if (selectedTrackerIndexes.isEmpty())
return;
@@ -226,7 +242,7 @@ void TrackerListWidget::deleteSelectedTrackers()
if (!torrent())
return;
const auto &selectedTrackerIndexes = getSelectedTrackerRows();
const QModelIndexList selectedTrackerIndexes = getSelectedTrackerRows();
if (selectedTrackerIndexes.isEmpty())
return;
@@ -245,7 +261,7 @@ void TrackerListWidget::editSelectedTracker()
if (!torrent())
return;
const auto &selectedTrackerIndexes = getSelectedTrackerRows();
const QModelIndexList selectedTrackerIndexes = getSelectedTrackerRows();
if (selectedTrackerIndexes.isEmpty())
return;
@@ -268,24 +284,36 @@ void TrackerListWidget::editSelectedTracker()
if (newTrackerURL == trackerURL)
return;
QList<BitTorrent::TrackerEntry> trackers = torrent()->trackers();
const QList<BitTorrent::TrackerEntryStatus> trackers = torrent()->trackers();
QList<BitTorrent::TrackerEntry> entries;
entries.reserve(trackers.size());
bool match = false;
for (BitTorrent::TrackerEntry &entry : trackers)
for (const BitTorrent::TrackerEntryStatus &status : trackers)
{
if (newTrackerURL == QUrl(entry.url))
const QUrl url {status.url};
if (newTrackerURL == url)
{
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL already exists."));
return;
}
if (!match && (trackerURL == QUrl(entry.url)))
BitTorrent::TrackerEntry entry
{
.url = status.url,
.tier = status.tier
};
if (!match && (trackerURL == url))
{
match = true;
entry.url = newTrackerURL.toString();
}
entries.append(entry);
}
torrent()->replaceTrackers(trackers);
torrent()->replaceTrackers(entries);
}
void TrackerListWidget::reannounceSelected()
@@ -315,14 +343,12 @@ void TrackerListWidget::reannounceSelected()
trackerURLs.insert(index.siblingAtColumn(TrackerListModel::COL_URL).data().toString());
}
const QList<BitTorrent::TrackerEntry> &trackers = m_model->torrent()->trackers();
const QList<BitTorrent::TrackerEntryStatus> &trackers = m_model->torrent()->trackers();
for (qsizetype i = 0; i < trackers.size(); ++i)
{
const BitTorrent::TrackerEntry &trackerEntry = trackers.at(i);
if (trackerURLs.contains(trackerEntry.url))
{
const BitTorrent::TrackerEntryStatus &status = trackers.at(i);
if (trackerURLs.contains(status.url))
torrent()->forceReannounce(i);
}
}
}

View File

@@ -38,6 +38,8 @@
#include "base/algorithm.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/trackerentry.h"
#include "base/bittorrent/trackerentrystatus.h"
#include "base/global.h"
#include "base/net/downloadmanager.h"
#include "base/preferences.h"
@@ -202,16 +204,15 @@ void TrackersFilterWidget::refreshTrackers(const BitTorrent::Torrent *torrent)
return false;
});
const QVector<BitTorrent::TrackerEntry> trackerEntries = torrent->trackers();
const bool isTrackerless = trackerEntries.isEmpty();
if (isTrackerless)
const QVector<BitTorrent::TrackerEntryStatus> trackers = torrent->trackers();
if (trackers.isEmpty())
{
addItems(NULL_HOST, {torrentID});
}
else
{
for (const BitTorrent::TrackerEntry &trackerEntry : trackerEntries)
addItems(trackerEntry.url, {torrentID});
for (const BitTorrent::TrackerEntryStatus &status : trackers)
addItems(status.url, {torrentID});
}
item(OTHERERROR_ROW)->setText(formatItemText(OTHERERROR_ROW, m_errors.size()));
@@ -380,8 +381,8 @@ void TrackersFilterWidget::setDownloadTrackerFavicon(bool value)
}
}
void TrackersFilterWidget::handleTrackerEntriesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackerEntries)
void TrackersFilterWidget::handleTrackerStatusesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers)
{
const BitTorrent::TorrentID id = torrent->id();
@@ -389,51 +390,51 @@ void TrackersFilterWidget::handleTrackerEntriesUpdated(const BitTorrent::Torrent
auto trackerErrorHashesIt = m_trackerErrors.find(id);
auto warningHashesIt = m_warnings.find(id);
for (const BitTorrent::TrackerEntry &trackerEntry : updatedTrackerEntries)
for (const BitTorrent::TrackerEntryStatus &trackerEntryStatus : updatedTrackers)
{
if (trackerEntry.status == BitTorrent::TrackerEntryStatus::Working)
if (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::Working)
{
if (errorHashesIt != m_errors.end())
{
errorHashesIt->remove(trackerEntry.url);
errorHashesIt->remove(trackerEntryStatus.url);
}
if (trackerErrorHashesIt != m_trackerErrors.end())
{
trackerErrorHashesIt->remove(trackerEntry.url);
trackerErrorHashesIt->remove(trackerEntryStatus.url);
}
const bool hasNoWarningMessages = std::all_of(trackerEntry.endpointEntries.cbegin(), trackerEntry.endpointEntries.cend()
, [](const BitTorrent::TrackerEndpointEntry &endpointEntry)
const bool hasNoWarningMessages = std::all_of(trackerEntryStatus.endpoints.cbegin(), trackerEntryStatus.endpoints.cend()
, [](const BitTorrent::TrackerEndpointStatus &endpointEntry)
{
return endpointEntry.message.isEmpty() || (endpointEntry.status != BitTorrent::TrackerEntryStatus::Working);
return endpointEntry.message.isEmpty() || (endpointEntry.state != BitTorrent::TrackerEndpointState::Working);
});
if (hasNoWarningMessages)
{
if (warningHashesIt != m_warnings.end())
{
warningHashesIt->remove(trackerEntry.url);
warningHashesIt->remove(trackerEntryStatus.url);
}
}
else
{
if (warningHashesIt == m_warnings.end())
warningHashesIt = m_warnings.insert(id, {});
warningHashesIt->insert(trackerEntry.url);
warningHashesIt->insert(trackerEntryStatus.url);
}
}
else if ((trackerEntry.status == BitTorrent::TrackerEntryStatus::NotWorking)
|| (trackerEntry.status == BitTorrent::TrackerEntryStatus::Unreachable))
else if ((trackerEntryStatus.state == BitTorrent::TrackerEndpointState::NotWorking)
|| (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::Unreachable))
{
if (errorHashesIt == m_errors.end())
errorHashesIt = m_errors.insert(id, {});
errorHashesIt->insert(trackerEntry.url);
errorHashesIt->insert(trackerEntryStatus.url);
}
else if (trackerEntry.status == BitTorrent::TrackerEntryStatus::TrackerError)
else if (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::TrackerError)
{
if (trackerErrorHashesIt == m_trackerErrors.end())
trackerErrorHashesIt = m_trackerErrors.insert(id, {});
trackerErrorHashesIt->insert(trackerEntry.url);
trackerErrorHashesIt->insert(trackerEntryStatus.url);
}
}
@@ -481,10 +482,10 @@ void TrackersFilterWidget::removeTracker(const QString &tracker)
continue;
QStringList trackersToRemove;
for (const BitTorrent::TrackerEntry &trackerEntry : asConst(torrent->trackers()))
for (const BitTorrent::TrackerEntryStatus &trackerEntryStatus : asConst(torrent->trackers()))
{
if ((trackerEntry.url == tracker) || (QUrl(trackerEntry.url).host() == tracker))
trackersToRemove.append(trackerEntry.url);
if ((trackerEntryStatus.url == tracker) || (QUrl(trackerEntryStatus.url).host() == tracker))
trackersToRemove.append(trackerEntryStatus.url);
}
torrent->removeTrackers({trackersToRemove});
@@ -592,8 +593,8 @@ void TrackersFilterWidget::handleTorrentsLoaded(const QVector<BitTorrent::Torren
for (const BitTorrent::Torrent *torrent : torrents)
{
const BitTorrent::TorrentID torrentID = torrent->id();
const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
for (const BitTorrent::TrackerEntry &tracker : trackers)
const QVector<BitTorrent::TrackerEntryStatus> trackers = torrent->trackers();
for (const BitTorrent::TrackerEntryStatus &tracker : trackers)
torrentsPerTracker[tracker.url].append(torrentID);
// Check for trackerless torrent
@@ -613,8 +614,8 @@ void TrackersFilterWidget::handleTorrentsLoaded(const QVector<BitTorrent::Torren
void TrackersFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
{
const BitTorrent::TorrentID torrentID = torrent->id();
const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
for (const BitTorrent::TrackerEntry &tracker : trackers)
const QVector<BitTorrent::TrackerEntryStatus> trackers = torrent->trackers();
for (const BitTorrent::TrackerEntryStatus &tracker : trackers)
removeItem(tracker.url, torrentID);
// Check for trackerless torrent

View File

@@ -32,12 +32,17 @@
#include <QtContainerFwd>
#include <QHash>
#include "base/bittorrent/trackerentry.h"
#include "base/path.h"
#include "basefilterwidget.h"
class TransferListWidget;
namespace BitTorrent
{
struct TrackerEntry;
struct TrackerEntryStatus;
}
namespace Net
{
struct DownloadResult;
@@ -55,8 +60,8 @@ public:
void addTrackers(const BitTorrent::Torrent *torrent, const QVector<BitTorrent::TrackerEntry> &trackers);
void removeTrackers(const BitTorrent::Torrent *torrent, const QStringList &trackers);
void refreshTrackers(const BitTorrent::Torrent *torrent);
void handleTrackerEntriesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackerEntries);
void handleTrackerStatusesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers);
void setDownloadTrackerFavicon(bool value);
private slots:

View File

@@ -42,6 +42,7 @@
#include "base/algorithm.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentrystatus.h"
#include "base/global.h"
#include "base/logger.h"
#include "base/net/downloadmanager.h"
@@ -191,10 +192,10 @@ void TransferListFiltersWidget::refreshTrackers(const BitTorrent::Torrent *torre
m_trackersFilterWidget->refreshTrackers(torrent);
}
void TransferListFiltersWidget::trackerEntriesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackerEntries)
void TransferListFiltersWidget::trackerEntryStatusesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers)
{
m_trackersFilterWidget->handleTrackerEntriesUpdated(torrent, updatedTrackerEntries);
m_trackersFilterWidget->handleTrackerStatusesUpdated(torrent, updatedTrackers);
}
void TransferListFiltersWidget::onCategoryFilterStateChanged(bool enabled)

View File

@@ -30,10 +30,8 @@
#pragma once
#include <QtContainerFwd>
#include <QHash>
#include <QWidget>
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentry.h"
class CategoryFilterWidget;
@@ -42,6 +40,12 @@ class TagFilterWidget;
class TrackersFilterWidget;
class TransferListWidget;
namespace BitTorrent
{
class Torrent;
struct TrackerEntryStatus;
}
class TransferListFiltersWidget final : public QWidget
{
Q_OBJECT
@@ -55,8 +59,8 @@ public slots:
void addTrackers(const BitTorrent::Torrent *torrent, const QVector<BitTorrent::TrackerEntry> &trackers);
void removeTrackers(const BitTorrent::Torrent *torrent, const QStringList &trackers);
void refreshTrackers(const BitTorrent::Torrent *torrent);
void trackerEntriesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntry> &updatedTrackerEntries);
void trackerEntryStatusesUpdated(const BitTorrent::Torrent *torrent
, const QHash<QString, BitTorrent::TrackerEntryStatus> &updatedTrackers);
private slots:
void onCategoryFilterStateChanged(bool enabled);

View File

@@ -45,7 +45,7 @@
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentry.h"
#include "base/bittorrent/trackerentrystatus.h"
#include "base/global.h"
#include "base/logger.h"
#include "base/path.h"
@@ -783,14 +783,14 @@ void TransferListWidget::editTorrentTrackers()
if (!torrents.empty())
{
commonTrackers = torrents[0]->trackers();
for (const BitTorrent::TrackerEntryStatus &status : asConst(torrents[0]->trackers()))
commonTrackers.append({.url = status.url, .tier = status.tier});
for (const BitTorrent::Torrent *torrent : torrents)
{
QSet<BitTorrent::TrackerEntry> trackerSet;
for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers()))
trackerSet.insert(entry);
for (const BitTorrent::TrackerEntryStatus &status : asConst(torrent->trackers()))
trackerSet.insert({.url = status.url, .tier = status.tier});
commonTrackers.erase(std::remove_if(commonTrackers.begin(), commonTrackers.end()
, [&trackerSet](const BitTorrent::TrackerEntry &entry) { return !trackerSet.contains(entry); })