From 77b0e6c11945c5339a3b4f504e722e2cca8dc04b Mon Sep 17 00:00:00 2001 From: J0Z1L Date: Sat, 28 Feb 2026 00:17:55 +0100 Subject: [PATCH] Improve Lidarr album matching with artist refresh and fallback lookups --- server.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/server.js b/server.js index 0eed762..00d6cb2 100644 --- a/server.js +++ b/server.js @@ -167,6 +167,10 @@ function mapSelectedTracks(lidarrTracks, selectedTrackNames) { }); } +function delay(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + async function fetchTrackFiles(albumId) { const endpoints = ['/api/v1/trackfile', '/api/v1/trackFile']; @@ -297,6 +301,60 @@ async function ensureArtist(artistName) { return lidarrRequest('post', '/api/v1/artist', payload); } +async function refreshArtistInLidarr(artistId) { + const payloads = [ + { name: 'RefreshArtist', artistId }, + { name: 'RefreshArtist', artistIds: [artistId] } + ]; + + for (const payload of payloads) { + try { + await lidarrRequest('post', '/api/v1/command', payload); + return true; + } catch (_err) { + // Try next payload shape. + } + } + return false; +} + +async function fetchArtistAlbums(artistId) { + try { + const albums = await lidarrRequest('get', '/api/v1/album', undefined, { artistId }); + return Array.isArray(albums) ? albums : []; + } catch (_err) { + return []; + } +} + +async function findLidarrAlbum(artist, albumName, fallbackArtistName) { + const artistName = artist?.artistName || fallbackArtistName; + + // 1) Existing albums already known to Lidarr for this artist. + const existing = await fetchArtistAlbums(artist.id); + let candidate = pickAlbumCandidate(existing, albumName, artistName); + if (candidate && candidate.id) return candidate; + + // 2) Force artist refresh and retry a few times. + await refreshArtistInLidarr(artist.id); + for (let i = 0; i < 4; i += 1) { + await delay(1500); + const refreshed = await fetchArtistAlbums(artist.id); + candidate = pickAlbumCandidate(refreshed, albumName, artistName); + if (candidate && candidate.id) return candidate; + } + + // 3) Fallback lookup terms. + const terms = [`${artistName} ${albumName}`, albumName]; + for (const term of terms) { + const lookup = await lidarrRequest('get', '/api/v1/album/lookup', undefined, { term }); + candidate = pickAlbumCandidate(lookup, albumName, artistName); + if (candidate && candidate.id) return candidate; + } + + return null; +} + app.get('/api/health', (_req, res) => { res.json({ ok: true, @@ -416,16 +474,11 @@ app.post('/api/lidarr/send-album', async (req, res) => { } try { - await ensureArtist(artistName); - - const lookup = await lidarrRequest('get', '/api/v1/album/lookup', undefined, { - term: `${artistName} ${albumName}` - }); - - const album = pickAlbumCandidate(lookup, albumName, artistName); + const artist = await ensureArtist(artistName); + const album = await findLidarrAlbum(artist, albumName, artistName); if (!album || !album.id) { return res.status(404).json({ - error: 'Album nicht in Lidarr-lookup gefunden. Pruefe Artist/Album oder Metadaten.' + error: 'Album nicht in Lidarr gefunden. Bitte Artist in Lidarr aktualisieren und erneut versuchen.' }); }