From cb054cbac70cbce2b8552a86d1bc3dfdcd28c44a Mon Sep 17 00:00:00 2001 From: sascha Date: Mon, 14 Sep 2026 09:15:04 +0200 Subject: [PATCH] Fix Sonarr path boundary and exact episode parsing --- .../scripts/Sonarr_-_Trigger_Manual_Import.js | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/fileflows/scripts/Sonarr_-_Trigger_Manual_Import.js b/fileflows/scripts/Sonarr_-_Trigger_Manual_Import.js index 48dc729..1adfe02 100644 --- a/fileflows/scripts/Sonarr_-_Trigger_Manual_Import.js +++ b/fileflows/scripts/Sonarr_-_Trigger_Manual_Import.js @@ -2,7 +2,7 @@ * @name Sonarr - Trigger Manual Import * @description Safely trigger Sonarr ManualImport for exactly one processed episode file. * @author FileFlows + Sascha - * @revision 10 + * @revision 11 * @output Import erfolgreich * @output Fehler * @param {string} URL Sonarr root URL and port @@ -31,13 +31,16 @@ function Script(URL, ApiKey, ImportPath, UseUnmappedPath, MoveMode, TimeOut) { } // ── SKIP-GUARD: Nur API-Call machen, wenn der aktuelle ImportPath - // mit dem konfigurierten Pfad uebereinstimmt. Sonst sofort OK. - // Das verhindert 3 unnoetige API-Calls pro Datei (4 Arr-Instanzen). - if (ImportPath && ImportPath.indexOf(URL) === -1) { - if (currentFile && ImportPath && currentFile.indexOf(ImportPath) === -1) { - Logger.ILog(`Skip: current file '${currentFile}' not under ImportPath '${ImportPath}' - not responsible`); - return 1; - } + // mit dem konfigurierten Pfad als vollständiges Pfadsegment + // übereinstimmt. Ein nacktes Prefix würde z. B. /serien4k + // fälschlich dem FHD-Root /serien zuordnen. + const normalizedCurrentPath = normalizeImportPath(exactImportPath); + const normalizedScopeRoot = normalizeImportPath(ImportPath); + const isInScope = normalizedCurrentPath === normalizedScopeRoot + || normalizedCurrentPath.startsWith(normalizedScopeRoot + '/'); + if (!isInScope) { + Logger.ILog(`Skip: current file '${currentFile}' not under ImportPath '${ImportPath}' - not responsible`); + return 1; } const sonarr = new Sonarr(URL, ApiKey); @@ -58,7 +61,18 @@ function Script(URL, ApiKey, ImportPath, UseUnmappedPath, MoveMode, TimeOut) { ?? findEpisodeFromGrabHistory(pattern, sonarr); if (trackedEpisode) break; } - if (!trackedEpisode) trackedEpisode = parseSeries(searchPatterns[0] || '', sonarr); + if (!trackedEpisode) { + // Ein Staffelpaket-Ordner ist absichtlich mehrdeutig. Zuerst + // den exakten Episoden-Dateinamen parsen, danach erst den + // Ordnernamen als letzten Fallback versuchen. + const parsePatterns = [filePattern, folderPattern] + .filter(Boolean) + .filter((value, index, values) => values.indexOf(value) === index); + for (const pattern of parsePatterns) { + trackedEpisode = parseSeries(pattern, sonarr); + if (trackedEpisode?.id && trackedEpisode?.episodeIds?.length) break; + } + } seriesId = trackedEpisode?.id ?? null; episodeIds = trackedEpisode?.episodeIds ?? null; }