mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 05:40:26 +02:00
fix: Adjust URL handling in CalibreOPDSClient to support base URLs without trailing slashes
This commit is contained in:
@@ -157,9 +157,9 @@ class CalibreOPDSClient:
|
|||||||
normalized = base_url.strip()
|
normalized = base_url.strip()
|
||||||
if not normalized:
|
if not normalized:
|
||||||
raise ValueError("Calibre OPDS base URL is required")
|
raise ValueError("Calibre OPDS base URL is required")
|
||||||
if not normalized.endswith("/"):
|
# Store the original URL without forcing a trailing slash.
|
||||||
normalized = f"{normalized}/"
|
# Some servers (e.g., Booklore) return 404 for URLs with trailing slashes.
|
||||||
self._base_url = normalized
|
self._base_url = normalized.rstrip("/")
|
||||||
self._auth = None
|
self._auth = None
|
||||||
if username:
|
if username:
|
||||||
self._auth = httpx.BasicAuth(username, password or "")
|
self._auth = httpx.BasicAuth(username, password or "")
|
||||||
@@ -183,12 +183,19 @@ class CalibreOPDSClient:
|
|||||||
href = href.strip()
|
href = href.strip()
|
||||||
if href.startswith("http://") or href.startswith("https://"):
|
if href.startswith("http://") or href.startswith("https://"):
|
||||||
return href
|
return href
|
||||||
if href.startswith("/") or href.startswith("?") or href.startswith("#"):
|
if href.startswith("/"):
|
||||||
return urljoin(self._base_url, href)
|
# Absolute path - join with origin only
|
||||||
|
parsed = urlparse(self._base_url)
|
||||||
|
return f"{parsed.scheme}://{parsed.netloc}{href}"
|
||||||
|
if href.startswith("?") or href.startswith("#"):
|
||||||
|
return f"{self._base_url}{href}"
|
||||||
if href.startswith("./") or href.startswith("../"):
|
if href.startswith("./") or href.startswith("../"):
|
||||||
return urljoin(self._base_url, href)
|
# For relative paths, we need a trailing slash for urljoin to work correctly
|
||||||
# Ensure relative paths like "search" keep the catalog prefix
|
base_with_slash = self._base_url if self._base_url.endswith("/") else f"{self._base_url}/"
|
||||||
return urljoin(self._base_url, f"./{href}")
|
return urljoin(base_with_slash, href)
|
||||||
|
# Relative path like "search" or "catalog?page=1" - treat as sibling
|
||||||
|
base_with_slash = self._base_url if self._base_url.endswith("/") else f"{self._base_url}/"
|
||||||
|
return urljoin(base_with_slash, href)
|
||||||
|
|
||||||
def _open_client(self) -> httpx.Client:
|
def _open_client(self) -> httpx.Client:
|
||||||
return httpx.Client(
|
return httpx.Client(
|
||||||
|
|||||||
@@ -163,7 +163,20 @@ def test_calibre_opds_relative_urls_keep_catalog_prefix() -> None:
|
|||||||
assert client._make_url("search") == "http://example.com/opds/search"
|
assert client._make_url("search") == "http://example.com/opds/search"
|
||||||
assert client._make_url("books/sample.epub") == "http://example.com/opds/books/sample.epub"
|
assert client._make_url("books/sample.epub") == "http://example.com/opds/books/sample.epub"
|
||||||
assert client._make_url("/cover/1") == "http://example.com/cover/1"
|
assert client._make_url("/cover/1") == "http://example.com/cover/1"
|
||||||
assert client._make_url("?page=2") == "http://example.com/opds/?page=2"
|
assert client._make_url("?page=2") == "http://example.com/opds?page=2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_calibre_opds_base_url_without_trailing_slash() -> None:
|
||||||
|
"""Ensure the client works with base URLs that don't have trailing slashes."""
|
||||||
|
client = CalibreOPDSClient("http://example.com/api/v1/opds")
|
||||||
|
|
||||||
|
# Base URL should be stored without trailing slash
|
||||||
|
assert client._base_url == "http://example.com/api/v1/opds"
|
||||||
|
# Relative paths should resolve as siblings to the base URL
|
||||||
|
assert client._make_url("catalog") == "http://example.com/api/v1/opds/catalog"
|
||||||
|
assert client._make_url("search?q=test") == "http://example.com/api/v1/opds/search?q=test"
|
||||||
|
assert client._make_url("/api/v1/opds/books") == "http://example.com/api/v1/opds/books"
|
||||||
|
assert client._make_url("?page=2") == "http://example.com/api/v1/opds?page=2"
|
||||||
|
|
||||||
|
|
||||||
def test_calibre_opds_filters_out_unsupported_formats() -> None:
|
def test_calibre_opds_filters_out_unsupported_formats() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user