mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-08-20 21:33:27 -07:00
WebUI: Support reannouncing individual trackers
This commit is contained in:
parent
66f3cf7e67
commit
cf5c899a13
5 changed files with 72 additions and 3 deletions
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
* [#22932](https://github.com/qbittorrent/qBittorrent/pull/22932)
|
* [#22932](https://github.com/qbittorrent/qBittorrent/pull/22932)
|
||||||
* `torrents/categories` and `sync/maindata` now serialize categories' `downloadPath` to `null`, rather than `undefined`
|
* `torrents/categories` and `sync/maindata` now serialize categories' `downloadPath` to `null`, rather than `undefined`
|
||||||
|
* [#22954](https://github.com/qbittorrent/qBittorrent/pull/22954)
|
||||||
|
* `torrents/reannounce` supports specifying individual trackers via `trackers` field
|
||||||
|
|
||||||
## 2.11.9
|
## 2.11.9
|
||||||
|
|
||||||
|
|
|
@ -1618,10 +1618,30 @@ void TorrentsController::reannounceAction()
|
||||||
requireParams({u"hashes"_s});
|
requireParams({u"hashes"_s});
|
||||||
|
|
||||||
const QStringList hashes {params()[u"hashes"_s].split(u'|')};
|
const QStringList hashes {params()[u"hashes"_s].split(u'|')};
|
||||||
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent)
|
const QStringList urlsParam {params()[u"urls"_s].split(u'|', Qt::SkipEmptyParts)};
|
||||||
|
|
||||||
|
QSet<QString> urls;
|
||||||
|
urls.reserve(urlsParam.size());
|
||||||
|
for (const QString &urlStr : urlsParam)
|
||||||
|
urls << QUrl::fromPercentEncoding(urlStr.toLatin1());
|
||||||
|
|
||||||
|
applyToTorrents(hashes, [&urls](BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
torrent->forceReannounce();
|
if (urls.isEmpty())
|
||||||
torrent->forceDHTAnnounce();
|
{
|
||||||
|
torrent->forceReannounce();
|
||||||
|
torrent->forceDHTAnnounce();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const QList<BitTorrent::TrackerEntryStatus> &trackers = torrent->trackers();
|
||||||
|
for (qsizetype i = 0; i < trackers.size(); ++i)
|
||||||
|
{
|
||||||
|
const BitTorrent::TrackerEntryStatus &status = trackers.at(i);
|
||||||
|
if (urls.contains(status.url))
|
||||||
|
torrent->forceReannounce(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setResult(QString());
|
setResult(QString());
|
||||||
|
|
|
@ -248,6 +248,8 @@
|
||||||
<li class="separator"><a href="#EditTracker"><img src="images/edit-rename.svg" alt="QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
<li class="separator"><a href="#EditTracker"><img src="images/edit-rename.svg" alt="QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
<li><a href="#RemoveTracker"><img src="images/list-remove.svg" alt="QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
<li><a href="#RemoveTracker"><img src="images/list-remove.svg" alt="QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
<li><a href="#CopyTrackerUrl" id="CopyTrackerUrl"><img src="images/edit-copy.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
<li><a href="#CopyTrackerUrl" id="CopyTrackerUrl"><img src="images/edit-copy.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
|
<li><a href="#ReannounceTrackers" id="ReannounceTrackers"><img src="images/view-refresh.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Force reannounce to selected tracker(s))QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
|
<li class="separator"><a href="#ReannounceAllTrackers" id="ReannounceAllTrackers"><img src="images/view-refresh.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Force reannounce to all trackers)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul id="torrentPeersMenu" class="contextMenu">
|
<ul id="torrentPeersMenu" class="contextMenu">
|
||||||
<li><a href="#addPeer"><img src="images/peers-add.svg" alt="QBT_TR(Add peers...)QBT_TR[CONTEXT=PeerListWidget]"> QBT_TR(Add peers...)QBT_TR[CONTEXT=PeerListWidget]</a></li>
|
<li><a href="#addPeer"><img src="images/peers-add.svg" alt="QBT_TR(Add peers...)QBT_TR[CONTEXT=PeerListWidget]"> QBT_TR(Add peers...)QBT_TR[CONTEXT=PeerListWidget]</a></li>
|
||||||
|
|
|
@ -1818,6 +1818,11 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||||
onSelectedRowChanged() {
|
onSelectedRowChanged() {
|
||||||
updatePropertiesPanel();
|
updatePropertiesPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isStopped(hash) {
|
||||||
|
const row = this.getRow(hash);
|
||||||
|
return (row === undefined) ? true : row.full_data.state.includes("stopped");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TorrentPeersTable extends DynamicTable {
|
class TorrentPeersTable extends DynamicTable {
|
||||||
|
|
|
@ -148,6 +148,12 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
},
|
},
|
||||||
RemoveTracker: (element, ref) => {
|
RemoveTracker: (element, ref) => {
|
||||||
removeTrackerFN(element);
|
removeTrackerFN(element);
|
||||||
|
},
|
||||||
|
ReannounceTrackers: (element, ref) => {
|
||||||
|
reannounceTrackersFN(element, torrentTrackersTable.selectedRowsIds());
|
||||||
|
},
|
||||||
|
ReannounceAllTrackers: (element, ref) => {
|
||||||
|
reannounceTrackersFN(element, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
offsets: {
|
offsets: {
|
||||||
|
@ -164,6 +170,8 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
this.hideItem("EditTracker");
|
this.hideItem("EditTracker");
|
||||||
this.hideItem("RemoveTracker");
|
this.hideItem("RemoveTracker");
|
||||||
this.hideItem("CopyTrackerUrl");
|
this.hideItem("CopyTrackerUrl");
|
||||||
|
this.hideItem("ReannounceTrackers");
|
||||||
|
this.hideItem("ReannounceAllTrackers");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (selectedTrackers.length === 1)
|
if (selectedTrackers.length === 1)
|
||||||
|
@ -173,6 +181,16 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
|
|
||||||
this.showItem("RemoveTracker");
|
this.showItem("RemoveTracker");
|
||||||
this.showItem("CopyTrackerUrl");
|
this.showItem("CopyTrackerUrl");
|
||||||
|
|
||||||
|
const torrentHash = torrentsTable.getCurrentTorrentID();
|
||||||
|
if (torrentsTable.isStopped(torrentHash)) {
|
||||||
|
this.hideItem("ReannounceTrackers");
|
||||||
|
this.hideItem("ReannounceAllTrackers");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.showItem("ReannounceTrackers");
|
||||||
|
this.showItem("ReannounceAllTrackers");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -253,6 +271,28 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const reannounceTrackersFN = (element, trackers) => {
|
||||||
|
if (current_hash.length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const body = new URLSearchParams({
|
||||||
|
hashes: current_hash
|
||||||
|
});
|
||||||
|
if (trackers.length > 0)
|
||||||
|
body.set("urls", trackers.map(encodeURIComponent).join("|"));
|
||||||
|
|
||||||
|
fetch("api/v2/torrents/reannounce", {
|
||||||
|
method: "POST",
|
||||||
|
body: body
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok)
|
||||||
|
return;
|
||||||
|
|
||||||
|
updateData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const clear = () => {
|
const clear = () => {
|
||||||
torrentTrackersTable.clear();
|
torrentTrackersTable.clear();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue