fix(backend): normalize iTunes lookup across all download paths

- Track path: always fetch iTunes when durationMs/trackNum missing (not just genre)
- Both paths: strip release suffixes from title before iTunes lookup
- Log "Album:" instead of "Album aus Spotify:" (also fires for iTunes global search)
- Log duration when fetched from iTunes so it's visible in job log

Ensures all importers have consistent yt-dlp search filters (duration filter
now always runs when iTunes finds the track).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-19 10:00:32 +02:00
1 parent 86d3999628
commit 4cbfa35655
1 file changed
+14 -7
+14 -7
View File
@@ -576,15 +576,19 @@ app.post('/api/download', async (req, res) => {
if (extra.album) log(jobId, `📋 Album: "${extra.album}" (${extra.year || '?'})`);
meta = { ...meta, ...extra, artworkUrl: spArt || extra.artworkUrl || '', genre: meta.genre || extra.genre || undefined };
} else {
log(jobId, `📋 Album aus Spotify: "${meta.album}"`);
// Spotify enrichment has no genre, totalTracks, or disc info — fetch from iTunes
if (!meta.genre || !meta.totalTracks) {
const genreMeta = await lookupItunesTrackMeta(searchArtist, title).catch(() => ({}));
log(jobId, `📋 Album: "${meta.album}"`);
// Always fetch iTunes when any field is missing — durationMs is required for the yt-dlp
// duration filter; without it any unrelated video that matches the title text gets downloaded.
if (!meta.genre || !meta.totalTracks || !meta.durationMs || !meta.trackNum) {
// Strip release-type suffixes before iTunes lookup so "recognize - Single" → "recognize"
const RELEASE_SUFFIX_RE = /\s*[-–]\s*(?:(?:official\s+)?(?:music\s+)?(?:single|ep|lp|album|ost|soundtrack|remaster(?:ed)?|deluxe(?:\s+edition)?|bonus\s+tracks?|b-?sides?|version|edit)\b.*|(?:20|19)\d{2})\s*$/i;
const itunesTitle = title.replace(RELEASE_SUFFIX_RE, '').trim() || title;
const genreMeta = await lookupItunesTrackMeta(searchArtist, itunesTitle).catch(() => ({}));
if (!meta.genre && genreMeta.genre) { meta.genre = genreMeta.genre; log(jobId, `📋 Genre: "${genreMeta.genre}"`); }
if (!meta.totalTracks && genreMeta.totalTracks) { meta.totalTracks = genreMeta.totalTracks; }
if (!meta.discNum && genreMeta.discNum) { meta.discNum = genreMeta.discNum; }
if (!meta.discTotal && genreMeta.discTotal) { meta.discTotal = genreMeta.discTotal; }
if (!meta.durationMs && genreMeta.durationMs) { meta.durationMs = genreMeta.durationMs; }
if (!meta.durationMs && genreMeta.durationMs) { meta.durationMs = genreMeta.durationMs; log(jobId, `📋 Duration: ${Math.round(genreMeta.durationMs/1000)}s`); }
if (!meta.trackNum && genreMeta.trackNum) { meta.trackNum = genreMeta.trackNum; }
}
}
@@ -651,6 +655,9 @@ app.post('/api/download', async (req, res) => {
const batchResults = await Promise.allSettled(batch.map(async track => {
const trackTitle = track.trackName || '';
const trackArtist = track.artistName || artist || '';
// Strip release-type suffixes before iTunes lookup ("Song - Single" → "Song")
const RELEASE_SUFFIX_RE = /\s*[-–]\s*(?:(?:official\s+)?(?:music\s+)?(?:single|ep|lp|album|ost|soundtrack|remaster(?:ed)?|deluxe(?:\s+edition)?|bonus\s+tracks?|b-?sides?|version|edit)\b.*|(?:20|19)\d{2})\s*$/i;
const itunesTitle = trackTitle.replace(RELEASE_SUFFIX_RE, '').trim() || trackTitle;
// If the frontend already enriched this track with iTunes data (collectionName +
// trackNumber + durationMs all present), skip the re-lookup to avoid a different
// iTunes result overriding the already-correct enriched metadata.
@@ -660,7 +667,7 @@ app.post('/api/download', async (req, res) => {
if (alreadyEnriched) {
log(jobId, `📋 Frontend-Metadaten: "${trackArtist} – ${trackTitle}" (${track.collectionName})`);
// Spotify enrichment copies album/trackNum/duration but not genre/totalTracks/disc — fetch those
const genreMeta = await lookupItunesTrackMeta(searchArtist, trackTitle).catch(() => ({}));
const genreMeta = await lookupItunesTrackMeta(searchArtist, itunesTitle).catch(() => ({}));
itunes = {
genre: genreMeta.genre,
totalTracks: genreMeta.totalTracks,
@@ -669,7 +676,7 @@ app.post('/api/download', async (req, res) => {
};
} else {
log(jobId, `📋 iTunes: "${trackArtist} – ${trackTitle}"`);
itunes = await lookupItunesTrackMeta(searchArtist, trackTitle);
itunes = await lookupItunesTrackMeta(searchArtist, itunesTitle);
}
// Prefer iTunes-resolved name (from server lookup or frontend enrichment) for sort tags / folders.
// trackArtist stays as rawArtist for main tags and YTM search.