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:
1 parent
86d3999628
commit
4cbfa35655
1 file changed
+14
-7
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user