Release v0.7.0 — complete DarkPeers rules, integration, and UX overhaul

This commit is contained in:
Procuria committed 2026-04-10 17:03:31 +02:00
1 parent 1f5670a658
commit 56c2682ff5
2 files changed
+66 -70

No files matched your search

+20 -41
View File
@@ -4,53 +4,32 @@ All notable changes to the DarkPeers Mod Queue Helper will be documented in this
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
## [0.6.4] - 2026-04-09
## [0.7.0] - 2026-04-10
### Fixed
- **Corrective message BBCode** — corrected Naming Guide link to proper `[url=…]…[/url]` BBCode syntax per bbcode.org spec.
## [0.6.3] - 2026-04-09
### Fixed
- **Corrective message BBCode** — incorrect fix (used `[url]…[/url]` without `=` attribute).
## [0.6.2] - 2026-04-09
### Fixed
- **Corrective message BBCode** — incorrect fix for the URL tag syntax (used `[url=…]` instead of `[url]…[/url]`).
## [0.6.1] - 2026-04-09
- **Banned groups** — replaced Luminarr list (87 groups) with DarkPeers authoritative list (60 groups + EVO/HDT conditional exceptions). False positives for Kira, 4K4U, d3g, iVy eliminated.
- **Encode resolution** — removed fake "720p minimum" rule. DarkPeers allows all resolutions (360p–4320p).
- **Opus/FLAC** — removed fake mono/stereo restriction. No channel limits on DarkPeers.
- **Dual-Audio** — corrected to DarkPeers definition: any 2 languages = Dual-Audio, 3+ = MULTi.
- **Release group** — missing group tag is now a warning, not an error.
- **Atmos detection** — checks only the default audio track, not all tracks.
- **HDR validation** — no longer gated behind 2160p/4320p. Catches "HDR10" at any resolution.
- **SRRDB search** — scene-name normalization and fallback keyword search when exact match fails.
- **Prowlarr rename detection** — ignores release group differences in self-consistency checks. AKA titles no longer cause false rename warnings.
- **Corrective messages** — replaced Luminarr §section references with "Naming Guide" link. Fixed BBCode URL syntax. Removed `img.luminarr.me`.
- **Prowlarr match summaries** — dynamically lists only fields that actually match instead of hardcoded claims.
### Added
- **Prowlarr timeout setting** — search timeout is now configurable via Tampermonkey settings (default: 15000ms). Accessible in the Integrations fieldset alongside Prowlarr URL and API Key.
## [0.6.0] - 2026-04-09
### Fixed
- **Banned groups** — replaced Luminarr list (87 groups) with DarkPeers authoritative list (60 groups + EVO/HDT conditional exceptions). False positives for Kira, 4K4U, d3g, iVy eliminated. EVO allowed for WEB-DL, HDT allowed for REMUX.
- **Encode resolution** — removed fake "720p minimum" rule. DarkPeers allows all resolutions including 360p, 480i, 480p, 576i, 576p.
- **Opus/FLAC** — removed fake mono/stereo restriction. DarkPeers has no channel limit on Opus or FLAC.
- **Dual-Audio** — corrected to DarkPeers definition: any 2 languages = Dual-Audio, 3+ = MULTi. Removed incorrect English-origin restriction.
- **Release group** — missing group tag is now a warning, not an error. DarkPeers allows uploads without a group tag.
- **Atmos detection** — now checks only the default audio track, not all tracks. Eliminates false positives from Atmos on commentary/secondary tracks.
- **HDR validation** — no longer gated behind 2160p/4320p. Validates HDR tags whenever they appear in the title, catching "HDR10" (should be "HDR") at any resolution.
- **SRRDB search** — added scene-name normalization (strip colons/apostrophes, & → and) and fallback keyword search when exact match fails.
- **Prowlarr rename detection** — self-consistency checks now ignore release group differences between torrent title and folder/file names, reducing false rename warnings.
- **Corrective messages** — replaced Luminarr §section references with plain "Naming Guide" link to DarkPeers wiki. Removed `img.luminarr.me` from image hosts.
### Added
- **Ignored indexers** — new setting to exclude specific indexers from Prowlarr results (e.g. TorrentLeech). Comma-separated, case-insensitive.
- **Manual re-search** — "Re-search" button in External Integrations section header. Prevents unwanted auto-searches after page edits. Click to re-query SRRDB and Prowlarr on demand.
- **Expanded indexer view** — all matching indexers shown (no longer capped at 3). First 3 inline, rest in collapsible "+N more" section.
- **Torrent age** — relative age shown next to each alternative indexer ("3d ago", "2mo ago") when Prowlarr provides publish dates.
- **Dynamic match summaries** — Prowlarr summary now lists only fields that actually match instead of hardcoded "title, year, resolution, codecs all consistent". Mismatched fields are excluded from the claim.
- **Alternative hyperlinks** — "Also found on" indexers are now clickable links to the source tracker page when URL is available.
- **Auto-search toggle** — "Auto-search on page load" setting. When off, SRRDB/Prowlarr only run when you click Search. No more automatic queries while browsing.
- **Ignored indexers** — exclude specific indexers from Prowlarr results via settings.
- **Search / Re-search button** — on-demand integration search in the External Integrations section.
- **Expanded indexer view** — all matching indexers shown (no cap). Collapsible "+N more" for overflow.
- **Torrent age** — relative age shown next to each alternative indexer.
- **Alternative hyperlinks** — "Also found on" indexers are clickable links.
- **Prowlarr timeout setting** — configurable search timeout (default: 15000ms).
- **MCP read-only test harness** — safety-enforced browser verification framework for live-site testing.
## [0.5.0] - 2026-04-06
+46 -29
View File
@@ -1,7 +1,7 @@
// ==UserScript==
// @name UNIT3D Mod Queue Helper — DarkPeers
// @namespace https://gitea.computerliebe.org/Procuria/dp-modq-helper
// @version 0.6.4
// @version 0.7.0
// @description Quality-gate checks for DarkPeers — extended moderation rules, title validation, SRRDB & Prowlarr integrations
// @author TQG Contributors
// @updateURL https://gitea.computerliebe.org/Procuria/dp-modq-helper/raw/branch/main/modq-helper-darkpeers.user.js
@@ -1227,7 +1227,7 @@ let _resolvedModStatuses = DEFAULT_MOD_STATUSES;
const Settings = {
_KEY: "modq_settings",
_defaults: {
prowlarr: { url: "", apiKey: "", enabled: false, preferredIndexers: [], ignoredIndexers: [], timeout: 15000 },
prowlarr: { url: "", apiKey: "", enabled: false, preferredIndexers: [], ignoredIndexers: [], timeout: 15000, autoSearch: true },
srrdb: { enabled: true },
checks: {
tmdbMatch: true, seasonEpisode: true, namingGuide: true,
@@ -1368,6 +1368,11 @@ const Settings = {
style="width:80px;background:#1e293b;border:1px solid #334155;color:#e2e8f0;border-radius:4px;padding:2px 6px;">
<small style="color:#64748b;font-size:11px;">Default: 15000</small>
</label>
<label style="display:flex;align-items:center;gap:6px;margin:8px 0 2px;color:#cbd5e1;font-size:13px;">
<input type="checkbox" data-setting="prowlarr.autoSearch" ${s.prowlarr.autoSearch !== false ? "checked" : ""}>
Auto-search on page load
</label>
<small style="color:#64748b;font-size:11px;margin-left:22px;">When off, Prowlarr/SRRDB only search when you click the Search button.</small>
</fieldset>
<fieldset style="border:1px solid #334155;border-radius:6px;padding:12px;margin-bottom:12px;">
@@ -3838,6 +3843,17 @@ const RenameDetector = {
} catch { return null; }
},
/**
* _stripAka — Remove "AKA ..." portion from a title name.
* DP naming convention includes "Name AKA Original" but folders/filenames
* never include the AKA part, causing Jaccard mismatch. Strip it before
* comparing titleNames.
*/
_stripAka(name) {
if (!name) return name;
return name.replace(/\s+AKA\s+.*/i, "").trim();
},
/** Codec aliases for fuzzy matching */
_codecAliases: {
"x264": "h.264", "h.264": "h.264", "avc": "h.264",
@@ -3946,8 +3962,8 @@ const RenameDetector = {
let weightedSum = 0;
const fieldScores = {};
// titleName — Jaccard similarity
const titleScore = this._jaccardWords(uploadTokens.titleName, resultTokens.titleName);
// titleName — Jaccard similarity (strip AKA for fair comparison)
const titleScore = this._jaccardWords(this._stripAka(uploadTokens.titleName), this._stripAka(resultTokens.titleName));
fieldScores.titleName = titleScore;
weightedSum += titleScore * weights.titleName;
totalWeight += weights.titleName;
@@ -4088,8 +4104,10 @@ const RenameDetector = {
* optionally ignores group differences.
*/
structurallyEquivalent(tokensA, tokensB, { ignoreGroup = false } = {}) {
// Compare title name words
const titleSim = this._jaccardWords(tokensA.titleName, tokensB.titleName);
// Compare title name words — strip AKA portion (folders never include it)
const titleA = this._stripAka(tokensA.titleName);
const titleB = this._stripAka(tokensB.titleName);
const titleSim = this._jaccardWords(titleA, titleB);
if (titleSim < 0.5) return false;
// Compare structural fields — must match if both present
@@ -4298,7 +4316,7 @@ const U={getStatusIcon(e){switch(e){case"pass":return'<i class="fas fa-check-cir
</div>
<div id="mh-filename-result" class="mh-filename-result"></div>
</div>
<div class="panel__body mh-body">${T}${this._buildIntegrationPlaceholders(e)}</div>`,n},injectPanel(e){const n=E.getModerationPanel();if(n)n.parentNode.insertBefore(e,n);else{const t=document.querySelector(_resolvedSelectors.torrentTags);t&&t.parentNode.insertBefore(e,t.nextSibling)}this.attachEvents(e)},attachEvents(e){const n=e.querySelector("#mh-toggle-all");if(n){let D=!1;n.addEventListener("click",()=>{D=!D,e.querySelectorAll(".mh-accordion, .mh-section").forEach(x=>x.open=D),n.querySelector("i").className=D?"fas fa-angles-up":"fas fa-angles-down",n.title=D?"Collapse all sections":"Expand all sections"})}const t=e.querySelector("#mh-corrective-text"),s=e.querySelector("#mh-corrective-editor");t&&s&&(t.addEventListener("click",()=>{t.style.display="none",s.style.display="block",s.focus()}),s.addEventListener("blur",()=>{t.textContent=s.value,t.style.display="",s.style.display=""}));const a=()=>s?s.value:"",o=e.querySelector("#mh-copy-message");o&&o.addEventListener("click",()=>{const D=a();navigator.clipboard.writeText(D).then(()=>{const x=o.querySelector("i");x.className="fas fa-check",o.classList.add("mh-btn--success"),setTimeout(()=>{x.className="fas fa-copy",o.classList.remove("mh-btn--success")},2e3)})});const c=D=>{const x=document.querySelectorAll(_resolvedSelectors.moderationForms);for(const p of x){const y=p.querySelector(_resolvedSelectors.moderationStatus);if(y&&y.value===D)return p.querySelector(_resolvedSelectors.moderationMessage)}return null},r=(D,x)=>{const p=e.querySelector(D);p&&p.addEventListener("click",()=>{const y=a(),C=c(x);if(C){C.value=y,C.dispatchEvent(new Event("input",{bubbles:!0}));const h=p.querySelector("i");h.className="fas fa-check",p.classList.add("mh-btn--success"),setTimeout(()=>{h.className="fas fa-paste",p.classList.remove("mh-btn--success")},2e3)}else{const h=p.querySelector("i");h.className="fas fa-xmark",p.classList.add("mh-btn--fail"),setTimeout(()=>{h.className="fas fa-paste",p.classList.remove("mh-btn--fail")},2e3)}})};r("#mh-fill-postpone",_resolvedModStatuses.postpone),r("#mh-fill-reject",_resolvedModStatuses.reject);const d=e.querySelector("#mh-filename-compare-btn"),f=e.querySelector("#mh-filename-block"),A=e.querySelector("#mh-filename-uploaded"),T=e.querySelector("#mh-filename-input"),b=e.querySelector("#mh-filename-run"),u=e.querySelector("#mh-filename-result");if(d&&f&&d.addEventListener("click",()=>{const D=f.style.display!=="none";if(f.style.display=D?"none":"",d.classList.toggle("mh-btn--active",!D),!D&&A){const x=E.getMediaInfoFilename()||"(not found)";A.textContent=x}}),b&&T&&u){const D=()=>{const x=T.value.trim();if(!x){u.innerHTML='<span class="mh-diff-error">Please enter a reference filename.</span>';return}const p=E.getMediaInfoFilename();if(!p||p==="(not found)"){u.innerHTML='<span class="mh-diff-error">Could not read MediaInfo filename from page.</span>';return}const y=z.diff(x,p);u.innerHTML=z.renderDiff(y)};b.addEventListener("click",D),T.addEventListener("keydown",x=>{x.key==="Enter"&&D()})}},_buildIntegrationPlaceholders(results){if(!results.nogroup&&!results.dpTitle)return"";return`<div class="mh-section-group"><details class="mh-section" open><summary class="mh-section__header"><i class="fas fa-plug mh-section__icon"></i><span class="mh-section__title">External Integrations</span><button class="form__button form__button--text mh-btn mh-btn--sm" id="mh-integration-refresh" title="Re-run integration searches"><i class="fas fa-rotate"></i> Re-search</button></summary><div class="mh-section__body"><div data-integration="srrdb" class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">SRRDB</span><span class="mh-integration__msg">Checking scene database...</span></div><div data-integration="prowlarr" class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">Prowlarr</span><span class="mh-integration__msg">Searching indexers...</span></div></div></details></div>`},renderIntegrationResult(name,result){const esc=(s)=>String(s||"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");if(result.error){return`<div class="mh-integration mh-integration--warn"><span class="mh-integration__icon"><i class="fas fa-exclamation-triangle mh-icon--warn"></i></span><span class="mh-integration__label">${esc(name)}</span><span class="mh-integration__msg">${esc(result.error)}</span></div>`}if(result.notConfigured){return`<div class="mh-integration mh-integration--na"><span class="mh-integration__icon"><i class="fas fa-minus-circle mh-icon--na"></i></span><span class="mh-integration__label">${esc(name)}</span><span class="mh-integration__msg">Not configured — open ModQ Helper Settings</span></div>`}if(name==="SRRDB"){if(!result.found){return`<div class="mh-integration mh-integration--na"><span class="mh-integration__icon"><i class="fLine truncated
<div class="panel__body mh-body">${T}${this._buildIntegrationPlaceholders(e, e._autoSearch)}</div>`,n},injectPanel(e){const n=E.getModerationPanel();if(n)n.parentNode.insertBefore(e,n);else{const t=document.querySelector(_resolvedSelectors.torrentTags);t&&t.parentNode.insertBefore(e,t.nextSibling)}this.attachEvents(e)},attachEvents(e){const n=e.querySelector("#mh-toggle-all");if(n){let D=!1;n.addEventListener("click",()=>{D=!D,e.querySelectorAll(".mh-accordion, .mh-section").forEach(x=>x.open=D),n.querySelector("i").className=D?"fas fa-angles-up":"fas fa-angles-down",n.title=D?"Collapse all sections":"Expand all sections"})}const t=e.querySelector("#mh-corrective-text"),s=e.querySelector("#mh-corrective-editor");t&&s&&(t.addEventListener("click",()=>{t.style.display="none",s.style.display="block",s.focus()}),s.addEventListener("blur",()=>{t.textContent=s.value,t.style.display="",s.style.display=""}));const a=()=>s?s.value:"",o=e.querySelector("#mh-copy-message");o&&o.addEventListener("click",()=>{const D=a();navigator.clipboard.writeText(D).then(()=>{const x=o.querySelector("i");x.className="fas fa-check",o.classList.add("mh-btn--success"),setTimeout(()=>{x.className="fas fa-copy",o.classList.remove("mh-btn--success")},2e3)})});const c=D=>{const x=document.querySelectorAll(_resolvedSelectors.moderationForms);for(const p of x){const y=p.querySelector(_resolvedSelectors.moderationStatus);if(y&&y.value===D)return p.querySelector(_resolvedSelectors.moderationMessage)}return null},r=(D,x)=>{const p=e.querySelector(D);p&&p.addEventListener("click",()=>{const y=a(),C=c(x);if(C){C.value=y,C.dispatchEvent(new Event("input",{bubbles:!0}));const h=p.querySelector("i");h.className="fas fa-check",p.classList.add("mh-btn--success"),setTimeout(()=>{h.className="fas fa-paste",p.classList.remove("mh-btn--success")},2e3)}else{const h=p.querySelector("i");h.className="fas fa-xmark",p.classList.add("mh-btn--fail"),setTimeout(()=>{h.className="fas fa-paste",p.classList.remove("mh-btn--fail")},2e3)}})};r("#mh-fill-postpone",_resolvedModStatuses.postpone),r("#mh-fill-reject",_resolvedModStatuses.reject);const d=e.querySelector("#mh-filename-compare-btn"),f=e.querySelector("#mh-filename-block"),A=e.querySelector("#mh-filename-uploaded"),T=e.querySelector("#mh-filename-input"),b=e.querySelector("#mh-filename-run"),u=e.querySelector("#mh-filename-result");if(d&&f&&d.addEventListener("click",()=>{const D=f.style.display!=="none";if(f.style.display=D?"none":"",d.classList.toggle("mh-btn--active",!D),!D&&A){const x=E.getMediaInfoFilename()||"(not found)";A.textContent=x}}),b&&T&&u){const D=()=>{const x=T.value.trim();if(!x){u.innerHTML='<span class="mh-diff-error">Please enter a reference filename.</span>';return}const p=E.getMediaInfoFilename();if(!p||p==="(not found)"){u.innerHTML='<span class="mh-diff-error">Could not read MediaInfo filename from page.</span>';return}const y=z.diff(x,p);u.innerHTML=z.renderDiff(y)};b.addEventListener("click",D),T.addEventListener("keydown",x=>{x.key==="Enter"&&D()})}},_buildIntegrationPlaceholders(results, autoSearch){if(!results.nogroup&&!results.dpTitle)return"";const _idle=autoSearch===false;const _srrdbContent=_idle?`<div data-integration="srrdb" class="mh-integration mh-integration--na"><span class="mh-integration__icon"><i class="fas fa-minus-circle mh-icon--na"></i></span><span class="mh-integration__label">SRRDB</span><span class="mh-integration__msg">Idle — use the Search button above to check</span></div>`:`<div data-integration="srrdb" class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">SRRDB</span><span class="mh-integration__msg">Checking scene database...</span></div>`;const _prowlarrContent=_idle?`<div data-integration="prowlarr" class="mh-integration mh-integration--na"><span class="mh-integration__icon"><i class="fas fa-minus-circle mh-icon--na"></i></span><span class="mh-integration__label">Prowlarr</span><span class="mh-integration__msg">Idle — use the Search button above to check</span></div>`:`<div data-integration="prowlarr" class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">Prowlarr</span><span class="mh-integration__msg">Searching indexers...</span></div>`;const _btnLabel=_idle?"Search":"Re-search";const _btnIcon=_idle?"fa-search":"fa-rotate";return`<div class="mh-section-group"><details class="mh-section" open><summary class="mh-section__header"><i class="fas fa-plug mh-section__icon"></i><span class="mh-section__title">External Integrations</span></summary><div class="mh-section__body"><div style="margin-bottom:6px;"><button class="form__button form__button--text mh-btn mh-btn--search" id="mh-integration-refresh" title="${_btnLabel} integration searches"><i class="fas ${_btnIcon}"></i> ${_btnLabel}</button></div><div id="mh-srrdb-container">$Line truncated
// Best match title with optional link
const titleText=esc(bestMatch.title);const indexerText=esc(bestMatch.indexer);const linkHtml=bestMatch.infoUrl?` <a href="${esc(bestMatch.infoUrl)}" target="_blank" rel="noopener" title="Open on ${indexerText}" class="mh-integration__link"><i class="fas fa-external-link-alt"></i></a>`:"";
matchHtml+=`<div class="mh-integration__detail"><strong>Best match:</strong> ${titleText} <span class="mh-integration__indexer">[${indexerText}]</span>${linkHtml}</div>`;
@@ -4404,6 +4422,8 @@ const Z=`
color: var(--text-color, #e5e5e5);
}
.mh-btn--sm { font-size: 11px; padding: 2px 6px; margin-left: auto; }
.mh-btn--search { font-size: 12px; padding: 4px 12px; background: rgba(59,130,246,0.15); color: rgb(96,165,250); border: 1px solid rgba(59,130,246,0.3); border-radius: 4px; }
.mh-btn--search:hover { background: rgba(59,130,246,0.25); color: rgb(147,197,253); }
.mh-body {
padding: 0 !important;
@@ -5034,6 +5054,9 @@ function main() {
}
// Create and inject panel
const _settings = Settings.load();
const _autoSearch = _settings.prowlarr?.autoSearch !== false;
results._autoSearch = _autoSearch;
const panel = U.createPanel(results);
U.injectPanel(panel);
@@ -5041,19 +5064,18 @@ function main() {
// Async integration pipeline (DarkPeers)
// Extracted into a function so the re-search button can call it again.
let _integrationSearchRun = false;
const _setIntegration = (id, html) => {
const c = document.querySelector(`#mh-${id}-container`);
if (c) c.innerHTML = html;
};
const _loadingHtml = (label) => `<div class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">${label}</span><span class="mh-integration__msg">Checking...</span></div>`;
const runIntegrationSearches = async () => {
if (!dpFeatures.prowlarr && !dpFeatures.srrdb) return;
const settings = Settings.load();
// Reset placeholders to loading state on re-search
if (_integrationSearchRun) {
const sEl = document.querySelector('[data-integration="srrdb"]');
if (sEl) sEl.outerHTML = '<div data-integration="srrdb" class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">SRRDB</span><span class="mh-integration__msg">Checking scene database...</span></div>';
const pEl = document.querySelector('[data-integration="prowlarr"]');
if (pEl) pEl.outerHTML = '<div data-integration="prowlarr" class="mh-integration mh-integration--loading"><span class="mh-integration__icon"><i class="fas fa-spinner fa-spin"></i></span><span class="mh-integration__label">Prowlarr</span><span class="mh-integration__msg">Searching indexers...</span></div>';
}
_integrationSearchRun = true;
// Show loading state
_setIntegration("srrdb", _loadingHtml("SRRDB"));
_setIntegration("prowlarr", _loadingHtml("Prowlarr"));
// SRRDB: search + file comparison
if (dpFeatures.srrdb && settings.srrdb?.enabled !== false) {
@@ -5091,11 +5113,9 @@ function main() {
}
}
const el = document.querySelector('[data-integration="srrdb"]');
if (el) el.outerHTML = U.renderIntegrationResult("SRRDB", searchResult);
_setIntegration("srrdb", U.renderIntegrationResult("SRRDB", searchResult));
} catch (err) {
const el = document.querySelector('[data-integration="srrdb"]');
if (el) el.outerHTML = U.renderIntegrationResult("SRRDB", { error: err.message });
_setIntegration("srrdb", U.renderIntegrationResult("SRRDB", { error: err.message }));
}
})();
}
@@ -5129,20 +5149,17 @@ function main() {
}
}
const el = document.querySelector('[data-integration="prowlarr"]');
if (el) el.outerHTML = U.renderIntegrationResult("Prowlarr", searchResult);
_setIntegration("prowlarr", U.renderIntegrationResult("Prowlarr", searchResult));
} catch (err) {
const el = document.querySelector('[data-integration="prowlarr"]');
if (el) el.outerHTML = U.renderIntegrationResult("Prowlarr", { error: err.message });
_setIntegration("prowlarr", U.renderIntegrationResult("Prowlarr", { error: err.message }));
}
})();
} else if (dpFeatures.prowlarr) {
const el = document.querySelector('[data-integration="prowlarr"]');
if (el) el.outerHTML = U.renderIntegrationResult("Prowlarr", { notConfigured: true });
_setIntegration("prowlarr", U.renderIntegrationResult("Prowlarr", { notConfigured: true }));
}
};
// Wire up re-search button
// Wire up search/re-search button
const refreshBtn = document.querySelector("#mh-integration-refresh");
if (refreshBtn) {
refreshBtn.addEventListener("click", () => {
@@ -5150,8 +5167,8 @@ function main() {
});
}
// Run initial search
if (dpFeatures.prowlarr || dpFeatures.srrdb) {
// Run initial search (only if autoSearch is enabled)
if ((dpFeatures.prowlarr || dpFeatures.srrdb) && _autoSearch) {
runIntegrationSearches();
}