Update to v0.6.8

This commit is contained in:
2026-09-25 17:46:48 +02:00
parent 7def1a4dc5
commit fc1fc283e6
2 changed files with 132 additions and 22 deletions
+75 -19
View File
@@ -4,6 +4,15 @@ 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/). The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
## [0.6.8] - 2026-09-25
### Fixed
- DarkPeers checks now show in the panel, in a new DarkPeers Rules section: title template, NOGROUP, banned group in files, extraneous files, category/type, single file in folder, missing episodes, unknown language, suspicion heuristics. They ran before but were never displayed.
- Fails and warnings from these checks now go into the corrective message.
- The per-check switches in Settings now work. A switched-off check shows as N/A and stays out of the message.
- Review results no longer count as "not passed" in the section and header counts.
## [0.6.7] - 2026-04-10 ## [0.6.7] - 2026-04-10
### Fixed ### Fixed
@@ -16,28 +25,75 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
### Fixed ### 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. - **AKA title false rename warnings** — titles with "AKA Original-Title" (e.g. `Squid Game AKA Ojing-eo geim`) no longer trigger false "possible rename" warnings when the folder uses the short name. The AKA portion is stripped before title comparison.
- **Encode resolution** — removed fake "720p minimum" rule. DarkPeers allows all resolutions (360p–4320p). - **Search button first-click** — rewrote integration rendering to use stable container divs, fixing the issue where the Search button only worked on the second click.
- **Opus/FLAC** — removed fake mono/stereo restriction. No channel limits on DarkPeers. - **Search button idle message** — changed to "Idle — use the Search button above to check" for clarity.
- **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 ### Added
- **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. - **Auto-search toggle** — new "Auto-search on page load" checkbox in Prowlarr settings. When unchecked, SRRDB/Prowlarr only search when you click the Search button. 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. ### Changed
- **Expanded indexer view** — all matching indexers shown (no cap). Collapsible "+N more" for overflow.
- **Torrent age** — relative age shown next to each alternative indexer. - **Search button styling** — moved to left-aligned position below section header with subtle blue accent for better visibility.
- **Alternative hyperlinks** — "Also found on" indexers are clickable links.
- **Prowlarr timeout setting** — configurable search timeout (default: 15000ms). ## [0.6.5] - 2026-04-10
- **MCP read-only test harness** — safety-enforced browser verification framework for live-site testing.
### Fixed
- **AKA title false rename warnings** — titles with "AKA Original-Title" (e.g. `Squid Game AKA Ojing-eo geim`) no longer trigger false "possible rename" warnings when the folder uses the short name (`Squid.Game`). The AKA portion is stripped before title comparison.
### Added
- **Auto-search toggle** — new "Auto-search on page load" checkbox in Prowlarr settings. When unchecked, SRRDB/Prowlarr only search when you click the Search button. No more automatic queries while browsing.
## [0.6.4] - 2026-04-09
### 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
### 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.
## [0.5.0] - 2026-04-06 ## [0.5.0] - 2026-04-06
+57 -3
View File
@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name UNIT3D Mod Queue Helper — DarkPeers // @name UNIT3D Mod Queue Helper — DarkPeers
// @namespace https://gitea.computerliebe.org/Procuria/dp-modq-helper // @namespace https://gitea.computerliebe.org/Procuria/dp-modq-helper
// @version 0.6.7 // @version 0.6.8
// @description Quality-gate checks for DarkPeers — extended moderation rules, title validation, SRRDB & Prowlarr integrations // @description Quality-gate checks for DarkPeers — extended moderation rules, title validation, SRRDB & Prowlarr integrations
// @author TQG Contributors // @author TQG Contributors
// @updateURL https://gitea.computerliebe.org/Procuria/dp-modq-helper/raw/branch/main/modq-helper-darkpeers.user.js // @updateURL https://gitea.computerliebe.org/Procuria/dp-modq-helper/raw/branch/main/modq-helper-darkpeers.user.js
@@ -4245,6 +4245,56 @@ ${e.violations.map(o=>" • "+o).join(`
Please review the [url=${this.RULES_URL}]Naming Guide[/url].`}return b}}; Please review the [url=${this.RULES_URL}]Naming Guide[/url].`}return b}};
/* ========================================================================
* DARKPEERS SECTION: rows for dpk results and the title validator,
* plus the per-check toggles from Settings.
* ======================================================================== */
const DP_SECTION = [
["dpTitle", "Title Template"],
["nogroup", "NOGROUP"],
["bannedFilename", "Banned Group in Files"],
["extraneousFiles", "Extraneous Files"],
["categoryTypeMismatch", "Category / Type"],
["singleFileFolder", "Single File in Folder"],
["missingEpisodes", "Missing Episodes"],
["unknownLanguage", "Unknown Language"],
["suspicion", "Suspicion Heuristics"],
];
/** Replace every check switched off in Settings with an N/A result of the same shape. */
function applyCheckToggles(results, checks) {
if (!checks) return results;
for (const [key, on] of Object.entries(checks)) {
if (on === false && results[key]) {
results[key] = { status: "na", message: "Disabled in settings", details: null, checks: [], violations: [] };
}
}
return results;
}
/** DarkPeers rows to render: present, not N/A. */
function dpSectionRows(results) {
return DP_SECTION.filter(([k]) => results[k] && results[k].status !== "na");
}
/* Corrective message: include fails and warnings from the DarkPeers rows */
(function() {
const _collect = G.collectIssues, _beautify = G.beautify;
G.collectIssues = function(e) {
const n = _collect.call(this, e);
for (const [key, label] of (e._dpRows || [])) {
const v = e[key];
if (v && (v.status === "fail" || v.status === "warn")) n.push({ id: "dp_" + key, status: v.status, raw: v.message, label });
}
return n;
};
G.beautify = function(e) {
if (e.id && e.id.startsWith("dp_")) return { text: e.raw, rules: [] };
return _beautify.call(this, e);
};
})();
/* ======================================================================== /* ========================================================================
* UI — Panel rendering, injection, and event handling * UI — Panel rendering, injection, and event handling
* Ported from the original U object. * Ported from the original U object.
@@ -4286,7 +4336,7 @@ const U={getStatusIcon(e){switch(e){case"pass":return'<i class="fas fa-check-cir
<strong>Banned Release Group Detected</strong> <strong>Banned Release Group Detected</strong>
<span>${e.message}</span> <span>${e.message}</span>
</div> </div>
</div>`:""},groupHeading(e){return`<div class="mh-group">${e}</div>`},sectionGroup(e,n,t){const s=t.map(f=>f.status).filter(f=>f!=="na"),a=s.filter(f=>f==="pass").length,o=s.length,c=a===o&&o>0,r=this.worstStatus(t.map(f=>f.status));return` </div>`:""},groupHeading(e){return`<div class="mh-group">${e}</div>`},sectionGroup(e,n,t){const s=t.map(f=>f.status).filter(f=>f!=="na"&&f!=="advisory"),a=s.filter(f=>f==="pass").length,o=s.length,c=a===o&&o>0,r=this.worstStatus(t.map(f=>f.status));return`
<details class="mh-section" ${c?"":"open"}> <details class="mh-section" ${c?"":"open"}>
<summary class="mh-section__summary"> <summary class="mh-section__summary">
<span class="mh-chip mh-chip--${r==="na"?"pass":r}">${a}/${o} passed</span> <span class="mh-chip mh-chip--${r==="na"?"pass":r}">${a}/${o} passed</span>
@@ -4294,7 +4344,7 @@ const U={getStatusIcon(e){switch(e){case"pass":return'<i class="fas fa-check-cir
<i class="fas fa-chevron-down mh-section__chevron"></i> <i class="fas fa-chevron-down mh-section__chevron"></i>
</summary> </summary>
<div class="mh-section__body">${n}</div> <div class="mh-section__body">${n}</div>
</details>`},createPanel(e){const n=document.createElement("section");n.className="panelV2 mh-panel",n.id="mod-helper-panel";const s=[e.tmdbMatch,e.seasonEpisode,e.namingGuide,e.elementOrder,e.folderStructure,e.mediaInfo,e.audioTags,e.subtitleRequirement,e.screenshots,e.bannedGroup,e.encodeCompliance,e.upscaleDetection,e.containerFormat,e.packUniformity,e.resolutionTypeMatch].map(i=>i.status),a=this.worstStatus(s),o=s.filter(i=>i!=="na"),c=o.filter(i=>i==="pass").length,r=o.filter(i=>i==="warn").length,d=o.filter(i=>i==="fail").length,f=o.length;let A=[];if(d&&A.push(`<span class="mh-chip mh-chip--fail">${d} failed</span>`),r&&A.push(`<span class="mh-chip mh-chip--warn">${r} warning${r>1?"s":""}</span>`),A.push(`<span class="mh-chip mh-chip--pass">${c}/${f} passed</span>`),e.bannedGroup.tieredInfo){const i=e.bannedGroup.tieredInfo.join(", ");A.push(`<span class="mh-chip mh-chip--pass" title="${i}">TRaSH Tiered Group</span>`)}let T="";T+=this.buildBannedGroupAlert(e.bannedGroup);const b=[e.tmdbMatch,e.seasonEpisode,e.namingGuide,e.elementOrder,e.bannedGroup,e.screenshots];let u="";u+=this.buildSimple("tmdb","TMDB Title Match",e.tmdbMatch),e.seasonEpisode.status!=="na"&&(u+=this.buildSimple("season","Season / Episode Format",e.seasonEpisode));const D=e.bannedGroup.tieredInfo?`<span class="mh-badge mh-badge--info" title="${e.bannedGroup.tieredInfo.join(", ")}">TRaSH Tiered Group</span>`:"";u+=this.buildSimple("group","Release Group",e.bannedGroup,{alert:e.bannedGroup.alert,extraBadge:D}),u+=this.buildSimple("screenshots","Screenshots",e.screenshots),u+=this.buildElementOrder(e.elementOrder),u+=this.buildNamingGuide(e.namingGuide),T+=this.sectionGroup("Content & Naming",u,b);const x=[e.folderStructure,e.containerFormat,e.mediaInfo,e.audioTags,e.subtitleRequirement,e.encodeCompliance,e.packUniformity,e.upscaleDetection,e.resolutionTypeMatch];let p="";e.folderStructure.status!=="na"&&(p+=this.buildSimple("folder","Folder Structure",e.folderStructure)),e.containerFormat.status!=="na"&&(p+=this.buildSimple("container","Container Format",e.containerFormat)),p+=this.buildSimple("mediainfo","MediaInfo",e.mediaInfo),e.subtitleRequirement.status!=="na"&&(p+=this.buildSimple("subs","Subtitle Requirement",e.subtitleRequirement)),p+=this.buildSimple("upscale","Upscale Detection",e.upscaleDetection),p+=this.buildSimple("restype","Resolution Type",e.resolutionTypeMatch),p+=this.buildMultiCheck("audio","Audio Compliance",e.audioTags),e.encodeCompliance.status!=="na"&&(p+=this.buildMultiCheck("encode","Encode Compliance",e.encodeCompliance)),e.packUniformity.status!=="na"&&(p+=this.buildMultiCheck("pack","Pack Uniformity",e.packUniformity)),T+=this.sectionGroup("Technical",p,x);const y=G.collectIssues(e),C=G.buildMessage(y);let h="";if(C){const i=C.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");h=` </details>`},createPanel(e){const n=document.createElement("section");n.className="panelV2 mh-panel",n.id="mod-helper-panel";const s=[e.tmdbMatch,e.seasonEpisode,e.namingGuide,e.elementOrder,e.folderStructure,e.mediaInfo,e.audioTags,e.subtitleRequirement,e.screenshots,e.bannedGroup,e.encodeCompliance,e.upscaleDetection,e.containerFormat,e.packUniformity,e.resolutionTypeMatch,...(e._dpRows||[]).map(([k])=>e[k])].map(i=>i.status),a=this.worstStatus(s),o=s.filter(i=>i!=="na"&&i!=="advisory"),c=o.filter(i=>i==="pass").length,r=o.filter(i=>i==="warn").length,d=o.filter(i=>i==="fail").length,f=o.length;let A=[];if(d&&A.push(`<span class="mh-chip mh-chip--fail">${d} failed</span>`),r&&A.push(`<span class="mh-chip mh-chip--warn">${r} warning${r>1?"s":""}</span>`),A.push(`<span class="mh-chip mh-chip--pass">${c}/${f} passed</span>`),e.bannedGroup.tieredInfo){const i=e.bannedGroup.tieredInfo.join(", ");A.push(`<span class="mh-chip mh-chip--pass" title="${i}">TRaSH Tiered Group</span>`)}let T="";T+=this.buildBannedGroupAlert(e.bannedGroup);const b=[e.tmdbMatch,e.seasonEpisode,e.namingGuide,e.elementOrder,e.bannedGroup,e.screenshots];let u="";u+=this.buildSimple("tmdb","TMDB Title Match",e.tmdbMatch),e.seasonEpisode.status!=="na"&&(u+=this.buildSimple("season","Season / Episode Format",e.seasonEpisode));const D=e.bannedGroup.tieredInfo?`<span class="mh-badge mh-badge--info" title="${e.bannedGroup.tieredInfo.join(", ")}">TRaSH Tiered Group</span>`:"";u+=this.buildSimple("group","Release Group",e.bannedGroup,{alert:e.bannedGroup.alert,extraBadge:D}),u+=this.buildSimple("screenshots","Screenshots",e.screenshots),u+=this.buildElementOrder(e.elementOrder),u+=this.buildNamingGuide(e.namingGuide),T+=this.sectionGroup("Content & Naming",u,b);const x=[e.folderStructure,e.containerFormat,e.mediaInfo,e.audioTags,e.subtitleRequirement,e.encodeCompliance,e.packUniformity,e.upscaleDetection,e.resolutionTypeMatch];let p="";e.folderStructure.status!=="na"&&(p+=this.buildSimple("folder","Folder Structure",e.folderStructure)),e.containerFormat.status!=="na"&&(p+=this.buildSimple("container","Container Format",e.containerFormat)),p+=this.buildSimple("mediainfo","MediaInfo",e.mediaInfo),e.subtitleRequirement.status!=="na"&&(p+=this.buildSimple("subs","Subtitle Requirement",e.subtitleRequirement)),p+=this.buildSimple("upscale","Upscale Detection",e.upscaleDetection),p+=this.buildSimple("restype","Resolution Type",e.resolutionTypeMatch),p+=this.buildMultiCheck("audio","Audio Compliance",e.audioTags),e.encodeCompliance.status!=="na"&&(p+=this.buildMultiCheck("encode","Encode Compliance",e.encodeCompliance)),e.packUniformity.status!=="na"&&(p+=this.buildMultiCheck("pack","Pack Uniformity",e.packUniformity)),T+=this.sectionGroup("Technical",p,x);if(e._dpRows&&e._dpRows.length){const dr=e._dpRows;let dh="";for(const [dk,dl] of dr){const v=e[dk];dh+=Array.isArray(v.checks)&&v.checks.length>1?this.buildMultiCheck("dp-"+dk,dl,v):this.buildSimple("dp-"+dk,dl,v)}T+=this.sectionGroup("DarkPeers Rules",dh,dr.map(([k])=>e[k]))}const y=G.collectIssues(e),C=G.buildMessage(y);let h="";if(C){const i=C.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");h=`
<div class="mh-message-block"> <div class="mh-message-block">
<div class="mh-message-block__header"> <div class="mh-message-block__header">
<i class="fas fa-clipboard-list mh-message-block__icon"></i> <i class="fas fa-clipboard-list mh-message-block__icon"></i>
@@ -5080,6 +5130,10 @@ function main() {
results.dpTitle = TitleValidator.validate(data.torrentName, data.category, data.type, data.mediaInfoText); results.dpTitle = TitleValidator.validate(data.torrentName, data.category, data.type, data.mediaInfoText);
} }
// Settings toggles, then the DarkPeers rows for the panel and the message
applyCheckToggles(results, Settings.load().checks);
results._dpRows = dpSectionRows(results);
// Inject CSS via GM_addStyle // Inject CSS via GM_addStyle
if (typeof GM_addStyle === "function") { if (typeof GM_addStyle === "function") {
GM_addStyle(Z); GM_addStyle(Z);