mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-10-04 22:05:45 +01:00
Fix ABB magnet parsing (#623)
This commit is contained in:
@@ -76,6 +76,7 @@ class DownloadTask:
|
||||
size: Optional[str] = None
|
||||
preview: Optional[str] = None
|
||||
content_type: Optional[str] = None # "book (fiction)", "audiobook", "magazine", etc.
|
||||
source_url: Optional[str] = None # Original release URL used by source-specific handlers
|
||||
|
||||
# Series info (for library naming templates)
|
||||
series_name: Optional[str] = None
|
||||
|
||||
@@ -188,6 +188,16 @@ def queue_release(
|
||||
year = release_data.get('year') or extra.get('year')
|
||||
preview = release_data.get('preview') or extra.get('preview')
|
||||
content_type = release_data.get('content_type') or extra.get('content_type')
|
||||
source_url_raw = (
|
||||
release_data.get('download_url')
|
||||
or release_data.get('source_url')
|
||||
or release_data.get('info_url')
|
||||
or extra.get('detail_url')
|
||||
or extra.get('source_url')
|
||||
)
|
||||
source_url = source_url_raw.strip() if isinstance(source_url_raw, str) else None
|
||||
if source_url == "":
|
||||
source_url = None
|
||||
|
||||
# Get series info for library naming templates
|
||||
series_name = release_data.get('series_name') or extra.get('series_name')
|
||||
@@ -220,6 +230,7 @@ def queue_release(
|
||||
size=release_data.get('size'),
|
||||
preview=preview,
|
||||
content_type=content_type,
|
||||
source_url=source_url,
|
||||
series_name=series_name,
|
||||
series_position=series_position,
|
||||
subtitle=subtitle,
|
||||
|
||||
@@ -19,6 +19,19 @@ logger = setup_logger(__name__)
|
||||
class AudiobookBayHandler(ExternalClientHandler):
|
||||
"""Handler for AudiobookBay downloads via configured torrent client."""
|
||||
|
||||
@staticmethod
|
||||
def _resolve_detail_url(task: DownloadTask) -> Optional[str]:
|
||||
"""Resolve ABB detail URL from queued task metadata."""
|
||||
source_url = (task.source_url or "").strip()
|
||||
if source_url:
|
||||
return source_url
|
||||
|
||||
# Backward-compat: older tests and some legacy flows used task_id as URL.
|
||||
task_id = (task.task_id or "").strip()
|
||||
if task_id.startswith(("http://", "https://")):
|
||||
return task_id
|
||||
return None
|
||||
|
||||
def _get_client(self, protocol: str) -> Optional[DownloadClient]:
|
||||
"""Compatibility shim so module-level patching still works in tests."""
|
||||
return get_client(protocol)
|
||||
@@ -33,7 +46,12 @@ class AudiobookBayHandler(ExternalClientHandler):
|
||||
status_callback: Callable[[str, Optional[str]], None],
|
||||
) -> Optional[DownloadRequest]:
|
||||
"""Resolve ABB detail page into a magnet-link download request."""
|
||||
detail_url = task.task_id
|
||||
detail_url = self._resolve_detail_url(task)
|
||||
if not detail_url:
|
||||
status_callback("error", "Missing AudiobookBay details URL")
|
||||
logger.warning(f"Missing details URL for AudiobookBay task: {task.task_id}")
|
||||
return None
|
||||
|
||||
hostname = normalize_hostname(config.get("ABB_HOSTNAME", ""))
|
||||
if not hostname:
|
||||
hostname = normalize_hostname(urlparse(detail_url).hostname)
|
||||
|
||||
@@ -82,6 +82,43 @@ class TestAudiobookBayHandlerDownload:
|
||||
mock_poll.assert_called_once()
|
||||
assert "resolving" in recorder.statuses
|
||||
|
||||
@patch('shelfmark.release_sources.audiobookbay.handler.scraper.extract_magnet_link')
|
||||
@patch('shelfmark.release_sources.audiobookbay.handler.get_client')
|
||||
def test_download_uses_source_url_for_hashed_task_id(self, mock_get_client, mock_extract_magnet):
|
||||
"""Test release queue flow where task_id is source hash and source_url has detail URL."""
|
||||
mock_extract_magnet.return_value = "magnet:?xt=urn:btih:abc123"
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.name = "qbittorrent"
|
||||
mock_client.find_existing.return_value = None
|
||||
mock_client.add_download.return_value = "download_id_123"
|
||||
mock_get_client.return_value = mock_client
|
||||
|
||||
handler = AudiobookBayHandler()
|
||||
task = DownloadTask(
|
||||
task_id="35f56a3e5734bfa69c3169ee8e605a60",
|
||||
source="audiobookbay",
|
||||
title="Test Book",
|
||||
content_type="audiobook",
|
||||
source_url="https://audiobookbay.lu/abss/test-book/",
|
||||
)
|
||||
cancel_flag = Event()
|
||||
recorder = ProgressRecorder()
|
||||
with patch.object(AudiobookBayHandler, "_poll_and_complete", return_value=None):
|
||||
result = handler.download(
|
||||
task=task,
|
||||
cancel_flag=cancel_flag,
|
||||
progress_callback=recorder.progress_callback,
|
||||
status_callback=recorder.status_callback,
|
||||
)
|
||||
|
||||
assert result is None
|
||||
mock_extract_magnet.assert_called_once_with(
|
||||
"https://audiobookbay.lu/abss/test-book/",
|
||||
"audiobookbay.lu"
|
||||
)
|
||||
assert "resolving" in recorder.statuses
|
||||
|
||||
@patch('shelfmark.release_sources.audiobookbay.handler.scraper.extract_magnet_link')
|
||||
@patch('shelfmark.release_sources.audiobookbay.handler.get_client')
|
||||
def test_download_existing_complete(self, mock_get_client, mock_extract_magnet):
|
||||
|
||||
@@ -74,6 +74,7 @@ def test_queue_release_uses_user_specific_books_output_mode(monkeypatch):
|
||||
"content_type": "book (fiction)",
|
||||
"format": "epub",
|
||||
"size": "1 MB",
|
||||
"download_url": "https://audiobookbay.lu/abss/release-title/",
|
||||
}
|
||||
|
||||
success, error = orchestrator.queue_release(release_data, user_id=42, username="alice")
|
||||
@@ -83,6 +84,7 @@ def test_queue_release_uses_user_specific_books_output_mode(monkeypatch):
|
||||
task = captured["task"]
|
||||
assert task.output_mode == "email"
|
||||
assert task.output_args == {"to": "alice@example.com"}
|
||||
assert task.source_url == "https://audiobookbay.lu/abss/release-title/"
|
||||
assert ("BOOKS_OUTPUT_MODE", 42) in config_calls
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user