Subject names lose the brackets the counters left unmatched
Test and deploy / test (push) Successful in 3m3s
Test and deploy / deploy (push) Successful in 2m13s

A poster's counter without its "[" ("… Facialized 002/477] - 0177.jpg")
left "… Facialized ]" as the release name (11286967). displayName (TS) and
display_name (Rust) drop unmatched brackets from subject and post names
only; the identity key keeps the remainder as it was, so no release splits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Opus 5.5 committed 2026-10-29 13:04:06 +01:00
1 parent c6f9409e7f
commit 3f0b5b8be1
4 files changed
+90 -6

No files matched your search

+51 -2
View File
@@ -449,6 +449,43 @@ fn finish_remainder(s: &str) -> String {
js::trim(&out).to_string()
}
/// displayName: a subject name as shown, brackets the counters left unmatched removed ("… Facialized 002/477] - …"
/// gave "… Facialized ]"). Only the name: the key keeps the remainder.
pub fn display_name(remainder: &str) -> String {
let b = remainder.as_bytes();
if !b.iter().any(|c| matches!(c, b'[' | b']' | b'(' | b')')) {
return remainder.to_string();
}
let mut drop = vec![false; b.len()];
for (open, close) in [(b'[', b']'), (b'(', b')')] {
let mut opens: Vec<usize> = Vec::new();
for (i, &c) in b.iter().enumerate() {
if c == open {
opens.push(i);
} else if c == close && opens.pop().is_none() {
drop[i] = true;
}
}
for i in opens {
drop[i] = true;
}
}
if !drop.contains(&true) {
return remainder.to_string();
}
let kept: Vec<u8> = b.iter().zip(&drop).filter(|(_, &d)| !d).map(|(&c, _)| c).collect();
let kept = String::from_utf8(kept).expect("only ASCII brackets removed");
let mut out = String::with_capacity(kept.len());
for c in kept.chars() {
if c == ' ' && out.ends_with(' ') {
continue;
}
out.push(c);
}
let name = js::trim(&out);
if name.is_empty() { remainder.to_string() } else { name.to_string() }
}
/// counterTotal: the subject's file counter total, first form found first.
pub fn counter_total(subject: &str) -> Option<String> {
let s = replace(&QUOTED, subject, " ", true);
@@ -841,11 +878,11 @@ pub fn release_identity(poster: &str, subject: &str, name: &str) -> Release {
if !image && test(&RANDOM_VOLUME, name) && stem.bytes().all(|c| c.is_ascii_alphanumeric() || c == b'_' || c == b'-') && looks_random(&stripped) {
parts.push(&stem);
}
return Release { key: hash(&parts), name: remainder, source: "subject", file_total };
return Release { key: hash(&parts), name: display_name(&remainder), source: "subject", file_total };
}
if let Some(total) = post_total.filter(|&n| n != 0 && !tag) {
if is_post_token(&remainder) {
return Release { key: hash(&["post", poster, &remainder, &total.to_string()]), name: remainder, source: "post", file_total };
return Release { key: hash(&["post", poster, &remainder, &total.to_string()]), name: display_name(&remainder), source: "post", file_total };
}
}
// A scene music post's index files ("00-ammar-turk_uit_de_kroeg-single-web-nl-2022-cover.jpg") under a bare counter go
@@ -1339,6 +1376,18 @@ mod tests {
assert_eq!(file_stem_re("Morning Lovers.wmv.058"), "Morning Lovers");
}
#[test]
fn display_names() {
let porn4you = "webmaster@hdbangvidz.com (Porn4You)";
let a = release_identity(porn4you, "Babe with Plump Bubble Butt Fucked and Facialized 002/477] - 0178.jpg", "0178.jpg");
let b = release_identity(porn4you, "Babe with Plump Bubble Butt Fucked and Facialized 003/477] - 0179.jpg", "0179.jpg");
assert_eq!(a.name, "Babe with Plump Bubble Butt Fucked and Facialized");
assert_eq!(a.key, b.key);
assert_eq!(display_name("[Group] Show (2020)"), "[Group] Show (2020)");
assert_eq!(display_name("( Show [x] name"), "Show [x] name");
assert_eq!(display_name("]"), "]");
}
#[test]
fn remainders() {
assert_eq!(subject_remainder(r#"Some.Release [01/45] - "x.rar" yEnc (1/50) 7168"#), "Some Release");