fix(transmission): map status 7 to Checking, implement control methods (closes #63)
Docs Check / Markdown lint (push) Failing after 1m14s
Build and Push Docker Image / build (push) Successful in 1m40s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m54s
CI / Security audit (push) Successful in 2m16s
CI / Swagger Validation & Coverage (push) Successful in 2m42s
Docs Check / Mermaid diagram parse check (push) Successful in 2m43s
CI / Tests & coverage (push) Successful in 2m55s

This commit is contained in:
2026-05-28 16:01:33 +01:00
parent bd7a9c7951
commit 3d49c926dc
3 changed files with 86 additions and 4 deletions
+44 -3
View File
@@ -113,7 +113,11 @@ class TransmissionClient extends DownloadClient {
4: 'Downloading', // TORRENT_DOWNLOAD
5: 'Queued', // TORRENT_SEED_WAIT
6: 'Seeding', // TORRENT_SEED
7: 'Unknown' // TORRENT_IS_CHECKING (alias for 2)
// Status code 7 is undocumented in the Transmission RPC spec (which
// formally defines only 06). The legacy alias "TORRENT_IS_CHECKING"
// (a duplicate of code 2) is the best-effort interpretation; map it to
// `Checking` so it is rendered usefully rather than as `Unknown`.
7: 'Checking' // TORRENT_IS_CHECKING (undocumented; treated as code 2)
};
const status = statusMap[torrent.status] || 'Unknown';
@@ -160,8 +164,12 @@ class TransmissionClient extends DownloadClient {
}
extractArrInfo(filename) {
// Similar to SABnzbdClient, try to extract Sonarr/Radarr info
// arrQueueId cannot be extracted from filename alone; *arr exposes that
// identifier only via its queue API. The reliable cross-client matching
// path is hash-based and lives in `DownloadMatcher.matchTorrents()` (see
// Issue #65), which keys on `torrent.hashString` for Transmission.
// This heuristic remains only to provide a coarse `type` hint.
// Look for patterns like "Series Name - S01E02 - Episode Title"
const seriesMatch = filename.match(/[-\s]S(\d{2})E(\d{2})/i);
if (seriesMatch) {
@@ -176,6 +184,39 @@ class TransmissionClient extends DownloadClient {
return {};
}
/**
* Start (resume) one or more torrents. `id` is the Transmission internal
* numeric id or a hashString; the RPC accepts either.
* @param {number|string|Array<number|string>} id
*/
async startTorrent(id) {
const ids = Array.isArray(id) ? id : [id];
await this.makeRequest('torrent-start', { ids });
logToFile(`[Transmission:${this.name}] Started torrent(s): ${ids.join(', ')}`);
}
/**
* Stop (pause) one or more torrents.
* @param {number|string|Array<number|string>} id
*/
async stopTorrent(id) {
const ids = Array.isArray(id) ? id : [id];
await this.makeRequest('torrent-stop', { ids });
logToFile(`[Transmission:${this.name}] Stopped torrent(s): ${ids.join(', ')}`);
}
/**
* Remove one or more torrents. When `deleteData` is true the local files
* are also deleted from disk (Transmission's `delete-local-data`).
* @param {number|string|Array<number|string>} id
* @param {boolean} [deleteData=false]
*/
async removeTorrent(id, deleteData = false) {
const ids = Array.isArray(id) ? id : [id];
await this.makeRequest('torrent-remove', { ids, 'delete-local-data': !!deleteData });
logToFile(`[Transmission:${this.name}] Removed torrent(s): ${ids.join(', ')} (deleteData=${!!deleteData})`);
}
}
module.exports = TransmissionClient;