mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-08-19 04:49:47 -07:00
WebUI: Add support for tracker status filter
This commit is contained in:
parent
e309b17732
commit
44bb1ac7eb
10 changed files with 79 additions and 16 deletions
|
@ -500,6 +500,9 @@ void SyncController::updateFreeDiskSpace(const qint64 freeDiskSpace)
|
||||||
// - "seen_complete": Indicates the time when the torrent was last seen complete/whole
|
// - "seen_complete": Indicates the time when the torrent was last seen complete/whole
|
||||||
// - "last_activity": Last time when a chunk was downloaded/uploaded
|
// - "last_activity": Last time when a chunk was downloaded/uploaded
|
||||||
// - "total_size": Size including unwanted data
|
// - "total_size": Size including unwanted data
|
||||||
|
// - "has_tracker_warning": the torrent has working tracker that has a message
|
||||||
|
// - "has_tracker_error": the torrent has a tracker error
|
||||||
|
// - "has_other_announce_error": the torrent has other problems announcing to a tracker
|
||||||
// Server state map may contain the following keys:
|
// Server state map may contain the following keys:
|
||||||
// - "connection_status": connection status
|
// - "connection_status": connection status
|
||||||
// - "dht_nodes": DHT nodes count
|
// - "dht_nodes": DHT nodes count
|
||||||
|
|
1
src/webui/www/private/images/tracker-error.svg
Normal file
1
src/webui/www/private/images/tracker-error.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m16.000002 1c-6.3509517 0-11.5000025 4.7958103-11.5000025 10.711067 0 .369709.033485.710286.072579 1.070355.031509.358271.083753.723168.1451609 1.074112 1.316651 7.528273 6.6824576 12.860221 11.2822626 17.144466 4.599805-4.284245 9.965566-9.61598 11.282261-17.144466.061409-.350944.113619-.715841.145157-1.074112.03932-.360069.07258-.700646.07258-1.070355 0-5.9152567-5.149052-10.711067-11.499998-10.711067zm0 6.4296445c2.540473 0 4.600808 1.9152985 4.600808 4.2814225s-2.060404 4.285178-4.600808 4.285178-4.600807-1.919054-4.600807-4.285178 2.060403-4.2814225 4.600807-4.2814225z" fill="#f00" stroke-width="2.59043"/></svg>
|
After Width: | Height: | Size: 716 B |
1
src/webui/www/private/images/tracker-warning.svg
Normal file
1
src/webui/www/private/images/tracker-warning.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m16.000002 1c-6.3509517 0-11.5000025 4.7958103-11.5000025 10.711067 0 .369709.033485.710286.072579 1.070355.031509.358271.083753.723168.1451609 1.074112 1.316651 7.528273 6.6824576 12.860221 11.2822626 17.144466 4.599805-4.284245 9.965566-9.61598 11.282261-17.144466.061409-.350944.113619-.715841.145157-1.074112.03932-.360069.07258-.700646.07258-1.070355 0-5.9152567-5.149052-10.711067-11.499998-10.711067zm0 6.4296445c2.540473 0 4.600808 1.9152985 4.600808 4.2814225s-2.060404 4.285178-4.600808 4.285178-4.600807-1.919054-4.600807-4.285178 2.060403-4.2814225 4.600807-4.2814225z" fill="#ff8c00" stroke-width="2.59043"/></svg>
|
After Width: | Height: | Size: 719 B |
1
src/webui/www/private/images/trackerless.svg
Normal file
1
src/webui/www/private/images/trackerless.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m16.000002 1c-6.3509517 0-11.5000025 4.7958103-11.5000025 10.711067 0 .369709.033485.710286.072579 1.070355.031509.358271.083753.723168.1451609 1.074112 1.316651 7.528273 6.6824576 12.860221 11.2822626 17.144466 4.599805-4.284245 9.965566-9.61598 11.282261-17.144466.061409-.350944.113619-.715841.145157-1.074112.03932-.360069.07258-.700646.07258-1.070355 0-5.9152567-5.149052-10.711067-11.499998-10.711067zm0 6.4296445c2.540473 0 4.600808 1.9152985 4.600808 4.2814225s-2.060404 4.285178-4.600808 4.285178-4.600807-1.919054-4.600807-4.285178 2.060403-4.2814225 4.600807-4.2814225z" fill="#808080" stroke-width="2.59043"/></svg>
|
After Width: | Height: | Size: 719 B |
|
@ -161,7 +161,10 @@ let setTagFilter = () => {};
|
||||||
|
|
||||||
/* Trackers filter */
|
/* Trackers filter */
|
||||||
const TRACKERS_ALL = "b4af0e4c-e76d-4bac-a392-46cbc18d9655";
|
const TRACKERS_ALL = "b4af0e4c-e76d-4bac-a392-46cbc18d9655";
|
||||||
|
const TRACKERS_ANNOUNCE_ERROR = "d0b4cad2-9f6f-4e7f-8d4b-f80a103dd436";
|
||||||
|
const TRACKERS_ERROR = "b551cfc3-64e9-4393-bc88-5d6ea2fab5cc";
|
||||||
const TRACKERS_TRACKERLESS = "e24bd469-ea22-404c-8e2e-a17c82f37ea0";
|
const TRACKERS_TRACKERLESS = "e24bd469-ea22-404c-8e2e-a17c82f37ea0";
|
||||||
|
const TRACKERS_WARNING = "82a702c5-210c-412b-829f-97632d7557e9";
|
||||||
|
|
||||||
// Map<trackerHost: String, Map<trackerURL: String, torrents: Set>>
|
// Map<trackerHost: String, Map<trackerURL: String, torrents: Set>>
|
||||||
const trackerMap = new Map();
|
const trackerMap = new Map();
|
||||||
|
@ -685,17 +688,41 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||||
const span = trackerFilterItem.firstElementChild;
|
const span = trackerFilterItem.firstElementChild;
|
||||||
span.lastChild.textContent = `${text} (${count})`;
|
span.lastChild.textContent = `${text} (${count})`;
|
||||||
|
|
||||||
|
switch (host) {
|
||||||
|
case TRACKERS_ANNOUNCE_ERROR:
|
||||||
|
case TRACKERS_ERROR:
|
||||||
|
span.lastElementChild.src = "images/tracker-error.svg";
|
||||||
|
break;
|
||||||
|
case TRACKERS_TRACKERLESS:
|
||||||
|
span.lastElementChild.src = "images/trackerless.svg";
|
||||||
|
break;
|
||||||
|
case TRACKERS_WARNING:
|
||||||
|
span.lastElementChild.src = "images/tracker-warning.svg";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return trackerFilterItem;
|
return trackerFilterItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
let trackerlessTorrentsCount = 0;
|
let trackerlessCount = 0;
|
||||||
for (const { full_data: { trackers_count: trackersCount } } of torrentsTable.getRowValues()) {
|
let trackerErrorCount = 0;
|
||||||
if (trackersCount === 0)
|
let announceErrorCount = 0;
|
||||||
trackerlessTorrentsCount += 1;
|
let trackerWarningCount = 0;
|
||||||
|
for (const { full_data } of torrentsTable.getRowValues()) {
|
||||||
|
if (full_data.trackers_count === 0)
|
||||||
|
trackerlessCount += 1;
|
||||||
|
|
||||||
|
// counting bools by adding them
|
||||||
|
trackerErrorCount += full_data.has_tracker_error;
|
||||||
|
announceErrorCount += full_data.has_other_announce_error;
|
||||||
|
trackerWarningCount += full_data.has_tracker_warning;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackerFilterList.appendChild(createLink(TRACKERS_ALL, "QBT_TR(All)QBT_TR[CONTEXT=TrackerFiltersList]", torrentsTable.getRowSize()));
|
trackerFilterList.appendChild(createLink(TRACKERS_ALL, "QBT_TR(All)QBT_TR[CONTEXT=TrackerFiltersList]", torrentsTable.getRowSize()));
|
||||||
trackerFilterList.appendChild(createLink(TRACKERS_TRACKERLESS, "QBT_TR(Trackerless)QBT_TR[CONTEXT=TrackerFiltersList]", trackerlessTorrentsCount));
|
trackerFilterList.appendChild(createLink(TRACKERS_TRACKERLESS, "QBT_TR(Trackerless)QBT_TR[CONTEXT=TrackerFiltersList]", trackerlessCount));
|
||||||
|
trackerFilterList.appendChild(createLink(TRACKERS_ERROR, "QBT_TR(Tracker error)QBT_TR[CONTEXT=TrackerFiltersList]", trackerErrorCount));
|
||||||
|
trackerFilterList.appendChild(createLink(TRACKERS_ANNOUNCE_ERROR, "QBT_TR(Other error)QBT_TR[CONTEXT=TrackerFiltersList]", announceErrorCount));
|
||||||
|
trackerFilterList.appendChild(createLink(TRACKERS_WARNING, "QBT_TR(Warning)QBT_TR[CONTEXT=TrackerFiltersList]", trackerWarningCount));
|
||||||
|
|
||||||
// Sort trackers by hostname
|
// Sort trackers by hostname
|
||||||
const sortedList = [];
|
const sortedList = [];
|
||||||
|
|
|
@ -620,11 +620,18 @@ window.qBittorrent.ContextMenu ??= (() => {
|
||||||
|
|
||||||
class TrackersFilterContextMenu extends FilterListContextMenu {
|
class TrackersFilterContextMenu extends FilterListContextMenu {
|
||||||
updateMenuItems() {
|
updateMenuItems() {
|
||||||
const id = this.options.element.id;
|
switch (this.options.element.id) {
|
||||||
if ((id !== TRACKERS_ALL) && (id !== TRACKERS_TRACKERLESS))
|
case TRACKERS_ALL:
|
||||||
this.showItem("deleteTracker");
|
case TRACKERS_ANNOUNCE_ERROR:
|
||||||
else
|
case TRACKERS_ERROR:
|
||||||
this.hideItem("deleteTracker");
|
case TRACKERS_TRACKERLESS:
|
||||||
|
case TRACKERS_WARNING:
|
||||||
|
this.hideItem("deleteTracker");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.showItem("deleteTracker");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this.updateTorrentActions();
|
this.updateTorrentActions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1558,7 +1558,7 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter(row, filterName, category, tag, tracker, filterTerms) {
|
applyFilter(row, filterName, category, tag, trackerHost, filterTerms) {
|
||||||
const state = row["full_data"].state;
|
const state = row["full_data"].state;
|
||||||
let inactive = false;
|
let inactive = false;
|
||||||
|
|
||||||
|
@ -1666,17 +1666,32 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tracker) {
|
switch (trackerHost) {
|
||||||
case TRACKERS_ALL:
|
case TRACKERS_ALL:
|
||||||
break; // do nothing
|
break; // do nothing
|
||||||
|
|
||||||
|
case TRACKERS_ANNOUNCE_ERROR:
|
||||||
|
if (!row["full_data"]["has_other_announce_error"])
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRACKERS_ERROR:
|
||||||
|
if (!row["full_data"]["has_tracker_error"])
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
case TRACKERS_TRACKERLESS:
|
case TRACKERS_TRACKERLESS:
|
||||||
if (row["full_data"].trackers_count > 0)
|
if (row["full_data"].trackers_count > 0)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRACKERS_WARNING:
|
||||||
|
if (!row["full_data"]["has_tracker_warning"])
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
const trackerTorrentMap = trackerMap.get(tracker);
|
const trackerTorrentMap = trackerMap.get(trackerHost);
|
||||||
if (trackerTorrentMap !== undefined) {
|
if (trackerTorrentMap !== undefined) {
|
||||||
let found = false;
|
let found = false;
|
||||||
for (const torrents of trackerTorrentMap.values()) {
|
for (const torrents of trackerTorrentMap.values()) {
|
||||||
|
|
|
@ -1093,7 +1093,11 @@ const initializeWindows = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteTrackerFN = (trackerHost) => {
|
deleteTrackerFN = (trackerHost) => {
|
||||||
if ((trackerHost === TRACKERS_ALL) || (trackerHost === TRACKERS_TRACKERLESS))
|
if ((trackerHost === TRACKERS_ALL)
|
||||||
|
|| (trackerHost === TRACKERS_ANNOUNCE_ERROR)
|
||||||
|
|| (trackerHost === TRACKERS_ERROR)
|
||||||
|
|| (trackerHost === TRACKERS_TRACKERLESS)
|
||||||
|
|| (trackerHost === TRACKERS_WARNING))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const contentURL = new URL("confirmtrackerdeletion.html", window.location);
|
const contentURL = new URL("confirmtrackerdeletion.html", window.location);
|
||||||
|
|
|
@ -74,10 +74,11 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
|
||||||
torrentTrackersTable.clear();
|
|
||||||
|
|
||||||
const trackers = await response.json();
|
const trackers = await response.json();
|
||||||
if (trackers) {
|
if (trackers) {
|
||||||
|
torrentTrackersTable.clear();
|
||||||
|
|
||||||
trackers.each((tracker) => {
|
trackers.each((tracker) => {
|
||||||
let status;
|
let status;
|
||||||
switch (tracker.status) {
|
switch (tracker.status) {
|
||||||
|
@ -122,7 +123,7 @@ window.qBittorrent.PropTrackers ??= (() => {
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
clearTimeout(loadTrackersDataTimer);
|
clearTimeout(loadTrackersDataTimer);
|
||||||
loadTrackersDataTimer = loadTrackersData.delay(10000);
|
loadTrackersDataTimer = loadTrackersData.delay(window.qBittorrent.Client.getSyncMainDataInterval());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -372,6 +372,9 @@
|
||||||
<file>private/images/torrent-start-forced.svg</file>
|
<file>private/images/torrent-start-forced.svg</file>
|
||||||
<file>private/images/torrent-start.svg</file>
|
<file>private/images/torrent-start.svg</file>
|
||||||
<file>private/images/torrent-stop.svg</file>
|
<file>private/images/torrent-stop.svg</file>
|
||||||
|
<file>private/images/tracker-error.svg</file>
|
||||||
|
<file>private/images/tracker-warning.svg</file>
|
||||||
|
<file>private/images/trackerless.svg</file>
|
||||||
<file>private/images/trackers.svg</file>
|
<file>private/images/trackers.svg</file>
|
||||||
<file>private/images/upload.svg</file>
|
<file>private/images/upload.svg</file>
|
||||||
<file>private/images/view-categories.svg</file>
|
<file>private/images/view-categories.svg</file>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue