fix(matching): Normalize dots to spaces for SAB/Sonarr matching
Some checks failed
Build and Push Docker Image / build (push) Successful in 13s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 46s
CI / Security audit (push) Has been cancelled
CI / Tests & coverage (push) Has been cancelled

SAB filenames use dots (dora.the.explorer.s02e08) but Sonarr titles
use spaces (Dora the Explorer - S02E08). Now tries matching with
both formats to improve match rate.

Also logs actual Sonarr titles when no match found for debugging.
This commit is contained in:
2026-05-19 22:02:55 +01:00
parent 42c3eebf18
commit 9d0e31ec9a

View File

@@ -1013,13 +1013,22 @@ router.get('/stream', requireAuth, async (req, res) => {
const slotState = getSlotStatusAndSpeed(slot); const slotState = getSlotStatusAndSpeed(slot);
const nzbNameLower = nzbName.toLowerCase(); const nzbNameLower = nzbName.toLowerCase();
// Normalize SAB name (dots to spaces) for better matching
const nzbNameNormalized = nzbNameLower.replace(/\./g, ' ');
const sonarrMatch = sonarrQueue.data.records.find(r => { const sonarrMatch = sonarrQueue.data.records.find(r => {
const rTitle = (r.title || r.sourceTitle || '').toLowerCase(); const rTitle = (r.title || r.sourceTitle || '').toLowerCase();
return rTitle && (rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle)); return rTitle && (
rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle) ||
rTitle.includes(nzbNameNormalized) || nzbNameNormalized.includes(rTitle)
);
}); });
const radarrMatch = radarrQueue.data.records.find(r => { const radarrMatch = radarrQueue.data.records.find(r => {
const rTitle = (r.title || r.sourceTitle || '').toLowerCase(); const rTitle = (r.title || r.sourceTitle || '').toLowerCase();
return rTitle && (rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle)); return rTitle && (
rTitle.includes(nzbNameLower) || nzbNameLower.includes(rTitle) ||
rTitle.includes(nzbNameNormalized) || nzbNameNormalized.includes(rTitle)
);
}); });
// Debug first 5 items - show matches and non-matches // Debug first 5 items - show matches and non-matches
if (sabSlotsChecked <= 5) { if (sabSlotsChecked <= 5) {
@@ -1029,7 +1038,9 @@ router.get('/stream', requireAuth, async (req, res) => {
console.log(`[SSE] ✓ Radarr match: SAB:"${nzbNameLower.substring(0, 50)}" → Radarr:"${(radarrMatch.title || radarrMatch.sourceTitle || '').substring(0, 50)}"`); console.log(`[SSE] ✓ Radarr match: SAB:"${nzbNameLower.substring(0, 50)}" → Radarr:"${(radarrMatch.title || radarrMatch.sourceTitle || '').substring(0, 50)}"`);
} else { } else {
console.log(`[SSE] ✗ No match for SAB: "${nzbNameLower.substring(0, 60)}"`); console.log(`[SSE] ✗ No match for SAB: "${nzbNameLower.substring(0, 60)}"`);
console.log(`[SSE] Sonarr queue has ${sonarrQueue.data.records.length} items`); // Show actual Sonarr titles to debug matching
const sonarrTitles = sonarrQueue.data.records.slice(0, 5).map(r => (r.title || r.sourceTitle || 'NO_TITLE').substring(0, 50));
console.log(`[SSE] Sonarr titles: ${sonarrTitles.join(' | ')}`);
} }
} }
if (sonarrMatch && sonarrMatch.seriesId) { if (sonarrMatch && sonarrMatch.seriesId) {