From 7b7175c229f0548f8a092c46070f4acad125b7e9 Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Fri, 9 Oct 2026 12:23:47 +0200 Subject: [PATCH] Rebuild: an image without words around it is keyed as a stem So a cover 'x.jpg' joins 'x.part01.rar' in a stem-named post; an image set like 'IMG_008' keys as the stem 'IMG'. Both implementations. Co-Authored-By: Claude Opus 5.5 --- lib/release/identity.ts | 4 ++-- tests/unit/release/identity.spec.ts | 2 ++ tools/edge-bench-rs/src/names.rs | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/release/identity.ts b/lib/release/identity.ts index 1a46afd..30c1c36 100644 --- a/lib/release/identity.ts +++ b/lib/release/identity.ts @@ -226,8 +226,8 @@ export function releaseIdentity(input: ReleaseInput): ReleaseIdentity | null { if (!tag && fileTotal && isPostToken(remainder)) { return { key: hash('post', input.poster, remainder, fileTotal), name: remainder, fileTotal, source: 'post' } } - // An image without words around it: its set by its name. - if (image) return { key: hash('images', input.poster, prefix), name: prefix || stem, fileTotal, source: 'stem' } + // An image without words around it: its set by its name (keyed as a stem, so "x.jpg" joins "x.part01.rar"). + if (image) return { key: hash('stem', input.poster, prefix || stem), name: prefix || stem, fileTotal, source: 'stem' } // The [i/M] total is informational, not part of the key: posters often // upload the par2 index without a counter, and it belongs to the same post. return { key: hash('stem', input.poster, stem), name: stem, fileTotal, source: 'stem' } diff --git a/tests/unit/release/identity.spec.ts b/tests/unit/release/identity.spec.ts index feac59b..d205877 100644 --- a/tests/unit/release/identity.spec.ts +++ b/tests/unit/release/identity.spec.ts @@ -229,5 +229,7 @@ test.group('release / par2 names', () => { const par2 = id('(Geisterjäger John Sinclair Hörspiele Vol. 2) [59/59] - "Hörspiele Vol. 2.par2" yEnc', 'Hörspiele Vol. 2.par2') assert.equal(t1.key, t2.key) assert.equal(t1.key, par2.key) + // A cover without words around it joins its stem's archive. + assert.equal(id('[2/6] - "x.jpg" yEnc', 'x.jpg').key, id('[1/6] - "x.part01.rar" yEnc', 'x.part01.rar').key) }) }) diff --git a/tools/edge-bench-rs/src/names.rs b/tools/edge-bench-rs/src/names.rs index c037df2..e3a42cb 100644 --- a/tools/edge-bench-rs/src/names.rs +++ b/tools/edge-bench-rs/src/names.rs @@ -534,7 +534,7 @@ pub fn release_identity(poster: &str, subject: &str, name: &str) -> Release { } if image { let name = if prefix.is_empty() { stem.clone() } else { prefix.clone() }; - return Release { key: hash(&["images", poster, &prefix]), name, source: "stem", file_total }; + return Release { key: hash(&["stem", poster, &name]), name, source: "stem", file_total }; } Release { key: hash(&["stem", poster, &stem]), name: stem, source: "stem", file_total } } @@ -947,6 +947,8 @@ mod tests { let par2 = id(r#"(Geisterjäger John Sinclair Hörspiele Vol. 2) [59/59] - "Hörspiele Vol. 2.par2" yEnc"#, "Hörspiele Vol. 2.par2"); assert_eq!(t1.key, t2.key); assert_eq!(t1.key, par2.key); + // A cover without words around it joins its stem's archive. + assert_eq!(id(r#"[2/6] - "x.jpg" yEnc"#, "x.jpg").key, id(r#"[1/6] - "x.part01.rar" yEnc"#, "x.part01.rar").key); } #[test]