fix(matching): Match SAB to Sonarr by downloadId first
Sonarr tracks the exact SAB download ID (nzo_id). Now tries to match by downloadId first, then falls back to title matching. Also adds debug to show if matches are via downloadId vs title, and logs downloadIds in history to verify the link exists.
This commit is contained in:
+45
-18
@@ -1016,21 +1016,38 @@ router.get('/stream', requireAuth, async (req, res) => {
|
|||||||
// Normalize SAB name (dots to spaces) for better matching
|
// Normalize SAB name (dots to spaces) for better matching
|
||||||
const nzbNameNormalized = nzbNameLower.replace(/\./g, ' ');
|
const nzbNameNormalized = nzbNameLower.replace(/\./g, ' ');
|
||||||
|
|
||||||
// Check Sonarr/Radarr QUEUE (active downloads)
|
// Try to match by downloadId first (most reliable)
|
||||||
let sonarrMatch = sonarrQueue.data.records.find(r => {
|
const sabDownloadId = slot.nzo_id || slot.id;
|
||||||
const rTitle = (r.title || r.sourceTitle || '').toLowerCase();
|
let sonarrMatch = sabDownloadId ? sonarrQueue.data.records.find(r => r.downloadId === sabDownloadId) : null;
|
||||||
return rTitle && (
|
let radarrMatch = sabDownloadId ? radarrQueue.data.records.find(r => r.downloadId === sabDownloadId) : null;
|
||||||
rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle) ||
|
|
||||||
rTitle.includes(nzbNameNormalized) || nzbNameNormalized.includes(rTitle)
|
// Also check HISTORY by downloadId
|
||||||
);
|
if (!sonarrMatch && sabDownloadId) {
|
||||||
});
|
sonarrMatch = sonarrHistory.data.records.find(r => r.downloadId === sabDownloadId);
|
||||||
let radarrMatch = radarrQueue.data.records.find(r => {
|
}
|
||||||
const rTitle = (r.title || r.sourceTitle || '').toLowerCase();
|
if (!radarrMatch && sabDownloadId) {
|
||||||
return rTitle && (
|
radarrMatch = radarrHistory.data.records.find(r => r.downloadId === sabDownloadId);
|
||||||
rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle) ||
|
}
|
||||||
rTitle.includes(nzbNameNormalized) || nzbNameNormalized.includes(rTitle)
|
|
||||||
);
|
// Fallback: Check by title matching
|
||||||
});
|
if (!sonarrMatch) {
|
||||||
|
sonarrMatch = sonarrQueue.data.records.find(r => {
|
||||||
|
const rTitle = (r.title || r.sourceTitle || '').toLowerCase();
|
||||||
|
return rTitle && (
|
||||||
|
rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle) ||
|
||||||
|
rTitle.includes(nzbNameNormalized) || nzbNameNormalized.includes(rTitle)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!radarrMatch) {
|
||||||
|
radarrMatch = radarrQueue.data.records.find(r => {
|
||||||
|
const rTitle = (r.title || r.sourceTitle || '').toLowerCase();
|
||||||
|
return rTitle && (
|
||||||
|
rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle) ||
|
||||||
|
rTitle.includes(nzbNameNormalized) || nzbNameNormalized.includes(rTitle)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Also check HISTORY (completed downloads) if no queue match
|
// Also check HISTORY (completed downloads) if no queue match
|
||||||
if (!sonarrMatch) {
|
if (!sonarrMatch) {
|
||||||
@@ -1055,19 +1072,29 @@ router.get('/stream', requireAuth, async (req, res) => {
|
|||||||
if (sabSlotsChecked <= 5) {
|
if (sabSlotsChecked <= 5) {
|
||||||
if (sonarrMatch) {
|
if (sonarrMatch) {
|
||||||
const source = sonarrQueue.data.records.includes(sonarrMatch) ? 'queue' : 'history';
|
const source = sonarrQueue.data.records.includes(sonarrMatch) ? 'queue' : 'history';
|
||||||
console.log(`[SSE] ✓ Sonarr ${source} match: SAB:"${nzbNameLower.substring(0, 50)}" → Sonarr:"${(sonarrMatch.title || sonarrMatch.sourceTitle || '').substring(0, 50)}"`);
|
const matchType = (sonarrMatch.downloadId === sabDownloadId) ? 'downloadId' : 'title';
|
||||||
|
console.log(`[SSE] ✓ Sonarr ${source} ${matchType} match: SAB:"${nzbNameLower.substring(0, 40)}" → Sonarr:"${(sonarrMatch.title || sonarrMatch.sourceTitle || '').substring(0, 40)}"`);
|
||||||
} else if (radarrMatch) {
|
} else if (radarrMatch) {
|
||||||
const source = radarrQueue.data.records.includes(radarrMatch) ? 'queue' : 'history';
|
const source = radarrQueue.data.records.includes(radarrMatch) ? 'queue' : 'history';
|
||||||
console.log(`[SSE] ✓ Radarr ${source} match: SAB:"${nzbNameLower.substring(0, 50)}" → Radarr:"${(radarrMatch.title || radarrMatch.sourceTitle || '').substring(0, 50)}"`);
|
const matchType = (radarrMatch.downloadId === sabDownloadId) ? 'downloadId' : 'title';
|
||||||
|
console.log(`[SSE] ✓ Radarr ${source} ${matchType} match: SAB:"${nzbNameLower.substring(0, 40)}" → Radarr:"${(radarrMatch.title || radarrMatch.sourceTitle || '').substring(0, 40)}"`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`[SSE] ✗ No match for SAB: "${nzbNameLower.substring(0, 60)}"`);
|
console.log(`[SSE] ✗ No match for SAB: "${nzbNameLower.substring(0, 60)}"`);
|
||||||
// Show counts
|
// Show counts
|
||||||
console.log(`[SSE] Queue: ${sonarrQueue.data.records.length}, History: ${sonarrHistory.data.records.length}`);
|
console.log(`[SSE] Queue: ${sonarrQueue.data.records.length}, History: ${sonarrHistory.data.records.length}`);
|
||||||
// Show history titles if there are any
|
// Show history titles if there are any
|
||||||
if (sonarrHistory.data.records.length > 0) {
|
if (sonarrHistory.data.records.length > 0) {
|
||||||
const histTitles = sonarrHistory.data.records.slice(0, 3).map(r => (r.title || r.sourceTitle || 'NO_TITLE').substring(0, 40));
|
const histTitles = sonarrHistory.data.records.slice(0, 3).map(r => {
|
||||||
|
const title = (r.title || r.sourceTitle || 'NO_TITLE').substring(0, 35);
|
||||||
|
const dlId = r.downloadId ? r.downloadId.substring(0, 15) : 'no-dl-id';
|
||||||
|
return `${title}[${dlId}]`;
|
||||||
|
});
|
||||||
console.log(`[SSE] History titles: ${histTitles.join(' | ')}`);
|
console.log(`[SSE] History titles: ${histTitles.join(' | ')}`);
|
||||||
}
|
}
|
||||||
|
// Also check if SAB slots have nzo_id we could use
|
||||||
|
if (slot.nzo_id) {
|
||||||
|
console.log(`[SSE] SAB nzo_id: ${slot.nzo_id.substring(0, 20)}...`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sonarrMatch && sonarrMatch.seriesId) {
|
if (sonarrMatch && sonarrMatch.seriesId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user