Identity: other quoted text, text separators, ids in image names, more
- Quoted text other than the file name stays in the remainder: ">>> CREATIVE
COMMONS NZB <<< "0190 alarm 5.0 " - File 1 of 9: "…rar"" made 12,605
files of all uploads one release.
- namesRelease accepts words joined by , & : ; \ / + ("Posting & deleting,
read 0 file "E:\VladModels\y038_Irina\185" …"): such image sets fell to
the stem rule ("P8250001.JPG"), one release over all folders.
- imageSet: a 5+ digit number left in the set is a per-image id
("sss-70556-3474182-23-10825418-pc", "Alena p 26663_…"): no set. Copy
markers may repeat ("diana-050-052[1][1]").
- unquotedName: an image after numbered text without a separator is the
last word ("<abm> … AB: part2 0573-1002 043.jpg").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e1d21d1e7c
commit
3fc38edda8
6 files changed
+84
-18
No files matched your search
+26
-10
@@ -465,13 +465,15 @@ pub fn image_set(stem: &str) -> String {
|
||||
break;
|
||||
}
|
||||
}
|
||||
match s.iter().rposition(u8::is_ascii_digit) {
|
||||
Some(last) => {
|
||||
let start = s[..=last].iter().rposition(|c| !c.is_ascii_digit()).map_or(0, |i| i + 1);
|
||||
String::from_utf8_lossy(&s[..start]).into_owned()
|
||||
}
|
||||
None => String::new(),
|
||||
let set = match s.iter().rposition(u8::is_ascii_digit) {
|
||||
Some(last) => &s[..s[..=last].iter().rposition(|c| !c.is_ascii_digit()).map_or(0, |i| i + 1)],
|
||||
None => return String::new(),
|
||||
};
|
||||
// A number of 5+ digits left in it is an id, per image ("sss-70556-3474182-23-10825418-pc"): no set.
|
||||
if set.split(|c| !c.is_ascii_digit()).any(|run| trim_zeros(run).len() >= 5) {
|
||||
return String::new();
|
||||
}
|
||||
String::from_utf8_lossy(set).into_owned()
|
||||
}
|
||||
|
||||
/// Number(digits) equality for digit strings: without leading zeros (all zeros: "0").
|
||||
@@ -481,7 +483,7 @@ fn trim_zeros(d: &[u8]) -> &[u8] {
|
||||
}
|
||||
|
||||
static TIMESTAMP: LazyLock<Regex> = LazyLock::new(|| re(r"[-_. ]?(?:19|20)[0-9]{2}[-._ ](?:0?[1-9]|1[0-2])[-._ ][0-9]{1,2}(?:[-._ ][0-9]{1,2})*$"));
|
||||
static COPY_MARK: LazyLock<Regex> = LazyLock::new(|| re(r"SP*[\[(][0-9]+[\])]$"));
|
||||
static COPY_MARK: LazyLock<Regex> = LazyLock::new(|| re(r"(?:SP*[\[(][0-9]+[\])])+$"));
|
||||
static RESOLUTION: LazyLock<Regex> = LazyLock::new(|| re(r"(?i)[_-][0-9]{3,4}(?:x[0-9]{3,4}|px)$"));
|
||||
static IMAGEVENUE: LazyLock<Regex> = LazyLock::new(|| re(r"(?i)_123_[0-9]+lo$"));
|
||||
static ZERO_SUFFIX: LazyLock<Regex> = LazyLock::new(|| re(r"[_-]0+$"));
|
||||
@@ -637,8 +639,10 @@ pub fn release_identity(poster: &str, subject: &str, name: &str) -> Release {
|
||||
let stem = file_stem(name);
|
||||
// A name that isn't quoted (unquoted_name) is taken out as the quotes would have been.
|
||||
// The subject here has its spaces collapsed; the name may not.
|
||||
let named = if subject.contains(&format!("\"{name}\"")) {
|
||||
subject.to_string()
|
||||
// Other quoted text stays: it names the release (">>> CREATIVE COMMONS NZB <<< "0190 alarm 5.0 " - File 1 of 9: …").
|
||||
let quoted = format!("\"{name}\"");
|
||||
let named = if subject.contains("ed) {
|
||||
subject.replacen("ed, " ", 1).replace('"', " ")
|
||||
} else {
|
||||
let collapsed = js::collapse_spaces(name);
|
||||
let collapsed = js::trim(&collapsed);
|
||||
@@ -916,7 +920,7 @@ pub fn upload_tool(message_id: &str) -> &'static str {
|
||||
|
||||
/// [A-Za-z]{2,}[._ -]+[A-Za-z0-9]{2,} anywhere.
|
||||
fn name_like(b: &[u8]) -> bool {
|
||||
let sep = |c: u8| matches!(c, b'.' | b'_' | b' ' | b'-');
|
||||
let sep = |c: u8| matches!(c, b'.' | b'_' | b' ' | b'-' | b',' | b'&' | b':' | b';' | b'\\' | b'/' | b'+');
|
||||
(2..b.len()).any(|k| {
|
||||
if !(sep(b[k]) && b[k - 1].is_ascii_alphabetic() && b[k - 2].is_ascii_alphabetic()) {
|
||||
return false;
|
||||
@@ -1221,6 +1225,9 @@ mod image_set_tests {
|
||||
("092_081_2000x1500", "092_"),
|
||||
("KP0027_197_00", "KP"),
|
||||
("01079-106-2048px", "01079-"),
|
||||
("diana-050-052[1][1]", "diana-050-"),
|
||||
("sss-70556-3474182-23-10825418-pc", ""),
|
||||
("Alena p 26663_alena-p-2-8323_123_39lo", ""),
|
||||
("she has sensual legs 172 _ 172", "she has sensual legs "),
|
||||
("jamie.lee.curtis_the.tailor.of.panama_17_123_244lo", "jamie.lee.curtis_the.tailor.of.panama_"),
|
||||
("JimAndJoey Kindly Husband-to-Be", ""),
|
||||
@@ -1238,6 +1245,15 @@ mod image_set_tests {
|
||||
assert_eq!(mint("JimAndJoey Kindly Husband-to-Be.JPG").key, mint("Oops OnlyOneMore.JPG").key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn other_quoted_text_and_text_separators_name_the_release() {
|
||||
let cc = |name: &str, n: &str| release_identity("p", &format!(r#">>> CREATIVE COMMONS NZB <<< "{name} " - File 1 of 9: "creative_commons_nzb_{n}.rar" yEnc"#), &format!("creative_commons_nzb_{n}.rar"));
|
||||
assert_ne!(cc("0190 alarm 5.0", "0190_alarm_5.0_").key, cc("portable irfanview 4.22", "portable_irfanview_4.22").key);
|
||||
let vlad = |dir: &str, total: u32, n: &str| release_identity("p", &format!(r#"Posting & deleting, read 0 file "E:\VladModels\y038_Irina\{dir}" Day 5/6 [01/{total}] - {n} yEnc"#), n);
|
||||
assert_eq!(vlad("185", 77, "P8250001.JPG").source, "subject");
|
||||
assert_ne!(vlad("185", 77, "P8250001.JPG").key, vlad("234", 77, "P5300085.JPG").key);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn images_without_words_by_their_set() {
|
||||
let id = |n: &str, c: &str| release_identity("p", &format!(r#"##[ "{n}" ({c})"#), n);
|
||||
|
||||
Reference in new issue
Block a user