From d326e0883477a7dbf453ab28a3fc619f759a8604 Mon Sep 17 00:00:00 2001 From: MasutaYunikon Date: Fri, 29 May 2026 02:34:26 +0200 Subject: [PATCH] fix(synology): filtrage par savePath et retour au GET pour add() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - list(): filtre les tâches par detail.destination === savePath (Synology n'ayant pas de labels/catégories, c'est le seul moyen de n'afficher que les torrents FanKarr) ; sans savePath configuré, tous les torrents sont retournés comme avant - add(): retour à la requête GET (comme l'ancien driver) — le POST avec destination dans le body ne fonctionnait pas correctement sur certains DSM, alors que les paramètres en query string fonctionnaient --- server/torrent-clients/synology-ds.ts | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/server/torrent-clients/synology-ds.ts b/server/torrent-clients/synology-ds.ts index 4d99ba2..d393f40 100644 --- a/server/torrent-clients/synology-ds.ts +++ b/server/torrent-clients/synology-ds.ts @@ -172,7 +172,17 @@ const DS: TorrentClientDriver = { const tasks: any[] = data?.tasks ?? [] - return tasks.map(t => { + // Filtrage par dossier cible — Synology n'a pas de système de labels/catégories. + // Si savePath est configuré, on ne garde que les tâches dont la destination correspond. + const normalizedSavePath = String(config.savePath ?? '').replace(/\/+$/, '').toLowerCase() + const filtered = normalizedSavePath + ? tasks.filter(t => { + const dest = String(t.additional?.detail?.destination ?? '').replace(/\/+$/, '').toLowerCase() + return dest === normalizedSavePath || dest.startsWith(normalizedSavePath + '/') + }) + : tasks + + return filtered.map(t => { const transfer = t.additional?.transfer ?? {} const detail = t.additional?.detail ?? {} const fileList: any[] = t.additional?.file ?? [] @@ -235,34 +245,26 @@ const DS: TorrentClientDriver = { const sid = await dsLogin(config) - const makeBody = (withDestination: boolean) => { - const body = new URLSearchParams({ + const doAdd = async (withDestination: boolean) => { + const params = new URLSearchParams({ api : 'SYNO.DownloadStation.Task', version: '1', method : 'create', _sid : sid, uri : url, }) - if (withDestination && config.savePath) body.append('destination', String(config.savePath)) - return body - } - - const doRequest = async (body: URLSearchParams) => { - const res = await fetch(`${config.url}/webapi/DownloadStation/task.cgi`, { - method : 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body : body.toString(), - }) + if (withDestination && config.savePath) params.append('destination', String(config.savePath)) + const res = await fetch(`${config.url}/webapi/DownloadStation/task.cgi?${params}`) if (!res.ok) throw new Error(`HTTP ${res.status}`) return res.json() } - let data = await doRequest(makeBody(true)) + let data = await doAdd(true) - // Code 403 = destination inexistante sur le NAS → réessai sans destination + // Code 403 = dossier cible introuvable sur le NAS → réessai sans destination if (!data.success && data.error?.code === 403 && config.savePath) { logger.warn('synology-ds', `Dossier cible "${config.savePath}" introuvable (code 403) — ajout sans destination`) - data = await doRequest(makeBody(false)) + data = await doAdd(false) } if (!data.success) throw new Error(`Ajout échoué : ${JSON.stringify(data.error)}`)