fix: use the US iTunes store everywhere for consistent artist naming

Search (web api.js) was JP-first, the download lookups were JP-first, and the Android
client was already US — so the same artist resolved inconsistently: sometimes kanji,
sometimes katakana, sometimes romaji, depending on which path and which store matched.

Switch everything to the US store:
- api.js itunesSearch → country=us (one fetch, matches the Android client)
- metadata.js lookupItunesTrackMeta → US only (drops the JP fetch: consistent names +
  halves the download's iTunes calls, which also eases the rate limit)
- searchItunesAlbumTracks → country=us
- remove the JP-katakana guards in the album/artist download paths (redundant now, and
  they wrongly romanized genuine Japanese artists like 羽岡佳 → "Kei Haneoka")

Titles still come from the source, so a Japanese title the user picked stays Japanese;
only iTunes-derived fields (album_artist, genre, year, artwork) follow the US store.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-07-29 10:37:07 +02:00
1 parent d98978a6c7
commit 9c8b4775ea
5 files changed
+23 -32

No files matched your search

+2 -9
View File
@@ -628,11 +628,7 @@ app.post('/api/download', async (req, res) => {
// over the request's `artist`, which can be a single track's performer — e.g. the lead single
// "TAKEDOWN" is by TWICE, so `artist` arrives as "TWICE" and would tag the whole soundtrack's
// album_artist as TWICE. Keeps album_artist consistent so Navidrome doesn't split the album.
let albumArtistName = tracks.map(t => t.collectionArtistName).find(Boolean) || artist;
// The JP store localizes Western artists to katakana ("DJスネイク"). If iTunes' album artist is
// Japanese but the request artist isn't, keep the request's English name (tag + folder).
const JP_RE = /[぀-ヿ㐀-䶿一-鿿]/;
if (albumArtistName && artist && JP_RE.test(albumArtistName) && !JP_RE.test(artist)) albumArtistName = artist;
const albumArtistName = tracks.map(t => t.collectionArtistName).find(Boolean) || artist;
if (albumArtistName !== artist) log(jobId, `👥 Album-Künstler: "${albumArtistName}" (iTunes)`);
const { done: dlDone, skipped: dlSkipped } = await downloadAlbumTracks({ jobId, artist: albumArtistName, albumTitle: album || title, tracks, artworkUrl });
const allSkipped = dlSkipped === tracks.length;
@@ -660,10 +656,7 @@ app.post('/api/download', async (req, res) => {
if (tracks.length) {
// Same as the album path: album_artist from iTunes' album-level artist, so a collaboration
// or soundtrack in the artist's discography isn't tagged with the searched artist.
let albArtist = tracks.map(t => t.collectionArtistName).find(Boolean) || alb.artistName || artist;
// Don't let the JP store's katakana album-artist override a non-Japanese searched artist.
const JP_RE = /[぀-ヿ㐀-䶿一-鿿]/;
if (albArtist && artist && JP_RE.test(albArtist) && !JP_RE.test(artist)) albArtist = artist;
const albArtist = tracks.map(t => t.collectionArtistName).find(Boolean) || alb.artistName || artist;
await downloadAlbumTracks({ jobId, artist: albArtist, albumTitle: alb.collectionName, tracks, artworkUrl: alb.artworkUrl100 });
}
done++;