From 6f7a1692d6b90c17f39d87776094d19767f35892 Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Tue, 13 Oct 2026 05:06:02 +0200 Subject: [PATCH] runOn: a space after the extension, not a bare dash 0c5ede9 cut "Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar" at .NFO: the release lost its group, and two groups' releases of one game would merge. Co-Authored-By: Claude Opus 5.5 --- edge/src/names.rs | 4 +++- lib/release/identity.ts | 5 +++-- tests/unit/release/identity.spec.ts | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/edge/src/names.rs b/edge/src/names.rs index e583fda..2f8cb60 100644 --- a/edge/src/names.rs +++ b/edge/src/names.rs @@ -699,7 +699,8 @@ pub fn run_on(name: &str) -> &str { if rest.is_empty() { return name; } - let spaced = rest.starts_with(js::is_space) || rest.trim_start_matches(js::is_space).starts_with('-'); + // Not a bare dash ("….READ.NFO-THETA.rar"). + let spaced = rest.starts_with(js::is_space); let repeats = ascii && rest.len() >= 4 && rest.as_bytes()[..4].eq_ignore_ascii_case(&b[..4]); if spaced || repeats { return &name[..m.end()]; @@ -1496,6 +1497,7 @@ mod image_set_tests { ("Goga Sekulic.part134.rar - Goga Sekulic - Diskografija (2000-2014).", "Goga Sekulic.part134.rar"), ("HASf293jLAIWUELvhaG3.part091.rar HASf293jLAIWUELvhaG3", "HASf293jLAIWUELvhaG3.part091.rar"), ("Movie.rar.Collection.mkv", "Movie.rar.Collection.mkv"), + ("Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar", "Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar"), ("x.part01.rar", "x.part01.rar"), ] { assert_eq!(super::run_on(n), cut, "{n}"); diff --git a/lib/release/identity.ts b/lib/release/identity.ts index 950be46..04662b6 100644 --- a/lib/release/identity.ts +++ b/lib/release/identity.ts @@ -298,7 +298,8 @@ const RUN_ON = /\.(?:part\d+\.rar|vol\d+[+-]\d+\.par2|par2|rar|r\d{2,3}|7z(?:\.\ /** * A quoted name that runs on past its extension into a title ("lois 1258 Billy Joel - Extremes.part01.rar lois 1258 Billy * Joel - Extremes ", "GrooveCoverage.part26.rarGrooveCoveragebestof", "Goga Sekulic.part134.rar - Goga Sekulic - …": each - * part a release of its own): the name up to that extension, when a space or a dash follows it, or the name's own start. + * part a release of its own): the name up to that extension, when a space follows it, or the name's own start. Not a + * bare dash ("Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar" keeps its group). */ export function runOn(name: string): string { const head = name.slice(0, 4).toLowerCase() @@ -307,7 +308,7 @@ export function runOn(name: string): string { const end = m.index + m[0].length const rest = name.slice(end) if (rest.length === 0) return name - if (/^\s|^\s*-/.test(rest) || (ascii && rest.slice(0, 4).toLowerCase() === head)) return name.slice(0, end) + if (/^\s/.test(rest) || (ascii && rest.slice(0, 4).toLowerCase() === head)) return name.slice(0, end) } return name } diff --git a/tests/unit/release/identity.spec.ts b/tests/unit/release/identity.spec.ts index 9911096..bdd099d 100644 --- a/tests/unit/release/identity.spec.ts +++ b/tests/unit/release/identity.spec.ts @@ -315,6 +315,7 @@ test.group('release / par2 names', () => { assert.equal(runOn('Goga Sekulic.part134.rar - Goga Sekulic - Diskografija (2000-2014).'), 'Goga Sekulic.part134.rar') assert.equal(runOn('HASf293jLAIWUELvhaG3.part091.rar HASf293jLAIWUELvhaG3'), 'HASf293jLAIWUELvhaG3.part091.rar') assert.equal(runOn('Movie.rar.Collection.mkv'), 'Movie.rar.Collection.mkv') + assert.equal(runOn('Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar'), 'Angry.Birds.Rio.v1.2.2.cracked.READ.NFO-THETA.rar') assert.equal(runOn('x.part01.rar'), 'x.part01.rar') const lois = (i: string, n: string) => releaseIdentity({ poster: 'p', subject: `(thnx to original poster) [${i}/92] - "${n}" yEnc`, name: n, weak: false })! assert.equal(lois('02', 'lois 1258 Billy Joel - Extremes.part01.rar lois 1258 Billy Joel - Extremes ').key, lois('01', 'lois 1258 Billy Joel - Extremes.par2 lois 1258 Billy Joel - Extremes ').key)