From 8f14d013b33d2614be8a689d171b71d67d608283 Mon Sep 17 00:00:00 2001 From: Honey Date: Wed, 27 May 2026 15:15:45 +0200 Subject: [PATCH] fix: skip iTunes album/duration enrichment for Japanese Spotify tracks to prevent wrong-song downloads --- src/spotify.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/spotify.js b/src/spotify.js index f724ae8..1c36a50 100644 --- a/src/spotify.js +++ b/src/spotify.js @@ -287,17 +287,26 @@ async function _loadSpotifyTrackArtwork(tracks, listEl) { const results = await itunesSearch(`${t.trackName} ${firstArtist}`, 'musicTrack', 1); const match = results[0]; if (!match) return; - // Enrich track object so downloads get correct metadata + // Always safe to enrich: artwork, preview, explicit, iTunes artist name if (match.artworkUrl100) t.artworkUrl100 = match.artworkUrl100; - if (match.collectionName) t.collectionName = match.collectionName; - if (match.releaseDate) t.releaseDate = match.releaseDate; - if (match.trackNumber) t.trackNumber = match.trackNumber; if (match.trackExplicitness) t.trackExplicitness = match.trackExplicitness; if (match.previewUrl) t.previewUrl = match.previewUrl; - if (match.trackTimeMillis) t.durationMs = match.trackTimeMillis; // Store iTunes canonical name separately — keeps original Spotify/Japanese in artistName // so the UI shows the original and YTM search uses the original channel name. if (match.artistName) t.itunesArtistName = match.artistName; + // Only enrich album/duration if we're confident the iTunes match is the correct song. + // For Japanese titles we can't word-match, so we skip — the backend's lookupItunesTrackMeta + // handles it with better matching. For ASCII titles, require at least one shared word. + const JP_RE = /[ぁ-んァ-ン一-龯]/; + const isJapanese = JP_RE.test(t.trackName); + const _norm = s => new Set((s||'').toLowerCase().replace(/[^a-z0-9]/g,' ').split(/\s+/).filter(Boolean)); + const titleMatch = !isJapanese && [..._norm(t.trackName)].some(w => _norm(match.trackName).has(w)); + if (titleMatch) { + if (match.collectionName) t.collectionName = match.collectionName; + if (match.releaseDate) t.releaseDate = match.releaseDate; + if (match.trackNumber) t.trackNumber = match.trackNumber; + if (match.trackTimeMillis) t.durationMs = match.trackTimeMillis; + } if (window._spotifyResolved?.tracks?.[idx]) Object.assign(window._spotifyResolved.tracks[idx], t); const url = match.artworkUrl100 || match.artworkUrl60 || ''; if (url) _setArt(artEls[idx], url);