Unquoted album tracks: the name starts at the track number
Test and deploy / test (push) Successful in 43s
Test and deploy / edge (push) Successful in 1m50s
Test and deploy / deploy (push) Successful in 1m21s

"A Strange Light from the East - Eastern Influenced Western Music
(1965-72) - CD2 - 07 - Rascals - Sattva.mp3 (1/43)": unquotedName cut at
the last " - " ("Sattva.mp3"), leaving track number and artist in the
subject, so every track was a release (85665085, 85665050). With a
" - NN - " track or part number the name starts there ("07 - Rascals -
Sattva.mp3"), the rest names the album and disc. Both implementations;
tests; fixtures identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Opus 5.5 committed 2026-10-11 22:41:54 +02:00
1 parent e0a0d0d520
commit 8d400822bd
4 files changed
+29 -2

No files matched your search

+17 -1
View File
@@ -259,6 +259,20 @@ fn has_extension(s: &str) -> bool {
s[..dot].chars().last().is_some_and(|c| c != '.' && !js::is_space(c))
}
/// The first / - \d{1,3} - / in `text`: the index of its " - ".
fn first_track(text: &str) -> Option<usize> {
let b = text.as_bytes();
let mut from = 0;
while let Some(i) = text[from..].find(" - ").map(|i| i + from) {
let digits = b[i + 3..].iter().take_while(|c| c.is_ascii_digit()).count();
if (1..=3).contains(&digits) && b[i + 3 + digits..].starts_with(b" - ") {
return Some(i);
}
from = i + 1;
}
None
}
/// unquotedName (lib/headers/subject.ts): the file name of a subject without a quoted one, from the text before its counter.
pub fn unquoted_name(before_counter: &str) -> Option<String> {
let mut text = before_counter.trim_end_matches(js::is_space);
@@ -300,7 +314,8 @@ pub fn unquoted_name(before_counter: &str) -> Option<String> {
}
if has_extension(text) {
let bracket = text.rfind("] ").map_or(0, |i| i + 2);
let dash = text.rfind(" - ").map_or(0, |i| i + 3);
// A track or part number (/ - \d{1,3} - /): the name starts there; else after the last " - ".
let dash = first_track(text).or_else(|| text.rfind(" - ")).map_or(0, |i| i + 3);
let name = js::trim(&text[bracket.max(dash)..]);
return (!name.is_empty() && has_extension(name)).then(|| name.to_string());
}
@@ -870,6 +885,7 @@ mod unquoted_tests {
("New_Super_Mario_Bros._[Keygen].exe ", Some("New_Super_Mario_Bros._[Keygen].exe")),
("Emily_18_-_Bed.part01.rar Emily 18 bed video FULL NUDE ", Some("Emily_18_-_Bed.part01.rar")),
("[33/117] 674a37548b09.dat ", Some("674a37548b09.dat")),
("A Strange Light from the East - Eastern Influenced Western Music (1965-72) - CD2 - 07 - Rascals - Sattva.mp3 ", Some("07 - Rascals - Sattva.mp3")),
("pal! [Mivina high(1).wmv\" yEnc] ", Some("Mivina high(1).wmv")),
("[03/21 Geroellheimer - S03E16.part01.rar\" yEnc ", Some("Geroellheimer - S03E16.part01.rar")),
("[7w] - 9BbEV2MrTi59GBTEFlVrssBrXNwXf2SK9cQEeDjg yEnc ", None),
+4 -1
View File
@@ -48,7 +48,10 @@ export function unquotedName(beforeCounter: string): string | null {
}
if (EXTENSION.test(text)) {
const bracket = text.lastIndexOf('] ')
const dash = text.lastIndexOf(' - ')
// A track or part number ("Album - CD2 - 07 - Artist - Title.mp3"): the name starts there, so the rest
// is the album, the same for every track (LOG.md 2026-10-11 (10)); else after the last " - ".
const track = / - \d{1,3} - /.exec(text)
const dash = track ? track.index : text.lastIndexOf(' - ')
const cut = Math.max(bracket === -1 ? 0 : bracket + 2, dash === -1 ? 0 : dash + 3)
const name = text.slice(cut).trim()
return name && EXTENSION.test(name) ? name : null
+1
View File
@@ -53,6 +53,7 @@ test.group('subject / parseSubject', () => {
['New_Super_Mario_Bros._[Keygen].exe (1/2)', 'New_Super_Mario_Bros._[Keygen].exe', 1, 2],
['Emily_18_-_Bed.part01.rar Emily 18 bed video FULL NUDE (01/24)', 'Emily_18_-_Bed.part01.rar', 1, 24],
['[33/117] 674a37548b09.dat (1/1)', '674a37548b09.dat', 1, 1, 33],
['A Strange Light from the East - Eastern Influenced Western Music (1965-72) - CD2 - 07 - Rascals - Sattva.mp3 (1/43)', '07 - Rascals - Sattva.mp3', 1, 43],
["pal! [Mivina high(1).wmv\" yEnc] (323/349)", 'Mivina high(1).wmv', 323, 349],
['[03/21 Geroellheimer - S03E16.part01.rar" yEnc (1/50)', 'Geroellheimer - S03E16.part01.rar', 1, 50],
]
+7
View File
@@ -187,6 +187,13 @@ test.group('release / par2 names', () => {
assert.isFalse(randomPoster('w.merklein@freenet.de (muffin)'))
})
test('album tracks with unquoted names are one release per disc', async ({ assert }) => {
const { parseSubject } = await import('#lib/headers/index')
const id = (subject: string) => releaseIdentity({ poster: 'Hannah_Qe@hotmail.com (Spidey)', subject: subject.replace(/ \(\d+\/\d+\)$/, ''), name: parseSubject(subject)!.name, weak: false })!
const album = 'A Strange Light from the East - Eastern Influenced Western Music (1965-72) - CD2'
assert.equal(id(`${album} - 07 - Rascals - Sattva.mp3 (1/43)`).key, id(`${album} - 08 - Incredible String Band - Koeeoaddi There.mp3 (1/47)`).key)
})
test('image sets: sizes in brackets and one-word set names', ({ assert }) => {
const id = (subject: string, name: string) => releaseIdentity({ poster: 'p', subject, name, weak: false })!
assert.equal(id('Aletta Ocean - "100628-035.jpg" yEnc [347K]', '100628-035.jpg').key, id('Aletta Ocean - "100628-036.jpg" yEnc [298K]', '100628-036.jpg').key)