mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-10-05 22:05:50 +01:00
calibrain said in #1315 that he'd review and merge a Debrid-Link client if someone took a stab at it, so here it is. It's the fourth debrid service alongside AllDebrid, Real-Debrid and TorBox and it uses the same DownloadClient interface as the other three. No frontend changes, the settings UI picks it up from the backend field definitions. **I can't test this against the live API.** I don't use debrid and I don't have a Debrid-Link key. Everything here is built from their v2 API docs and cross-checked against two independent reference implementations, so the request shapes should be right, but nobody has run a real magnet through it yet. @Tatsu941 you opened the issue and mentioned they give developers free premium. Would you be able to try it? The things most worth confirming are the field names on a seedbox torrent, that `premiumLeft` is the right premium check, and that an API error comes back the way the client expects. Happy to fix whatever turns up. Two things about their API shaped how this is written. Every v2 endpoint wraps its payload in a `{success, value}` envelope and a failure can arrive with an HTTP 200, so `_request_value` decides the outcome from the body instead of the status code. A completed seedbox torrent already carries a direct `downloadUrl` on every file. The other three clients each need a separate unrestrict or link-request call per file and this one doesn't, which is why it came out shorter than them despite doing the same job. Endpoints used: | Endpoint | Used for | |---|---| | `GET account/infos` | test the key, confirm premium time remains | | `POST seedbox/add` | magnet as JSON, .torrent as multipart | | `GET seedbox/list` | poll progress | | `DELETE seedbox/{id}/remove` | clean up | Ruff and basedpyright are clean and the 36 new tests pass. The two failures in `tests/e2e/test_proxy_auth_middleware.py` are already on main and fail the same way on a pristine checkout. They assume the first proxy-authenticated user becomes an admin, which only holds while the user table has no admin in it, so they depend on how many users earlier tests created. One thing for review: the download loop uses `download_url` like the other three clients, which holds each file in memory. I kept the existing pattern rather than do something different in a new-provider PR, but say so if you'd rather it streamed here. Closes #1315
50 lines
2.0 KiB
Python
50 lines
2.0 KiB
Python
"""Debrid-Link Download Client settings and connection-action tests."""
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from shelfmark.core.settings_registry import ActionButton, PasswordField
|
|
|
|
|
|
def _field(fields, key):
|
|
return next(field for field in fields if field.key == key)
|
|
|
|
|
|
def test_debridlink_fields_are_registered_with_conditional_visibility():
|
|
from shelfmark.download.clients.settings import prowlarr_clients_settings
|
|
|
|
fields = prowlarr_clients_settings()
|
|
client_field = _field(fields, "PROWLARR_TORRENT_CLIENT")
|
|
api_key_field = _field(fields, "DEBRIDLINK_API_KEY")
|
|
test_action = _field(fields, "test_debridlink")
|
|
|
|
assert {option["value"] for option in client_field.options} >= {"debridlink"}
|
|
assert isinstance(api_key_field, PasswordField)
|
|
assert api_key_field.show_when == {"field": "PROWLARR_TORRENT_CLIENT", "value": "debridlink"}
|
|
assert isinstance(test_action, ActionButton)
|
|
assert test_action.show_when == {"field": "PROWLARR_TORRENT_CLIENT", "value": "debridlink"}
|
|
|
|
|
|
def test_debridlink_connection_action_uses_unsaved_api_key(monkeypatch):
|
|
from shelfmark.core.config import config
|
|
from shelfmark.download.clients import settings as settings_module
|
|
|
|
client = MagicMock()
|
|
client.test_connection.return_value = (True, "Connected")
|
|
client_type = MagicMock(return_value=client)
|
|
monkeypatch.setattr("shelfmark.download.clients.debridlink.DebridLinkClient", client_type)
|
|
monkeypatch.setattr(config, "get", lambda _key, default="": "saved-key")
|
|
|
|
result = settings_module._test_debridlink_connection({"DEBRIDLINK_API_KEY": "unsaved-key"})
|
|
|
|
assert result == {"success": True, "message": "Connected"}
|
|
assert client._api_key == "unsaved-key"
|
|
|
|
|
|
def test_debridlink_connection_action_requires_api_key():
|
|
from shelfmark.download.clients.settings import _test_debridlink_connection
|
|
|
|
assert _test_debridlink_connection({"DEBRIDLINK_API_KEY": ""}) == {
|
|
"success": False,
|
|
"message": "Debrid-Link API Key is required",
|
|
}
|