mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-09-24 13:40:21 +01:00
Feature: rTorrent client support (#463)
This adds in rtorrent for https://github.com/calibrain/shelfmark/issues/420 The one weird thing I noticed is that the download path needs to be the same for both (that's not how I typically set it up) But it definitely adds to rtorrent and gives progress. **rTorrent client integration:** * Added a new `RTorrentClient` class in `shelfmark/release_sources/prowlarr/clients/rtorrent.py` that implements the download client interface for rTorrent using XML-RPC, supporting adding, removing, and querying torrent status. * Registered the rTorrent client in the client registry in `shelfmark/release_sources/prowlarr/clients/__init__.py`. **Settings and configuration:** * Extended the Prowlarr client settings UI and backend (`shelfmark/release_sources/prowlarr/settings.py`) to add rTorrent as a selectable client, provide rTorrent-specific configuration fields (URL, username, password, label, download directory), and implement a connection test action. [[1]](diffhunk://#diff-052272b85804cb61162870f262cc7544ef321596ff3ebf08117a6c25afaa3ec5R390) [[2]](diffhunk://#diff-052272b85804cb61162870f262cc7544ef321596ff3ebf08117a6c25afaa3ec5R539-R582) [[3]](diffhunk://#diff-052272b85804cb61162870f262cc7544ef321596ff3ebf08117a6c25afaa3ec5R198-R225) **Test environment and scripts:** * Updated `docker-compose.test-clients.yml` to add an rTorrent service for local testing, including configuration, ports, and documentation updates. [[1]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R17-L19) [[2]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R39) [[3]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R66) [[4]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R164-R181) * Enhanced `scripts/test_clients.py` to include rTorrent in the test suite, with logic for connecting, adding, and removing torrents via XML-RPC. [[1]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR26) [[2]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR57) [[3]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR88-R90) [[4]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR395-R468) [[5]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR492) Closes https://github.com/calibrain/shelfmark/issues/420
This commit is contained in:
@@ -23,6 +23,7 @@ Web UIs:
|
||||
- Deluge: http://localhost:8112
|
||||
- NZBGet: http://localhost:6789
|
||||
- SABnzbd: http://localhost:8085
|
||||
- rTorrent: http://localhost:8000 (web ui http://localhost:8089 via ruTorrent)
|
||||
|
||||
Prerequisites (for running this script locally):
|
||||
pip install requests transmission-rpc deluge-client qbittorrent-api
|
||||
@@ -53,6 +54,7 @@ First-Time Setup:
|
||||
|
||||
import sys
|
||||
import time
|
||||
from xmlrpc import client
|
||||
|
||||
# Test configuration - matches docker-compose.test-clients.yml
|
||||
CONFIG = {
|
||||
@@ -83,6 +85,9 @@ CONFIG = {
|
||||
"username": "admin",
|
||||
"password": "admin",
|
||||
},
|
||||
"rtorrent": {
|
||||
"url": "http://localhost:8000/RPC2",
|
||||
},
|
||||
}
|
||||
|
||||
# Test magnet link (Ubuntu ISO - legal, small metadata)
|
||||
@@ -387,6 +392,80 @@ def test_deluge():
|
||||
print(" 3. Or access Web UI at http://localhost:8112 (password: deluge)")
|
||||
return False
|
||||
|
||||
def test_rtorrent():
|
||||
"""Test rTorrent connection."""
|
||||
print("\n" + "=" * 50)
|
||||
print("Testing rTorrent")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
import xmlrpc.client
|
||||
|
||||
url = "http://localhost:8000/RPC2"
|
||||
client = xmlrpc.client.ServerProxy(url)
|
||||
|
||||
# Test connection
|
||||
version = client.system.library_version()
|
||||
print(f" Connected to rTorrent {version}")
|
||||
|
||||
# Get torrent list
|
||||
torrents = client.download_list()
|
||||
print(f" Active torrents: {len(torrents)}")
|
||||
|
||||
# Test adding a torrent (then remove it)
|
||||
print(" Testing add/remove torrent...")
|
||||
|
||||
label = "automated"
|
||||
|
||||
commands = []
|
||||
if label:
|
||||
commands.append(f"d.custom1.set={label}")
|
||||
|
||||
download_dir = "/downloads"
|
||||
if download_dir:
|
||||
commands.append(f"d.directory_base.set={download_dir}")
|
||||
|
||||
# rtorrent is weird in that it doesn't return the torrent ID/hash on add
|
||||
client.load.start("", TEST_MAGNET, ";".join(commands))
|
||||
|
||||
# but we know that it is 3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0 from the magnet link
|
||||
torrent_id = "3B245504CF5F11BBDBE1201CEA6A6BF45AEE1BC0" # rtorrent uses uppercase hashes
|
||||
print(f" Added test torrent: {torrent_id}")
|
||||
|
||||
torrent_list = client.d.multicall.filtered(
|
||||
"",
|
||||
"default",
|
||||
f"equal=d.hash=,cat={torrent_id}",
|
||||
"d.hash=",
|
||||
"d.state=",
|
||||
"d.completed_bytes=",
|
||||
"d.size_bytes=",
|
||||
"d.down.rate=",
|
||||
"d.up.rate=",
|
||||
"d.custom1=",
|
||||
"d.complete=",
|
||||
)
|
||||
torrent = torrent_list[0]
|
||||
if not torrent:
|
||||
print(" ERROR: Could not find added torrent in list")
|
||||
return False
|
||||
|
||||
|
||||
client.d.erase(torrent_id)
|
||||
print(" Removed test torrent")
|
||||
|
||||
print(" SUCCESS: rTorrent is working!")
|
||||
return True
|
||||
|
||||
except ImportError:
|
||||
print(" ERROR: xmlrpc.client not available")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f" ERROR: {e}")
|
||||
if "Connection refused" in str(e):
|
||||
print(" Is the container running? docker ps | grep rtorrent")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
print("Download Client Test Suite")
|
||||
@@ -410,6 +489,7 @@ def main():
|
||||
results["qbittorrent"] = test_qbittorrent()
|
||||
results["transmission"] = test_transmission()
|
||||
results["deluge"] = test_deluge()
|
||||
results["rtorrent"] = test_rtorrent()
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 50)
|
||||
|
||||
Reference in New Issue
Block a user