diff --git a/edge/src/names.rs b/edge/src/names.rs index 4aa244b..f7e64a0 100644 --- a/edge/src/names.rs +++ b/edge/src/names.rs @@ -884,9 +884,12 @@ pub fn release_identity(poster: &str, subject: &str, name: &str) -> Release { let b = lower.as_bytes(); let index = if b.starts_with(b"00") { 2 + b[2..].iter().take_while(|c| matches!(c, b'-' | b'_' | b' ' | b'.')).count() } else { 0 }; let key_stem = if index > 2 { &lower[index..] } else { &lower[..] }; - Release { key: hash(&["stem", poster, key_stem]), name: stem, source: "stem", file_total } + // Nor spaces at a dash ("… XVID- Farbiges Krabbeltier.r00" beside "… XVID-Farbiges Krabbeltier.vol03+04.par2"). + let key_stem = replace(&DASH_SPACES, key_stem, "-", true); + Release { key: hash(&["stem", poster, &key_stem]), name: stem, source: "stem", file_total } } +static DASH_SPACES: LazyLock = LazyLock::new(|| re(r" *- *")); static HEX_ID: LazyLock = LazyLock::new(|| re(r"(?i)\[[0-9a-f]{8,}\]")); static VIDEO: LazyLock = LazyLock::new(|| re(r"(?i)\.(mkv|mp4|avi|m4v|ts|wmv|mov)$")); static EPISODE: LazyLock = LazyLock::new(|| re(r"(?i)^(.+?)[ ._-]+S([0-9]{1,2})E[0-9]{1,3}")); @@ -1541,6 +1544,8 @@ mod image_set_tests { 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 ); + let jb = |i: &str, n: &str| super::release_identity("JBinUp", &format!(r#"[{i}/58] - Summer Power Up - "{n}" yEnc"#), n); + assert_eq!(jb("01", "www.realmom.info - XVID- Farbiges Krabbeltier.r00").key, jb("54", "www.realmom.info - XVID-Farbiges Krabbeltier.vol03+04.par2").key); let mdg = |post: &str, i: &str, n: &str| super::release_identity("p", &format!(r#"{post} - ({i}/90) "{n}" - 16,14 MB - yEnc"#), n); assert_eq!(mdg("MDG005b", "01", "IMG_2307.JPG").key, mdg("MDG005b", "02", "IMG_2308.jpg").key); assert_ne!(mdg("MDG005b", "01", "IMG_2307.JPG").key, mdg("MDG006a", "01", "IMG_4410.JPG").key); diff --git a/lib/release/identity.ts b/lib/release/identity.ts index 2eb76d8..44bcdc8 100644 --- a/lib/release/identity.ts +++ b/lib/release/identity.ts @@ -464,7 +464,9 @@ export function releaseIdentity(input: ReleaseInput): ReleaseIdentity | null { const base = volume && postTotal && Number(volume[2]) <= postTotal ? volume[1] : stem // Without case and a scene index's "00-" ("00-laura_van_dam_-_capture_radio_113-cable-10-10-2026-talion.m3u" beside // "Laura_van_Dam_-_Capture_Radio_113-CABLE-10-10-2026-TALiON.par2": one upload, two releases; LOG.md 2026-10-12 (19)). - return { key: hash('stem', poster, base.toLowerCase().replace(/^00[-_ .]+/, '')), name: stem, fileTotal, source: 'stem' } + // Nor spaces at a dash ("www.realmom.info - XVID- Farbiges Krabbeltier.r00" beside "… XVID-Farbiges Krabbeltier.vol03+04.par2": + // 52 uploads were two releases each; LOG.md 2026-10-13 (46)). + return { key: hash('stem', poster, base.toLowerCase().replace(/^00[-_ .]+/, '').replace(/ *- */g, '-')), name: stem, fileTotal, source: 'stem' } } /** Release of a par2 recovery set; every file listed in it belongs to it. */ diff --git a/tests/unit/release/identity.spec.ts b/tests/unit/release/identity.spec.ts index bf34a11..2fad40b 100644 --- a/tests/unit/release/identity.spec.ts +++ b/tests/unit/release/identity.spec.ts @@ -290,6 +290,11 @@ test.group('release / par2 names', () => { assert.notEqual(ep(1, 'Pokemon - S02E01 - Pallet Party Panic.mkv').key, ep(1, 'Pokemon - S03E01 - x.mkv').key) }) + test('spaces at a dash are no part of a stem key', ({ assert }) => { + const id = (i: string, n: string) => releaseIdentity({ poster: 'JBinUp', subject: `[${i}/58] - Summer Power Up - "${n}" yEnc`, name: n, weak: false })! + assert.equal(id('01', 'www.realmom.info - XVID- Farbiges Krabbeltier.r00').key, id('54', 'www.realmom.info - XVID-Farbiges Krabbeltier.vol03+04.par2').key) + }) + test("a scene index's files go with the release: no case, no 00-", ({ assert }) => { const id = (n: string) => releaseIdentity({ poster: 'SavageCobra ', subject: n, name: n, weak: false })! const a = id('00-laura_van_dam_-_capture_radio_113-cable-10-10-2026-talion.m3u')