From e5ea799d3f8b0ed001e85d8d68f3866ae050c24a Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Fri, 4 Jul 2025 14:52:51 -0700 Subject: [PATCH] WebAPI: Support setting tracker tier --- WebAPI_Changelog.md | 4 ++ src/webui/api/torrentscontroller.cpp | 53 +++++++++++++++++++------- src/webui/www/private/edittracker.html | 2 +- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/WebAPI_Changelog.md b/WebAPI_Changelog.md index 2345df422..2cb5fe033 100644 --- a/WebAPI_Changelog.md +++ b/WebAPI_Changelog.md @@ -6,6 +6,10 @@ * `endpoints` is an array of tracker endpoints, each with `name`, `updating`, `status`, `msg`, `bt_version`, `num_peers`, `num_peers`, `num_leeches`, `num_downloaded`, `next_announce` and `min_announce` fields * `torrents/trackers` now returns `5` and `6` in `status` field as possible values * `5` for `Tracker error` and `6` for `Unreachable` +* [#22963](https://github.com/qbittorrent/qBittorrent/pull/22963) + * `torrents/editTracker` endpoint now supports setting a tracker's tier via `tier` parameter + * `torrents/editTracker` endpoint always responds with a 204 when successful + * `torrents/editTracker` endpoint `origUrl` parameter renamed to `url` ## 2.12.1 * [#23031](https://github.com/qbittorrent/qBittorrent/pull/23031) diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 1df3a820c..e1af67a81 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -1160,22 +1160,44 @@ void TorrentsController::addTrackersAction() void TorrentsController::editTrackerAction() { - requireParams({u"hash"_s, u"origUrl"_s, u"newUrl"_s}); + requireParams({u"hash"_s, u"url"_s}); const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_s]); - const QString origUrl = params()[u"origUrl"_s]; - const QString newUrl = params()[u"newUrl"_s]; + const QString origUrl = params()[u"url"_s]; + const std::optional newUrlParam = getOptionalString(params(), u"newUrl"_s); + const std::optional newTierParam = getOptionalString(params(), u"tier"_s); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->getTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); + if (!newUrlParam && !newTierParam) + throw APIError(APIErrorType::BadParams, tr("Must specify at least one of [newUrl, tier]")); + + std::optional newTier; + if (newTierParam) + { + bool ok = false; + const auto number = newTierParam.value().toInt(&ok); + if (!ok) + throw APIError(APIErrorType::BadParams, tr("tier must be an integer")); + if ((number < 0) || (number > 255)) + throw APIError(APIErrorType::BadParams, tr("tier must be between 0 and 255")); + newTier = number; + } const QUrl origTrackerUrl {origUrl}; - const QUrl newTrackerUrl {newUrl}; - if (origTrackerUrl == newTrackerUrl) + std::optional newTrackerUrl; + if (newUrlParam) + { + const QUrl url = newUrlParam.value(); + if (!url.isValid()) + throw APIError(APIErrorType::BadParams, tr("New tracker URL is invalid")); + if (url != origTrackerUrl) + newTrackerUrl = url; + } + + if (!newTrackerUrl && !newTier) return; - if (!newTrackerUrl.isValid()) - throw APIError(APIErrorType::BadParams, u"New tracker URL is invalid"_s); const QList currentTrackers = torrent->trackers(); QList entries; @@ -1186,8 +1208,8 @@ void TorrentsController::editTrackerAction() { const QUrl trackerUrl {tracker.url}; - if (trackerUrl == newTrackerUrl) - throw APIError(APIErrorType::Conflict, u"New tracker URL already exists"_s); + if (newTrackerUrl && (trackerUrl == newTrackerUrl)) + throw APIError(APIErrorType::Conflict, tr("New tracker URL already exists")); BitTorrent::TrackerEntry entry { @@ -1197,18 +1219,23 @@ void TorrentsController::editTrackerAction() if (trackerUrl == origTrackerUrl) { + const bool isTrackerTierChanged = newTier && (tracker.tier != newTier); + if (!newTrackerUrl && !isTrackerTierChanged) + return; + match = true; - entry.url = newTrackerUrl.toString(); + if (newTrackerUrl) + entry.url = newTrackerUrl.value().toString(); + if (newTier) + entry.tier = newTier.value(); } entries.append(entry); } if (!match) - throw APIError(APIErrorType::Conflict, u"Tracker not found"_s); + throw APIError(APIErrorType::Conflict, tr("Tracker not found")); torrent->replaceTrackers(entries); torrent->forceReannounce(); - - setResult(QString()); } void TorrentsController::removeTrackersAction() diff --git a/src/webui/www/private/edittracker.html b/src/webui/www/private/edittracker.html index b5aff329d..aece2fb28 100644 --- a/src/webui/www/private/edittracker.html +++ b/src/webui/www/private/edittracker.html @@ -40,7 +40,7 @@ method: "POST", body: new URLSearchParams({ hash: searchParams.get("hash"), - origUrl: currentUrl, + url: currentUrl, newUrl: document.getElementById("trackerUrl").value }) })