From 62250081ef979755a694c8ca71da56df96a18854 Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Mon, 12 Oct 2026 18:24:42 +0200 Subject: [PATCH] A poster tag of 4+ words may share one with the stem "German Board - [Usenet4ever.info] und [SecretUsenet.com] - "21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar"": "German" in the stem made the tag a name, and the poster's readable uploads were releases of 1,422 and 1,535 files. Co-Authored-By: Claude Opus 5.5 --- edge/src/names.rs | 9 +++++++-- lib/release/identity.ts | 9 +++++++-- tests/unit/release/identity.spec.ts | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/edge/src/names.rs b/edge/src/names.rs index f6c73da..1fb6d59 100644 --- a/edge/src/names.rs +++ b/edge/src/names.rs @@ -605,6 +605,7 @@ pub fn is_poster_tag(remainder: &str, stem: &str) -> bool { return false; } let rem = remainder.to_lowercase(); + let (mut significant, mut shared) = (0, 0); for word in rem.split(|c: char| !(c.is_ascii_lowercase() || c.is_ascii_digit())) { if !word.is_empty() && word.bytes().all(|c| c.is_ascii_digit()) { if word.len() >= 2 && whole.contains(word) { @@ -615,11 +616,13 @@ pub fn is_poster_tag(remainder: &str, stem: &str) -> bool { if word.len() < 3 || TAG_WORDS.contains(&word) { continue; } + significant += 1; if if word.len() >= 4 { compact.contains(word) } else { whole.contains(word) } { - return false; + shared += 1; } } - true + // A tag of 4+ words may share one with the stem ("German Board - [Usenet4ever.info] und [SecretUsenet.com]"). + shared == 0 || (shared == 1 && significant >= 4) } /// releaseIdentity for a named (not weak) file: never null. @@ -1402,6 +1405,8 @@ mod image_set_tests { let gb = |n: &str| release_identity("p", &format!(r#"German Board - [Usenet4ever.info] und [SecretUsenet.com] - "{n}" yEnc"#), n); assert_eq!(gb("6c57319fbae505679737bd46a76193a1-u4e.part6.rar").key, gb("6c57319fbae505679737bd46a76193a1-u4e.par2").key); assert_ne!(gb("6c57319fbae505679737bd46a76193a1-u4e.part6.rar").key, gb("6fc0ff192a355703b3e81557893013b1-u4e.part6.rar").key); + assert_ne!(gb("21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar").key, gb("Ice.Age.4.Voll.verschoben.2012.BDRip.AC3.German.XviD-POE.part01.rar").key); + assert_eq!(gb("21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar").key, gb("21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.par2").key); let pck = |i: &str, n: &str| release_identity("p", &format!(r#"(????) [{i}/2195] - "{n}" yEnc"#), n); assert_eq!(pck("0659", "DN.VPL PCK.1508").key, pck("0660", "DN.VPL PCK.1509").key); assert_eq!(pck("0659", "DN.VPL PCK.1508").name, "DN.VPL PCK.1508"); diff --git a/lib/release/identity.ts b/lib/release/identity.ts index 556f916..1cb12fc 100644 --- a/lib/release/identity.ts +++ b/lib/release/identity.ts @@ -244,15 +244,20 @@ export function isPosterTag(remainder: string, stem: string): boolean { const whole = new Set(words.split(' ')) // A per-post id, also inside a word ("FTD772544"). if (/\d{5,}/.test(remainder)) return false + let significant = 0 + let shared = 0 for (const word of remainder.toLowerCase().split(/[^a-z0-9]+/)) { if (/^\d+$/.test(word)) { if (word.length >= 2 && whole.has(word)) return false continue } if (word.length < 3 || TAG_WORDS.has(word)) continue - if (word.length >= 4 ? compact.includes(word) : whole.has(word)) return false + significant++ + if (word.length >= 4 ? compact.includes(word) : whole.has(word)) shared++ } - return true + // A tag of 4+ words may share one with the stem ("German Board - [Usenet4ever.info] und [SecretUsenet.com] - + // "21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar"": the poster's uploads were releases of 1,535 files). + return shared === 0 || (shared === 1 && significant >= 4) } /** diff --git a/tests/unit/release/identity.spec.ts b/tests/unit/release/identity.spec.ts index dcf0b2a..02fb312 100644 --- a/tests/unit/release/identity.spec.ts +++ b/tests/unit/release/identity.spec.ts @@ -331,6 +331,8 @@ test.group('release / par2 names', () => { const gb = (n: string) => id(`German Board - [Usenet4ever.info] und [SecretUsenet.com] - "${n}" yEnc`, n) assert.equal(gb('6c57319fbae505679737bd46a76193a1-u4e.part6.rar').key, gb('6c57319fbae505679737bd46a76193a1-u4e.par2').key) assert.notEqual(gb('6c57319fbae505679737bd46a76193a1-u4e.part6.rar').key, gb('6fc0ff192a355703b3e81557893013b1-u4e.part6.rar').key) + assert.notEqual(gb('21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar').key, gb('Ice.Age.4.Voll.verschoben.2012.BDRip.AC3.German.XviD-POE.part01.rar').key) + assert.equal(gb('21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.part01.rar').key, gb('21.Jump.Street.2012.BDRip.AC3.German.XviD-POE.par2').key) const pck = (i: string, n: string) => id(`(????) [${i}/2195] - "${n}" yEnc`, n) assert.equal(pck('0659', 'DN.VPL PCK.1508').key, pck('0660', 'DN.VPL PCK.1509').key) assert.equal(pck('0659', 'DN.VPL PCK.1508').name, 'DN.VPL PCK.1508')