From 1e6e5f161c38092b3f675229f7edbaa1eebb12e5 Mon Sep 17 00:00:00 2001 From: s0len <35483234+s0len@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:50:17 +0200 Subject: [PATCH] Fix Nextory: bump X-App-Version, null series, missing urllib3 dep (#25) * Fix Nextory: bump X-App-Version and handle null series The Nextory API now rejects the old X-App-Version "5.4.1" with an AppDeprecateError. Bump it to "2026.05.4" (current Android app version). Also, the product API can return {"series": null} for standalone books (not just omit the key entirely). The previous `"series" in product_info` check passed in that case and we crashed on a NoneType subscript. Co-Authored-By: Claude Opus 4.7 (1M context) * Add urllib3 as explicit dependency grawlix/sources/storytel.py imports urllib3.util.parse_url but urllib3 was only pulled in transitively. Fresh installs (e.g. via uv tool) fail at import time with ModuleNotFoundError. Co-Authored-By: Claude Opus 4.7 (1M context) * Fix invalid escape sequence warning in saxo regex f"\d+$" produced a SyntaxWarning on Python 3.12 (and will become a SyntaxError in a future release). The string has no interpolation, so the raw form r"\d+$" is the right fix. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- grawlix/sources/nextory.py | 7 ++++--- grawlix/sources/saxo.py | 2 +- pyproject.toml | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/grawlix/sources/nextory.py b/grawlix/sources/nextory.py index b68761d..4c88f28 100644 --- a/grawlix/sources/nextory.py +++ b/grawlix/sources/nextory.py @@ -30,7 +30,7 @@ class Nextory(Source): self._client.headers.update( { "X-Application-Id": "200", - "X-App-Version": "5.4.1", + "X-App-Version": "2026.05.4", "X-Locale": LOCALE, "X-Model": "Personal Computer", "X-Device-Id": device_id, @@ -139,9 +139,10 @@ class Nextory(Source): @staticmethod def _extract_series_name(product_info: dict) -> Optional[str]: - if not "series" in product_info: + series = product_info.get("series") + if not series: return None - return product_info["series"]["name"] + return series["name"] async def _get_book_id_from_url_id(self, url_id: str) -> str: diff --git a/grawlix/sources/saxo.py b/grawlix/sources/saxo.py index 77731ae..0d59b95 100644 --- a/grawlix/sources/saxo.py +++ b/grawlix/sources/saxo.py @@ -122,7 +122,7 @@ class Saxo(Source): :param url: Url of book :returns: Isbn of book """ - isbn_match = re.search(f"\d+$", url) + isbn_match = re.search(r"\d+$", url) if isbn_match and isbn_match.group(): return isbn_match.group() raise NotImplemented diff --git a/pyproject.toml b/pyproject.toml index 83ffec8..ebf2958 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ dependencies = [ "pycryptodome", "rich", "tomli", + "urllib3", ] dynamic = ["version"]