diff --git a/edge/src/names.rs b/edge/src/names.rs index 7c47d66..78dc549 100644 --- a/edge/src/names.rs +++ b/edge/src/names.rs @@ -68,8 +68,8 @@ pub fn file_stem_re(name: &str) -> String { stem } -/// Old-style rar volumes after .r99, as the file's own extension, lower case: /\.[s-z]\d{2}$/. -static OLD_RAR_VOLUME: LazyLock = LazyLock::new(|| re(r"\.[s-z][0-9]{2}$")); +/// Old-style rar volumes after .r99, as the file's own extension, lower case, not x or z (".x64"): /\.[s-v]\d{2}$/. +static OLD_RAR_VOLUME: LazyLock = LazyLock::new(|| re(r"\.[s-v][0-9]{2}$")); static QUOTED: LazyLock = LazyLock::new(|| re(r#""[^"]*""#)); static COUNTERS: LazyLock = LazyLock::new(|| re(r"\[[0-9]+/[0-9]+\]|\([0-9]+/[0-9]+\)")); static YENC_END: LazyLock = LazyLock::new(|| re(r"(?i)\byEnc\b(SP+[0-9]+)?SP*$")); @@ -216,7 +216,7 @@ pub fn file_stem(name: &str) -> String { let b = stem.as_bytes(); let mut len = b.len(); // Old-style rar volumes after .r99 (".s41"), as the file's own extension, lower case. - if len >= 4 && b[len - 4] == b'.' && (b's'..=b'z').contains(&b[len - 3]) && b[len - 2..].iter().all(u8::is_ascii_digit) { + if len >= 4 && b[len - 4] == b'.' && (b's'..=b'v').contains(&b[len - 3]) && b[len - 2..].iter().all(u8::is_ascii_digit) { len -= 4; } let mut changed = true; @@ -1427,6 +1427,7 @@ mod image_set_tests { ("x8ZRmX5N83mrokOwqJtoIGHTrqXQrgCyj.s00", "x8ZRmX5N83mrokOwqJtoIGHTrqXQrgCyj"), ("the.office.us.s01.rar", "the.office.us.s01"), ("Some.Show.S01", "Some.Show.S01"), + ("Electric.Rain.Swift.3D.PS.v1.0.142.x64", "Electric.Rain.Swift.3D.PS.v1.0.142.x64"), ("chappelle1.part02.rev", "chappelle1"), ("chappelle1.rev", "chappelle1"), ("VwE3i90MVX9dqMFuDfzdS7Q6.part1.par2", "VwE3i90MVX9dqMFuDfzdS7Q6"), diff --git a/lib/release/identity.ts b/lib/release/identity.ts index 72ac3a9..d571414 100644 --- a/lib/release/identity.ts +++ b/lib/release/identity.ts @@ -48,9 +48,9 @@ const SUFFIXES = [ /** Strips per-file suffixes (volume numbers, archive and par2 extensions) from a filename. */ export function fileStem(name: string): string { - // Old-style rar volumes after .r99 ("BD_NoTHing018.s41", "….s00"): only as the file's own extension, in lower case, so - // a season ("show.s01.rar", "Show.S01") stays. - let stem = name.trim().replace(/\.[s-z]\d{2}$/, '') + // Old-style rar volumes after .r99 ("BD_NoTHing018.s41", "….s00", ".t91", ".v81"): only as the file's own extension, in + // lower case, so a season ("show.s01.rar", "Show.S01") stays; not x or z (".x64", ".x86" builds; ".z01" goes with .zip). + let stem = name.trim().replace(/\.[s-v]\d{2}$/, '') let changed = true while (changed) { changed = false diff --git a/tests/unit/release/identity.spec.ts b/tests/unit/release/identity.spec.ts index 8d20d0e..2e51327 100644 --- a/tests/unit/release/identity.spec.ts +++ b/tests/unit/release/identity.spec.ts @@ -304,6 +304,7 @@ test.group('release / par2 names', () => { // A season stays. assert.equal(fileStem('the.office.us.s01.rar'), 'the.office.us.s01') assert.equal(fileStem('Some.Show.S01'), 'Some.Show.S01') + assert.equal(fileStem('Electric.Rain.Swift.3D.PS.v1.0.142.x64'), 'Electric.Rain.Swift.3D.PS.v1.0.142.x64') assert.equal(fileStem('chappelle1.part02.rev'), 'chappelle1') assert.equal(fileStem('chappelle1.rev'), 'chappelle1') assert.equal(fileStem('VwE3i90MVX9dqMFuDfzdS7Q6.part1.par2'), 'VwE3i90MVX9dqMFuDfzdS7Q6')