diff --git a/CHANGELOG.md b/CHANGELOG.md index b040709..08bb5a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,10 @@ Versioning: two-part `MAJOR.MINOR` — each release bumps the minor (features an are now always required keywords. In the same pass, a small abbreviation map (street/st, saint/st, mount/mt, doctor/dr, versus/vs, number/no) lets a candidate spelled "700 Main St" match a release titled "700 Main Street" — that mismatch had rejected the correct official Art Track in every step, - which is why the search fell through to the wrong video in the first place. + which is why the search fell through to the wrong video in the first place. A re-release year next + to a qualifier ("… - 2020 Remaster") is exempt from the number rule: it appears on the release but + never in the YouTube title. Measured against a 29-title sample, 24 titles keep their previous + behaviour exactly. --- diff --git a/CLAUDE.md b/CLAUDE.md index 822d73b..6c0b6f3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -99,8 +99,10 @@ On the deploy host the music lives at `/opt/navidrome/music`. check, so nothing else caught it). Numeric tokens are now emitted as `\b\b` in addition to the two longest words. Same fix carries a small abbreviation map (street/st, saint/st, mount/mt, doctor/dr, versus/vs, number/no): uploaders write "700 Main St" where the release says "Street", - which had rejected the correct official Art Track in every step. Unit-tested in - `backend/test/ytdlp.test.js`. + which had rejected the correct official Art Track in every step. One exception: a **re-release year + next to a qualifier** ("… - 2020 Remaster") is dropped again — it sits on the release but never in + the YouTube title, so requiring it would reject the correct upload. A title that IS a year ("1999", + "Berlin 2020") keeps it. Unit-tested in `backend/test/ytdlp.test.js`. - **Size cap:** `--max-filesize 30M` on every yt-dlp call; Mittelweg steps also cap at 2× expected duration. Prevents saving a 28-min video (52 MB) when the wrong result slips through. - **Leading aesthetic characters:** artists often style their name with leading punctuation diff --git a/backend/lib/ytdlp.js b/backend/lib/ytdlp.js index 9ce376a..6a9a0b8 100644 --- a/backend/lib/ytdlp.js +++ b/backend/lib/ytdlp.js @@ -30,8 +30,15 @@ function buildTitleKeywords(title) { // longest-two rule threw them away: "700 Main Street" kept only Street+Main and happily matched // "777 Main Street" by a different artist. Numbers are therefore always required, on top of the // two longest words. - const numbers = words.filter(w => /^\d+$/.test(w)); - const wordsNoNum = words.filter(w => !/^\d+$/.test(w)); + // Ausnahme: die Jahreszahl einer Neuauflage ("… - 2020 Remaster") steht auf der Veroeffentlichung, + // aber nie im YouTube-Titel — als Pflicht-Keyword wuerde sie den richtigen Upload ablehnen. Nur + // wenn ein solches Qualifier-Wort daneben steht; ein Titel, der SELBST eine Jahreszahl ist + // ("1999", "Berlin 2020"), behaelt sie. + const RELEASE_QUALIFIER = /\b(remaster|remastered|version|edition|anniversary|mono|stereo)\b/i; + const isEditionYear = w => /^(19|20)\d{2}$/.test(w) && RELEASE_QUALIFIER.test(title || ''); + const isRequiredNum = w => /^\d+$/.test(w) && !isEditionYear(w); + const numbers = words.filter(isRequiredNum); + const wordsNoNum = words.filter(w => !isRequiredNum(w)); const top2 = wordsNoNum.sort((a, b) => b.length - a.length).slice(0, 2); // Uploaders abbreviate the same word the release spells out ("700 Main St" vs "700 Main Street"), // which rejected the official Art Track in every cascade step. Accept either spelling; \b keeps diff --git a/backend/test/ytdlp.test.js b/backend/test/ytdlp.test.js index 1d83b6c..223a05c 100644 --- a/backend/test/ytdlp.test.js +++ b/backend/test/ytdlp.test.js @@ -33,3 +33,15 @@ test('titles without numbers keep the previous two-longest-words behaviour', () assert.equal(accepts('Bohemian Rhapsody', 'Queen - Bohemian Rhapsody (Official Video)'), true); assert.equal(accepts('Bohemian Rhapsody', 'Queen - Another One Bites The Dust'), false); }); + +test('a remaster year is not required — YouTube titles never carry it', () => { + // "… - 2020 Remaster" steht auf der Veröffentlichung, der Upload heißt schlicht + // "Take Me Home, Country Roads". Vor dieser Ausnahme hätte die 2020 ihn abgelehnt. + assert.equal(accepts('Take Me Home, Country Roads - 2020 Remaster', + 'John Denver - Take Me Home, Country Roads'), true); +}); + +test('a year that IS the title stays required', () => { + assert.equal(accepts('1999', 'Prince - 1999 (Official Music Video)'), true); + assert.equal(accepts('1999', 'Prince - 1984 (Official Music Video)'), false); +});