Rebuild: a poster's constant tag no longer makes one release of all their uploads
Release 145637 held four albums: the poster puts '[KiLL.dA.FuCkIn.
EaStErRaBbIt]----' before every upload, and the text outside the quotes
(when it names a release) was the key with the poster. The same made
one release of a poster's albums under '(PowBeertje80 Posted)' (a post
id, with the same [i/M]), of masterposts' films, and of one volume of
every set in a DVD9 post.
Now, when the file's stem describes something itself (12+ letters and
digits, two words of 3+ letters) and the text outside the quotes shares
no word with it (4+ letters as part of the stem, 3-letter words and
numbers whole; boilerplate like www/net/posted not counted; no 5+ digit
per-post id), that text is taken for the poster's tag and the stem
says which release the file is. Albums of track files ('FTA … Ketchup'),
'DIE_ZEIT_35' with '35_China_dl', 'FTD769997' posts, scene names with
abbreviated file names ('grp-sm') and generic sidecars ('file_id.diz')
keep their grouping.
releases:regroup re-keys a sample of the catalog with the current rule:
on homelab's test data 145637 → 4 albums, 111566 → 17 albums of 27
files, the rest of the subject releases that change mostly lose an ad
image ('Flyer-download-2-Day.gif'); stem releases unchanged. Ported to
edge-bench-rs: check.ts still finds all captures identical (ath 2013:
16 → 76 releases on both sides).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d256619e5
commit
59481037fb
4 files changed
+214
-4
No files matched your search
@@ -348,15 +348,76 @@ fn hash(parts: &[&str]) -> String {
|
||||
sha1_hex(&parts.join("\n"))
|
||||
}
|
||||
|
||||
/// A name that says what it is: 12+ letters and digits, two words of 3+ letters (`describes`).
|
||||
fn describes(stem: &str) -> bool {
|
||||
let b = stem.as_bytes();
|
||||
if b.iter().filter(|c| c.is_ascii_alphanumeric()).count() < 12 {
|
||||
return false;
|
||||
}
|
||||
// [A-Za-z]{3,}[^A-Za-z0-9]+[A-Za-z]{3,}
|
||||
let mut i = 0;
|
||||
while i < b.len() {
|
||||
let letters = b[i..].iter().take_while(|c| c.is_ascii_alphabetic()).count();
|
||||
if letters == 0 {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
let end = i + letters;
|
||||
if letters >= 3 {
|
||||
let gap = b[end..].iter().take_while(|c| !c.is_ascii_alphanumeric()).count();
|
||||
if gap > 0 && b[end + gap..].iter().take_while(|c| c.is_ascii_alphabetic()).count() >= 3 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
i = end;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
const TAG_WORDS: [&str; 21] = [
|
||||
"www", "http", "https", "com", "net", "org", "info", "the", "and", "presents", "posted", "post", "powered", "yenc", "part", "rar", "par2", "nzb", "voor", "for", "from",
|
||||
];
|
||||
|
||||
/// isPosterTag: the text outside the quotes shares no word with the file's stem.
|
||||
pub fn is_poster_tag(remainder: &str, stem: &str) -> bool {
|
||||
let lower = stem.to_lowercase();
|
||||
let words: Vec<&str> = lower.split(|c: char| !(c.is_ascii_lowercase() || c.is_ascii_digit())).filter(|w| !w.is_empty()).collect();
|
||||
let compact: String = words.concat();
|
||||
let whole: std::collections::HashSet<&str> = words.iter().copied().collect();
|
||||
// A per-post id, also inside a word ("FTD772544").
|
||||
let b = remainder.as_bytes();
|
||||
if b.windows(5).any(|w| w.iter().all(u8::is_ascii_digit)) {
|
||||
return false;
|
||||
}
|
||||
let rem = remainder.to_lowercase();
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if word.len() < 3 || TAG_WORDS.contains(&word) {
|
||||
continue;
|
||||
}
|
||||
if if word.len() >= 4 { compact.contains(word) } else { whole.contains(word) } {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// releaseIdentity for a named (not weak) file: never null.
|
||||
pub fn release_identity(poster: &str, subject: &str, name: &str) -> Release {
|
||||
let file_total = file_counter_total(subject);
|
||||
let stem = file_stem(name);
|
||||
let remainder = subject_remainder(subject);
|
||||
if names_release(&remainder) {
|
||||
// The poster's constant tag outside the quotes: the file's stem says which upload it is.
|
||||
let tag = describes(&stem) && !looks_random(&stem) && is_poster_tag(&remainder, &stem);
|
||||
if !tag && names_release(&remainder) {
|
||||
return Release { key: hash(&["subject", poster, &remainder]), name: remainder, source: "subject", file_total };
|
||||
}
|
||||
if let Some(total) = file_total.filter(|&n| n != 0) {
|
||||
if let Some(total) = file_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 };
|
||||
}
|
||||
@@ -722,6 +783,24 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poster_tags_as_in_the_typescript() {
|
||||
let kill = "www.ggb.6x.to <darkness@earth.de>";
|
||||
let a = release_identity(kill, r#"[KiLL.dA.FuCkIn.EaStErRaBbIt]---- (03/10) "Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].r00" yEnc"#, "Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].r00");
|
||||
let nfo = release_identity(kill, r#"[KiLL.dA.FuCkIn.EaStErRaBbIt]---- (01/10) "Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].nfo" yEnc"#, "Cephalgy.-.Weisses.Fleisch.2003[[g.6x.to]].nfo");
|
||||
let b = release_identity(kill, r#"[KiLL.dA.FuCkIn.EaStErRaBbIt]---- (03/10) "Shnarph.-.Lautlos.2008[[g.6x.to]].r00" yEnc"#, "Shnarph.-.Lautlos.2008[[g.6x.to]].r00");
|
||||
assert_eq!(a.key, nfo.key);
|
||||
assert_ne!(a.key, b.key);
|
||||
assert_eq!(a.source, "stem");
|
||||
let ftd1 = release_identity("p", r#"FTD769997 [01/23] - "Prison.Break.S04E02.720p.part01.rar" yEnc"#, "Prison.Break.S04E02.720p.part01.rar");
|
||||
let ftd2 = release_identity("p", r#"FTD769997 [23/23] - "Prison.Break.S04E02.720p.part.par2" yEnc"#, "Prison.Break.S04E02.720p.part.par2");
|
||||
assert_eq!(ftd1.key, ftd2.key);
|
||||
let scene = release_identity("p", r#"Some.Movie.2008.DVDRip.XviD-GRP [01/40] - "grp-sm.part01.rar" yEnc"#, "grp-sm.part01.rar");
|
||||
assert_eq!(scene.name, "Some Movie 2008 DVDRip XviD GRP");
|
||||
assert!(is_poster_tag("PowBeertje80 Posted", "Bravo Hits Vol.14 2CD -1996-"));
|
||||
assert!(!is_poster_tag("Audiofiles DIE ZEIT 35", "35_China_dl"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_names() {
|
||||
assert!(looks_random("prvjr7hapd0i1ny14pz4"));
|
||||
|
||||
Reference in new issue
Block a user