Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAPI: optionally include trackers list in torrent info response #22128

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 42 additions & 21 deletions src/webui/api/torrentscontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const QString KEY_PROP_SSL_PRIVATEKEY = u"ssl_private_key"_s;
const QString KEY_PROP_SSL_DHPARAMS = u"ssl_dh_params"_s;
const QString KEY_PROP_HAS_METADATA = u"has_metadata"_s;
const QString KEY_PROP_PROGRESS = u"progress"_s;
const QString KEY_PROP_TRACKERS = u"trackers"_s;


// File keys
Expand Down Expand Up @@ -248,6 +249,31 @@ namespace
return {dht, pex, lsd};
}

QJsonArray getTrackers(const BitTorrent::Torrent *const torrent)
{
QJsonArray trackerList;

for (const BitTorrent::TrackerEntryStatus &tracker : asConst(torrent->trackers()))
{
const bool isNotWorking = (tracker.state == BitTorrent::TrackerEndpointState::NotWorking)
|| (tracker.state == BitTorrent::TrackerEndpointState::TrackerError)
|| (tracker.state == BitTorrent::TrackerEndpointState::Unreachable);
trackerList << QJsonObject
{
{KEY_TRACKER_URL, tracker.url},
{KEY_TRACKER_TIER, tracker.tier},
{KEY_TRACKER_STATUS, static_cast<int>((isNotWorking ? BitTorrent::TrackerEndpointState::NotWorking : tracker.state))},
{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}
};
}

return trackerList;
}

QList<BitTorrent::TorrentID> toTorrentIDs(const QStringList &idStrings)
{
QList<BitTorrent::TorrentID> idList;
Expand Down Expand Up @@ -304,6 +330,7 @@ void TorrentsController::countAction()
// - tag (string): torrent tag for filtering by it (empty string means "untagged"; no "tag" param presented means "any tag")
// - hashes (string): filter by hashes, can contain multiple hashes separated by |
// - private (bool): filter torrents that are from private trackers (true) or not (false). Empty means any torrent (no filtering)
// - includeTrackers (bool): include trackers in list output (true) or not (false). Empty means not included
// - sort (string): name of column for sorting by its value
// - reverse (bool): enable reverse sorting
// - limit (int): set limit number of torrents returned (if greater than 0, otherwise - unlimited)
Expand All @@ -319,6 +346,7 @@ void TorrentsController::infoAction()
int offset {params()[u"offset"_s].toInt()};
const QStringList hashes {params()[u"hashes"_s].split(u'|', Qt::SkipEmptyParts)};
const std::optional<bool> isPrivate = parseBool(params()[u"private"_s]);
const bool includeTrackers = parseBool(params()[u"includeTrackers"_s]).value_or(false);

std::optional<TorrentIDSet> idSet;
if (!hashes.isEmpty())
Expand All @@ -332,8 +360,15 @@ void TorrentsController::infoAction()
QVariantList torrentList;
for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents()))
{
if (torrentFilter.match(torrent))
torrentList.append(serialize(*torrent));
if (!torrentFilter.match(torrent))
continue;

QVariantMap serializedTorrent = serialize(*torrent);

if (includeTrackers)
serializedTorrent.insert(KEY_PROP_TRACKERS, getTrackers(torrent));

torrentList.append(serializedTorrent);
}

if (torrentList.isEmpty())
Expand Down Expand Up @@ -531,27 +566,13 @@ void TorrentsController::trackersAction()
if (!torrent)
throw APIError(APIErrorType::NotFound);

QJsonArray trackerList = getStickyTrackers(torrent);
QJsonArray trackersList = getStickyTrackers(torrent);

for (const BitTorrent::TrackerEntryStatus &tracker : asConst(torrent->trackers()))
{
const bool isNotWorking = (tracker.state == BitTorrent::TrackerEndpointState::NotWorking)
|| (tracker.state == BitTorrent::TrackerEndpointState::TrackerError)
|| (tracker.state == BitTorrent::TrackerEndpointState::Unreachable);
trackerList << QJsonObject
{
{KEY_TRACKER_URL, tracker.url},
{KEY_TRACKER_TIER, tracker.tier},
{KEY_TRACKER_STATUS, static_cast<int>((isNotWorking ? BitTorrent::TrackerEndpointState::NotWorking : tracker.state))},
{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}
};
}
// merge QJsonArray
for (const auto &tracker : asConst(getTrackers(torrent)))
trackersList.append(tracker);

setResult(trackerList);
setResult(trackersList);
}

// Returns the web seeds for a torrent in JSON format.
Expand Down
Loading