diff --git a/CHANGELOG.md b/CHANGELOG.md index 82320e0..0a6d356 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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/). +## [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 ### Fixed @@ -16,28 +25,75 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this ### 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. -- **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. +- **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. +- **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. +- **Search button idle message** — changed to "Idle — use the Search button above to check" for clarity. ### 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. -- **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. +- **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. + +### Changed + +- **Search button styling** — moved to left-aligned position below section header with subtle blue accent for better visibility. + +## [0.6.5] - 2026-04-10 + +### 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 diff --git a/modq-helper-darkpeers.user.js b/modq-helper-darkpeers.user.js index 2ac424f..10a68f6 100644 --- a/modq-helper-darkpeers.user.js +++ b/modq-helper-darkpeers.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name UNIT3D Mod Queue Helper — DarkPeers // @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 // @author TQG Contributors // @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}}; +/* ======================================================================== + * 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 * Ported from the original U object. @@ -4286,7 +4336,7 @@ const U={getStatusIcon(e){switch(e){case"pass":return'${e}`},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` + `:""},groupHeading(e){return`
${e}
`},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`
${a}/${o} passed @@ -4294,7 +4344,7 @@ const U={getStatusIcon(e){switch(e){case"pass":return'
${n}
-
`},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(`${d} failed`),r&&A.push(`${r} warning${r>1?"s":""}`),A.push(`${c}/${f} passed`),e.bannedGroup.tieredInfo){const i=e.bannedGroup.tieredInfo.join(", ");A.push(`TRaSH Tiered Group`)}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?`TRaSH Tiered Group`:"";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,"&").replace(//g,">");h=` + `},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(`${d} failed`),r&&A.push(`${r} warning${r>1?"s":""}`),A.push(`${c}/${f} passed`),e.bannedGroup.tieredInfo){const i=e.bannedGroup.tieredInfo.join(", ");A.push(`TRaSH Tiered Group`)}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?`TRaSH Tiered Group`:"";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,"&").replace(//g,">");h=`
@@ -5080,6 +5130,10 @@ function main() { 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 if (typeof GM_addStyle === "function") { GM_addStyle(Z);