WebUI: Allow to display only hostname in the Tracker column

It is now possible to display only hostname in the Tracker column.
Closes #11357.
PR #21243.
This commit is contained in:
skomerko 2024-09-01 10:34:49 +02:00 committed by GitHub
parent fc82abe7f6
commit 9d0fa213be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 68 additions and 47 deletions

View file

@ -31,7 +31,6 @@ window.qBittorrent.Client ??= (() => {
return { return {
closeWindow: closeWindow, closeWindow: closeWindow,
closeWindows: closeWindows, closeWindows: closeWindows,
genHash: genHash,
getSyncMainDataInterval: getSyncMainDataInterval, getSyncMainDataInterval: getSyncMainDataInterval,
isStopped: isStopped, isStopped: isStopped,
stop: stop, stop: stop,
@ -56,16 +55,6 @@ window.qBittorrent.Client ??= (() => {
MochaUI.closeAll(); MochaUI.closeAll();
}; };
const genHash = function(string) {
// origins:
// https://stackoverflow.com/a/8831937
// https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0
let hash = 0;
for (let i = 0; i < string.length; ++i)
hash = ((Math.imul(hash, 31) + string.charCodeAt(i)) | 0);
return hash;
};
const getSyncMainDataInterval = function() { const getSyncMainDataInterval = function() {
return customSyncMainDataInterval ? customSyncMainDataInterval : serverSyncMainDataInterval; return customSyncMainDataInterval ? customSyncMainDataInterval : serverSyncMainDataInterval;
}; };
@ -128,6 +117,7 @@ let serverSyncMainDataInterval = 1500;
let customSyncMainDataInterval = null; let customSyncMainDataInterval = null;
let useSubcategories = true; let useSubcategories = true;
const useAutoHideZeroStatusFilters = LocalPreferences.get("hide_zero_status_filters", "false") === "true"; const useAutoHideZeroStatusFilters = LocalPreferences.get("hide_zero_status_filters", "false") === "true";
const displayFullURLTrackerColumn = LocalPreferences.get("full_url_tracker_column", "false") === "true";
/* Categories filter */ /* Categories filter */
const CATEGORIES_ALL = 1; const CATEGORIES_ALL = 1;
@ -357,7 +347,7 @@ window.addEventListener("DOMContentLoaded", () => {
return true; return true;
} }
const categoryHash = window.qBittorrent.Client.genHash(category); const categoryHash = window.qBittorrent.Misc.genHash(category);
if (!category_list.has(categoryHash)) { // This should not happen if (!category_list.has(categoryHash)) { // This should not happen
category_list.set(categoryHash, { category_list.set(categoryHash, {
name: category, name: category,
@ -400,7 +390,7 @@ window.addEventListener("DOMContentLoaded", () => {
const tags = torrent["tags"].split(","); const tags = torrent["tags"].split(",");
let added = false; let added = false;
for (let i = 0; i < tags.length; ++i) { for (let i = 0; i < tags.length; ++i) {
const tagHash = window.qBittorrent.Client.genHash(tags[i].trim()); const tagHash = window.qBittorrent.Misc.genHash(tags[i].trim());
if (!tagList.has(tagHash)) { // This should not happen if (!tagList.has(tagHash)) { // This should not happen
tagList.set(tagHash, { tagList.set(tagHash, {
name: tags, name: tags,
@ -590,30 +580,6 @@ window.addEventListener("DOMContentLoaded", () => {
tag.classList.toggle("selectedFilter", (Number(tag.id) === selectedTag)); tag.classList.toggle("selectedFilter", (Number(tag.id) === selectedTag));
}; };
// getHost emulate the GUI version `QString getHost(const QString &url)`
const getHost = function(url) {
// We want the hostname.
// If failed to parse the domain, original input should be returned
if (!/^(?:https?|udp):/i.test(url))
return url;
try {
// hack: URL can not get hostname from udp protocol
const parsedUrl = new URL(url.replace(/^udp:/i, "https:"));
// host: "example.com:8443"
// hostname: "example.com"
const host = parsedUrl.hostname;
if (!host)
return url;
return host;
}
catch (error) {
return url;
}
};
const updateTrackerList = function() { const updateTrackerList = function() {
const trackerFilterList = $("trackerFilterList"); const trackerFilterList = $("trackerFilterList");
if (trackerFilterList === null) if (trackerFilterList === null)
@ -749,7 +715,7 @@ window.addEventListener("DOMContentLoaded", () => {
continue; continue;
const responseCategory = response["categories"][key]; const responseCategory = response["categories"][key];
const categoryHash = window.qBittorrent.Client.genHash(key); const categoryHash = window.qBittorrent.Misc.genHash(key);
const category = category_list.get(categoryHash); const category = category_list.get(categoryHash);
if (category !== undefined) { if (category !== undefined) {
// only the save path can change for existing categories // only the save path can change for existing categories
@ -767,14 +733,14 @@ window.addEventListener("DOMContentLoaded", () => {
} }
if (response["categories_removed"]) { if (response["categories_removed"]) {
response["categories_removed"].each((category) => { response["categories_removed"].each((category) => {
const categoryHash = window.qBittorrent.Client.genHash(category); const categoryHash = window.qBittorrent.Misc.genHash(category);
category_list.delete(categoryHash); category_list.delete(categoryHash);
}); });
update_categories = true; update_categories = true;
} }
if (response["tags"]) { if (response["tags"]) {
for (const tag of response["tags"]) { for (const tag of response["tags"]) {
const tagHash = window.qBittorrent.Client.genHash(tag); const tagHash = window.qBittorrent.Misc.genHash(tag);
if (!tagList.has(tagHash)) { if (!tagList.has(tagHash)) {
tagList.set(tagHash, { tagList.set(tagHash, {
name: tag, name: tag,
@ -786,15 +752,15 @@ window.addEventListener("DOMContentLoaded", () => {
} }
if (response["tags_removed"]) { if (response["tags_removed"]) {
for (let i = 0; i < response["tags_removed"].length; ++i) { for (let i = 0; i < response["tags_removed"].length; ++i) {
const tagHash = window.qBittorrent.Client.genHash(response["tags_removed"][i]); const tagHash = window.qBittorrent.Misc.genHash(response["tags_removed"][i]);
tagList.delete(tagHash); tagList.delete(tagHash);
} }
updateTags = true; updateTags = true;
} }
if (response["trackers"]) { if (response["trackers"]) {
for (const [tracker, torrents] of Object.entries(response["trackers"])) { for (const [tracker, torrents] of Object.entries(response["trackers"])) {
const host = getHost(tracker); const host = window.qBittorrent.Misc.getHost(tracker);
const hash = window.qBittorrent.Client.genHash(host); const hash = window.qBittorrent.Misc.genHash(host);
let trackerListItem = trackerList.get(hash); let trackerListItem = trackerList.get(hash);
if (trackerListItem === undefined) { if (trackerListItem === undefined) {
@ -809,7 +775,8 @@ window.addEventListener("DOMContentLoaded", () => {
if (response["trackers_removed"]) { if (response["trackers_removed"]) {
for (let i = 0; i < response["trackers_removed"].length; ++i) { for (let i = 0; i < response["trackers_removed"].length; ++i) {
const tracker = response["trackers_removed"][i]; const tracker = response["trackers_removed"][i];
const hash = window.qBittorrent.Client.genHash(getHost(tracker)); const host = window.qBittorrent.Misc.getHost(tracker);
const hash = window.qBittorrent.Misc.genHash(host);
const trackerListEntry = trackerList.get(hash); const trackerListEntry = trackerList.get(hash);
if (trackerListEntry) if (trackerListEntry)
trackerListEntry.trackerTorrentMap.delete(tracker); trackerListEntry.trackerTorrentMap.delete(tracker);

View file

@ -1248,6 +1248,14 @@ window.qBittorrent.DynamicTable ??= (() => {
} }
}; };
// tracker
this.columns["tracker"].updateTd = function(td, row) {
const value = this.getRowValue(row);
const tracker = displayFullURLTrackerColumn ? value : window.qBittorrent.Misc.getHost(value);
td.textContent = tracker;
td.title = value;
};
// dl_limit, up_limit // dl_limit, up_limit
this.columns["dl_limit"].updateTd = function(td, row) { this.columns["dl_limit"].updateTd = function(td, row) {
const speed = this.getRowValue(row); const speed = this.getRowValue(row);
@ -1424,7 +1432,7 @@ window.qBittorrent.DynamicTable ??= (() => {
break; // do nothing break; // do nothing
default: default:
if (!useSubcategories) { if (!useSubcategories) {
if (categoryHash !== window.qBittorrent.Client.genHash(row["full_data"].category)) if (categoryHash !== window.qBittorrent.Misc.genHash(row["full_data"].category))
return false; return false;
} }
else { else {
@ -1449,7 +1457,7 @@ window.qBittorrent.DynamicTable ??= (() => {
break; // do nothing break; // do nothing
default: { default: {
const tagHashes = row["full_data"].tags.split(", ").map(tag => window.qBittorrent.Client.genHash(tag)); const tagHashes = row["full_data"].tags.split(", ").map(tag => window.qBittorrent.Misc.genHash(tag));
if (!tagHashes.contains(tagHash)) if (!tagHashes.contains(tagHash))
return false; return false;
break; break;

View file

@ -32,6 +32,8 @@ window.qBittorrent ??= {};
window.qBittorrent.Misc ??= (() => { window.qBittorrent.Misc ??= (() => {
const exports = () => { const exports = () => {
return { return {
genHash: genHash,
getHost: getHost,
createDebounceHandler: createDebounceHandler, createDebounceHandler: createDebounceHandler,
friendlyUnit: friendlyUnit, friendlyUnit: friendlyUnit,
friendlyDuration: friendlyDuration, friendlyDuration: friendlyDuration,
@ -51,6 +53,40 @@ window.qBittorrent.Misc ??= (() => {
}; };
}; };
const genHash = function(string) {
// origins:
// https://stackoverflow.com/a/8831937
// https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0
let hash = 0;
for (let i = 0; i < string.length; ++i)
hash = ((Math.imul(hash, 31) + string.charCodeAt(i)) | 0);
return hash;
};
// getHost emulate the GUI version `QString getHost(const QString &url)`
const getHost = function(url) {
// We want the hostname.
// If failed to parse the domain, original input should be returned
if (!/^(?:https?|udp):/i.test(url))
return url;
try {
// hack: URL can not get hostname from udp protocol
const parsedUrl = new URL(url.replace(/^udp:/i, "https:"));
// host: "example.com:8443"
// hostname: "example.com"
const host = parsedUrl.hostname;
if (!host)
return url;
return host;
}
catch (error) {
return url;
}
};
const createDebounceHandler = (delay, func) => { const createDebounceHandler = (delay, func) => {
let timer = -1; let timer = -1;
return (...params) => { return (...params) => {

View file

@ -76,10 +76,18 @@
</table> </table>
</fieldset> </fieldset>
<div class="formRow"> <div class="formRow" style="margin-bottom: 5px;">
<input type="checkbox" id="performanceWarning"> <input type="checkbox" id="performanceWarning">
<label for="performanceWarning">QBT_TR(Log performance warnings)QBT_TR[CONTEXT=OptionsDialog]</label> <label for="performanceWarning">QBT_TR(Log performance warnings)QBT_TR[CONTEXT=OptionsDialog]</label>
</div> </div>
<fieldset class="settings">
<legend title="QBT_TR(Following settings are WebUI only)QBT_TR[CONTEXT=OptionsDialog]">QBT_TR(Custom WebUI settings)QBT_TR[CONTEXT=OptionsDialog]</legend>
<div class="formRow" style="margin-bottom: 3px;">
<input type="checkbox" id="displayFullURLTrackerColumn">
<label for="displayFullURLTrackerColumn">QBT_TR(Display full announce URL in the Tracker column)QBT_TR[CONTEXT=OptionsDialog]</label>
</div>
</fieldset>
</div> </div>
<div id="DownloadsTab" class="PrefTab invisible"> <div id="DownloadsTab" class="PrefTab invisible">
@ -2086,6 +2094,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
window.parent.qBittorrent.Cache.preferences.init({ window.parent.qBittorrent.Cache.preferences.init({
onSuccess: (pref) => { onSuccess: (pref) => {
// Behavior tab // Behavior tab
document.getElementById("displayFullURLTrackerColumn").checked = (LocalPreferences.get("full_url_tracker_column", "false") === "true");
document.getElementById("hideZeroFiltersCheckbox").checked = (LocalPreferences.get("hide_zero_status_filters", "false") === "true"); document.getElementById("hideZeroFiltersCheckbox").checked = (LocalPreferences.get("hide_zero_status_filters", "false") === "true");
$("dblclickDownloadSelect").value = LocalPreferences.get("dblclick_download", "1"); $("dblclickDownloadSelect").value = LocalPreferences.get("dblclick_download", "1");
$("dblclickCompleteSelect").value = LocalPreferences.get("dblclick_complete", "1"); $("dblclickCompleteSelect").value = LocalPreferences.get("dblclick_complete", "1");
@ -2499,6 +2508,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
// Validate form data // Validate form data
// Behavior tab // Behavior tab
LocalPreferences.set("full_url_tracker_column", document.getElementById("displayFullURLTrackerColumn").checked.toString());
LocalPreferences.set("hide_zero_status_filters", document.getElementById("hideZeroFiltersCheckbox").checked.toString()); LocalPreferences.set("hide_zero_status_filters", document.getElementById("hideZeroFiltersCheckbox").checked.toString());
LocalPreferences.set("dblclick_download", $("dblclickDownloadSelect").value); LocalPreferences.set("dblclick_download", $("dblclickDownloadSelect").value);
LocalPreferences.set("dblclick_complete", $("dblclickCompleteSelect").value); LocalPreferences.set("dblclick_complete", $("dblclickCompleteSelect").value);