fix: iTunes artist match and MusicBrainz first-artist-only query

iTunes: split artist by [\s,;/] not just space so "VXLLAIN, iGRES"
yields first word "vxllain" (no trailing comma) and matches correctly.

MusicBrainz: extract first artist from the full credit string (split on
,;&•) and use `artistname` field — MB stores credits like "VXLLAIN feat.
iGRES & ENXK" which never matched the comma-joined full string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-23 22:00:58 +02:00
1 parent ae48ed4129
commit 17414ca888
2 files changed
+8 -4

No files matched your search

+5 -3
View File
@@ -95,11 +95,13 @@ async function lookupItunesTrackMeta(artist, title) {
res.on('end', () => { try { resolve(JSON.parse(d).results || []); } catch { reject(new Error('parse')); } });
}).on('error', reject);
});
const normT = normalizeTitle(title);
const normA = (artist || '').toLowerCase().trim();
const normT = normalizeTitle(title);
const normA = (artist || '').toLowerCase().trim();
// Split by space OR comma/semicolon/slash so "VXLLAIN, iGRES" → "vxllain" not "vxllain,"
const firstWord = s => (s || '').toLowerCase().split(/[\s,;/]/)[0];
const match = results.find(t =>
normalizeTitle(t.trackName) === normT &&
(t.artistName || '').toLowerCase().trim().split(' ')[0] === normA.split(' ')[0]
firstWord(t.artistName) === firstWord(normA)
);
if (!match) return {};
return {
+3 -1
View File
@@ -553,7 +553,9 @@ app.get('/api/musicbrainz/lookup', async (req, res) => {
const { artist, title } = req.query;
if (!artist || !title) return res.status(400).json({ error: 'artist and title required' });
try {
const query = `recording:"${title.replace(/"/g, '')}" AND artist:"${artist.replace(/"/g, '')}"`;
// Use only the first artist — MB won't match "VXLLAIN, iGRES, ENXK" against "VXLLAIN feat. iGRES & ENXK"
const firstArtist = artist.split(/[,;&•]/)[0].trim().replace(/"/g, '');
const query = `recording:"${title.replace(/"/g, '')}" AND artistname:"${firstArtist}"`;
const url = `https://musicbrainz.org/ws/2/recording/?query=${encodeURIComponent(query)}&fmt=json&limit=5`;
const r = await fetch(url, { headers: { 'User-Agent': 'NovaSonic/1.0 (me_honeyy@proton.me)' }, signal: AbortSignal.timeout(10000) });
if (!r.ok) return res.status(502).json({ error: `MusicBrainz ${r.status}` });