fix: resolve missing Radarr and Sonarr links on active downloads (fixes #59)

This commit is contained in:
2026-05-27 23:46:35 +01:00
parent a37874c553
commit 13f3d767c5
3 changed files with 138 additions and 2 deletions
+9 -1
View File
@@ -13,7 +13,7 @@ const { buildUserDownloads } = require('../services/DownloadBuilder');
const { onHistoryUpdate, offHistoryUpdate } = require('../utils/historyFetcher');
const arrRetrieverRegistry = require('../utils/arrRetrievers');
const { getOmbiInstances, getSonarrInstances, getRadarrInstances } = require('../utils/config');
const { extractRequestedUser, filterRequestsByUser, decorateRequestsWithArrLinks } = require('../utils/ombiHelpers');
const { extractRequestedUser, filterRequestsByUser, decorateRequestsWithArrLinks, decorateDownloadsWithArrLinks } = require('../utils/ombiHelpers');
const { canBlocklist } = require('../services/DownloadAssembler');
@@ -218,6 +218,10 @@ router.get('/user-downloads', requireAuth, async (req, res) => {
ombiBaseUrl
});
if (isAdmin) {
await decorateDownloadsWithArrLinks(userDownloads, isAdmin);
}
res.json({
user: user.name,
isAdmin,
@@ -513,6 +517,10 @@ router.get('/stream', requireAuth, async (req, res) => {
ombiBaseUrl
});
if (isAdmin) {
await decorateDownloadsWithArrLinks(userDownloads, isAdmin);
}
console.log(`[SSE] Sending ${userDownloads.length} downloads for ${user.name}`);
const downloadClients = downloadClientRegistry.getAllClients().map(c => ({
id: c.getInstanceId(),
+88 -1
View File
@@ -145,8 +145,95 @@ async function decorateRequestsWithArrLinks(requests, isAdmin) {
});
}
async function decorateDownloadsWithArrLinks(downloads, isAdmin) {
if (!isAdmin || !Array.isArray(downloads)) return;
const arrRetrieverRegistry = require('./arrRetrievers');
await arrRetrieverRegistry.initialize();
const sonarrRetrievers = arrRetrieverRegistry.getRetrieversByType('sonarr') || [];
const radarrRetrievers = arrRetrieverRegistry.getRetrieversByType('radarr') || [];
const [sonarrData, radarrData] = await Promise.all([
Promise.all(sonarrRetrievers.map(async r => {
try {
const response = await require('axios').get(`${r.url}/api/v3/series`, {
headers: { 'X-Api-Key': r.apiKey }
});
return { instance: r, series: response.data || [] };
} catch {
return { instance: r, series: [] };
}
})),
Promise.all(radarrRetrievers.map(async r => {
try {
const response = await require('axios').get(`${r.url}/api/v3/movie`, {
headers: { 'X-Api-Key': r.apiKey }
});
return { instance: r, movies: response.data || [] };
} catch {
return { instance: r, movies: [] };
}
}))
]);
downloads.forEach(dl => {
// Determine if it's TV (series) or Movie
const isTv = dl.type === 'series' || dl.arrType === 'sonarr';
if (isTv) {
// Look for a match in Sonarr instances
for (const instData of sonarrData) {
const match = instData.series.find(s => {
if (!s) return false;
// Match by database series ID if the instance matches
const instanceUrlMatch = dl.arrInstanceUrl === instData.instance.url;
if (instanceUrlMatch && dl.arrSeriesId != null && s.id === parseInt(dl.arrSeriesId, 10)) {
return true;
}
// Fallback to seriesName matching
if (dl.seriesName && s.title && dl.seriesName.toLowerCase() === s.title.toLowerCase()) {
return true;
}
return false;
});
if (match && match.titleSlug) {
dl.arrLink = `${instData.instance.url}/series/${match.titleSlug}`;
dl.arrType = 'sonarr';
break;
}
}
} else if (dl.type === 'movie' || dl.arrType === 'radarr') {
// Look for a match in Radarr instances
for (const instData of radarrData) {
const match = instData.movies.find(m => {
if (!m) return false;
// Match by database movie ID if instance matches
const instanceUrlMatch = dl.arrInstanceUrl === instData.instance.url;
if (instanceUrlMatch && dl.arrContentId != null && m.id === parseInt(dl.arrContentId, 10)) {
return true;
}
// Fallback to movieName matching
if (dl.movieName && m.title && dl.movieName.toLowerCase() === m.title.toLowerCase()) {
return true;
}
return false;
});
if (match && match.titleSlug) {
dl.arrLink = `${instData.instance.url}/movie/${match.titleSlug}`;
dl.arrType = 'radarr';
break;
}
}
}
});
}
module.exports = {
extractRequestedUser,
filterRequestsByUser,
decorateRequestsWithArrLinks
decorateRequestsWithArrLinks,
decorateDownloadsWithArrLinks
};