mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-09-24 11:10:19 +01:00
fix(deluge): send seeding ratio limit under Deluge's own keys (#1367)
Deluge's per-torrent options are `stop_at_ratio` (bool) and `stop_ratio` (float), and `torrentmanager` checks `options['stop_at_ratio'] and get_ratio() >= options['stop_ratio']`. We were putting the indexer's float into `stop_at_ratio`, which only switched stopping on and left the daemon's global ratio (default 2.0) as the one actually enforced. A `ratio_limit` of 0 turned stopping off entirely. `stop_at_ratio_enabled` is not a Deluge option at all. Deluge has no per-torrent seeding time limit, `seed_time_limit` is a global core preference, so the value is logged as unapplied instead of sent as a key the daemon drops. qBittorrent and Transmission already honour both indexer limits, so this removes a silent difference between clients. ## Verification - `tests/prowlarr/test_deluge_client.py`: the ratio arrives as `stop_ratio` with `stop_at_ratio` set, and no key Deluge does not define is sent. Both fail on current main and pass here. - Full suite (3165), ruff, ruff format, basedpyright, vulture green.
This commit is contained in:
@@ -292,11 +292,14 @@ class DelugeClient(DownloadClient):
|
||||
# Per-torrent seeding limits from indexer
|
||||
seeding_time_limit = coerce_optional_int(kwargs.get("seeding_time_limit"))
|
||||
if seeding_time_limit is not None:
|
||||
options["seed_time_limit"] = seeding_time_limit
|
||||
logger.debug(
|
||||
"Deluge has no per-torrent seeding time limit, ignoring %s minutes",
|
||||
seeding_time_limit,
|
||||
)
|
||||
ratio_limit = coerce_optional_float(kwargs.get("ratio_limit"))
|
||||
if ratio_limit is not None:
|
||||
options["stop_at_ratio"] = ratio_limit
|
||||
options["stop_at_ratio_enabled"] = True
|
||||
options["stop_ratio"] = ratio_limit
|
||||
options["stop_at_ratio"] = True
|
||||
|
||||
if torrent_info.is_magnet:
|
||||
magnet_url = torrent_info.magnet_url or url
|
||||
|
||||
@@ -114,6 +114,82 @@ class TestDelugeClientAddDownload:
|
||||
{},
|
||||
)
|
||||
|
||||
def test_add_download_sends_ratio_limit_as_stop_ratio(self, monkeypatch):
|
||||
"""Ratio limits should use Deluge's stop_ratio float plus the stop_at_ratio switch."""
|
||||
config_values = {
|
||||
"DELUGE_HOST": "http://localhost",
|
||||
"DELUGE_PORT": "8112",
|
||||
"DELUGE_PASSWORD": "password",
|
||||
"DELUGE_CATEGORY": "books",
|
||||
}
|
||||
monkeypatch.setattr(
|
||||
"shelfmark.download.clients.deluge.config.get",
|
||||
make_config_getter(config_values),
|
||||
)
|
||||
|
||||
from shelfmark.download.clients.deluge import DelugeClient
|
||||
|
||||
client = DelugeClient()
|
||||
monkeypatch.setattr(client, "_ensure_connected", lambda: None)
|
||||
mock_rpc_call = MagicMock(return_value="abcdef1234567890abcdef1234567890abcdef12")
|
||||
monkeypatch.setattr(client, "_rpc_call", mock_rpc_call)
|
||||
monkeypatch.setattr(client, "_try_set_label", MagicMock())
|
||||
|
||||
magnet = "magnet:?xt=urn:btih:ABCDEF1234567890ABCDEF1234567890ABCDEF12&dn=test"
|
||||
with patch(
|
||||
"shelfmark.download.clients.deluge.extract_torrent_info", autospec=True
|
||||
) as mock_extract:
|
||||
mock_extract.return_value = TorrentInfo(
|
||||
info_hash="abcdef1234567890abcdef1234567890abcdef12",
|
||||
torrent_data=None,
|
||||
is_magnet=True,
|
||||
magnet_url=magnet,
|
||||
)
|
||||
client.add_download(magnet, "Test", ratio_limit=1.5)
|
||||
|
||||
mock_rpc_call.assert_called_once_with(
|
||||
"core.add_torrent_magnet",
|
||||
magnet,
|
||||
{"stop_ratio": 1.5, "stop_at_ratio": True},
|
||||
)
|
||||
|
||||
def test_add_download_skips_options_deluge_does_not_define(self, monkeypatch):
|
||||
"""Deluge has no per-torrent seeding time limit, so no unknown keys are sent."""
|
||||
config_values = {
|
||||
"DELUGE_HOST": "http://localhost",
|
||||
"DELUGE_PORT": "8112",
|
||||
"DELUGE_PASSWORD": "password",
|
||||
"DELUGE_CATEGORY": "books",
|
||||
}
|
||||
monkeypatch.setattr(
|
||||
"shelfmark.download.clients.deluge.config.get",
|
||||
make_config_getter(config_values),
|
||||
)
|
||||
|
||||
from shelfmark.download.clients.deluge import DelugeClient
|
||||
|
||||
client = DelugeClient()
|
||||
monkeypatch.setattr(client, "_ensure_connected", lambda: None)
|
||||
mock_rpc_call = MagicMock(return_value="abcdef1234567890abcdef1234567890abcdef12")
|
||||
monkeypatch.setattr(client, "_rpc_call", mock_rpc_call)
|
||||
monkeypatch.setattr(client, "_try_set_label", MagicMock())
|
||||
|
||||
magnet = "magnet:?xt=urn:btih:ABCDEF1234567890ABCDEF1234567890ABCDEF12&dn=test"
|
||||
with patch(
|
||||
"shelfmark.download.clients.deluge.extract_torrent_info", autospec=True
|
||||
) as mock_extract:
|
||||
mock_extract.return_value = TorrentInfo(
|
||||
info_hash="abcdef1234567890abcdef1234567890abcdef12",
|
||||
torrent_data=None,
|
||||
is_magnet=True,
|
||||
magnet_url=magnet,
|
||||
)
|
||||
client.add_download(magnet, "Test", ratio_limit=1.5, seeding_time_limit=120)
|
||||
|
||||
options = mock_rpc_call.call_args.args[2]
|
||||
assert "stop_at_ratio_enabled" not in options
|
||||
assert "seed_time_limit" not in options
|
||||
|
||||
|
||||
class TestDelugeClientErrors:
|
||||
"""Tests for Deluge error handling fallbacks."""
|
||||
|
||||
Reference in New Issue
Block a user