ranobelib-python-sdk 0.8.0__tar.gz → 0.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/PKG-INFO +1 -1
  2. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/pyproject.toml +1 -1
  3. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/pyproject.toml.orig +1 -1
  4. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/catalog.py +15 -11
  5. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/client.py +8 -6
  6. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/README.md +0 -0
  7. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/__init__.py +0 -0
  8. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/cache.py +0 -0
  9. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/console.py +0 -0
  10. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exceptions.py +0 -0
  11. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/__init__.py +0 -0
  12. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/_illustrations.py +0 -0
  13. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/_shared.py +0 -0
  14. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/epub.py +0 -0
  15. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/fb2.py +0 -0
  16. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/pdf.py +0 -0
  17. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/exporters/txt.py +0 -0
  18. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/models.py +0 -0
  19. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/numbering.py +0 -0
  20. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/py.typed +0 -0
  21. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/sdk.py +0 -0
  22. {ranobelib_python_sdk-0.8.0 → ranobelib_python_sdk-0.9.0}/src/ranobelib/sizing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ranobelib-python-sdk
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: Async Python SDK for ranobelib.me: title metadata, chapter/volume downloads, and export to epub/fb2/txt/pdf
5
5
  Keywords: ranobelib,ranobe,novel,webnovel,epub,fb2,sdk
6
6
  Author: LLIJIYAPNIK
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ranobelib-python-sdk"
3
- version = "0.8.0"
3
+ version = "0.9.0"
4
4
  description = "Async Python SDK for ranobelib.me: title metadata, chapter/volume downloads, and export to epub/fb2/txt/pdf"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ranobelib-python-sdk"
3
- version = "0.8.0"
3
+ version = "0.9.0"
4
4
  description = "Async Python SDK for ranobelib.me: title metadata, chapter/volume downloads, and export to epub/fb2/txt/pdf"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -81,7 +81,7 @@ class Catalog:
81
81
  genres: list[int] | None = None,
82
82
  tags: list[int] | None = None,
83
83
  status: int | None = None,
84
- country: int | None = None,
84
+ countries: list[int] | None = None,
85
85
  sort: str = DEFAULT_SORT,
86
86
  refresh: bool = False,
87
87
  ) -> CatalogPage:
@@ -104,11 +104,14 @@ class Catalog:
104
104
  from tags being more numerous/specific than genres). Also not validated
105
105
  before sending, same as ``genres``.
106
106
  status: A single ``Title.status.id`` to filter by (e.g. ongoing vs. completed).
107
- country: A single ``Country.id`` to filter by — a title only has one country of
108
- origin, unlike ``genres``. Ids come from ``list_countries()``. Sent on the
109
- wire as the API's ``types[]`` parameter, not a ``country``/``countries[]``
110
- one — see docs/api-notes.md for why (``Country`` mirrors the API's own
111
- "type" concept, which isn't strictly limited to literal countries).
107
+ countries: ``Country.id``s to filter by. A title matches if its own country is
108
+ *any* of these (OR, not AND like ``genres``/``tags`` — a title only has one
109
+ country of origin, so requiring all of them could never match past the first,
110
+ see docs/api-notes.md). ``None`` or an empty list applies no country filter.
111
+ Ids come from ``list_countries()``. Sent on the wire as the API's ``types[]``
112
+ parameter, not a ``country``/``countries[]`` one — see docs/api-notes.md for
113
+ why (``Country`` mirrors the API's own "type" concept, which isn't strictly
114
+ limited to literal countries).
112
115
  sort: Sort order. Despite the name, this is sent as the API's ``sort_by``
113
116
  parameter — an actual ``sort`` parameter exists but is silently ignored by
114
117
  the API (see docs/api-notes.md). Known accepted values: ``"name"``,
@@ -140,7 +143,7 @@ class Catalog:
140
143
  genres=genres,
141
144
  tags=tags,
142
145
  status=status,
143
- country=country,
146
+ countries=countries,
144
147
  sort=sort,
145
148
  )
146
149
  if not refresh:
@@ -155,7 +158,7 @@ class Catalog:
155
158
  genres=genres,
156
159
  tags=tags,
157
160
  status=status,
158
- country=country,
161
+ countries=countries,
159
162
  sort=sort,
160
163
  )
161
164
  self._cache.set(key, data)
@@ -191,7 +194,7 @@ class Catalog:
191
194
 
192
195
  async def list_countries(self, *, refresh: bool = False) -> list[Country]:
193
196
  """Fetch the full list of catalog countries (id → name), for use as filter options
194
- with ``list_titles(country=...)``.
197
+ with ``list_titles(countries=...)``.
195
198
 
196
199
  Mirrors ``list_genres()`` exactly, down to the network-wide, not-site-scoped shape
197
200
  of the underlying endpoint (``GET /api/constants?fields[]=types`` — the API's own
@@ -225,14 +228,15 @@ def _cache_key(
225
228
  genres: list[int] | None,
226
229
  tags: list[int] | None,
227
230
  status: int | None,
228
- country: int | None,
231
+ countries: list[int] | None,
229
232
  sort: str,
230
233
  ) -> str:
231
234
  genres_part = ",".join(str(genre_id) for genre_id in genres or [])
232
235
  tags_part = ",".join(str(tag_id) for tag_id in tags or [])
236
+ countries_part = ",".join(str(country_id) for country_id in countries or [])
233
237
  return (
234
238
  f"catalog:{page}:{per_page}:{query or ''}:{genres_part}:{tags_part}:"
235
- f"{status}:{country}:{sort}"
239
+ f"{status}:{countries_part}:{sort}"
236
240
  )
237
241
 
238
242
 
@@ -172,7 +172,7 @@ class ApiClient:
172
172
  genres: list[int] | None,
173
173
  tags: list[int] | None,
174
174
  status: int | None,
175
- country: int | None,
175
+ countries: list[int] | None,
176
176
  sort: str,
177
177
  ) -> dict[str, Any]:
178
178
  """Fetch one page of the catalog listing/search results.
@@ -192,9 +192,11 @@ class ApiClient:
192
192
  tags: Tag ids to filter by. Same AND semantics as ``genres`` — a title must have
193
193
  *all* of them, not just any one (see docs/api-notes.md).
194
194
  status: A single ``Title.status.id`` to filter by.
195
- country: A single ``Country.id`` to filter by. Sent on the wire as ``types[]``
196
- (repeatable array parameter, but only ever given one value here) — the API's
197
- own name for this concept is "type", not "country" (see docs/api-notes.md).
195
+ countries: ``Country.id``s to filter by. A title matches if its own country is
196
+ *any* of these (OR, not AND like ``genres``/``tags`` — a title only has one
197
+ country, confirmed against the live API, see docs/api-notes.md). Sent on the
198
+ wire as repeated ``types[]`` parameters — the API's own name for this concept
199
+ is "type", not "country" (see docs/api-notes.md).
198
200
  sort: Forwarded as the API's ``sort_by`` parameter, not ``sort`` — the API
199
201
  silently ignores an actual ``sort`` parameter (see docs/api-notes.md); this
200
202
  mismatch between the SDK's public keyword and the wire parameter name is
@@ -217,8 +219,8 @@ class ApiClient:
217
219
  params.append(("tags[]", str(tag_id)))
218
220
  if status is not None:
219
221
  params.append(("status[]", str(status)))
220
- if country is not None:
221
- params.append(("types[]", str(country)))
222
+ for country_id in countries or []:
223
+ params.append(("types[]", str(country_id)))
222
224
 
223
225
  response = await self._get("/manga", params=httpx.QueryParams(params))
224
226
  self._raise_for_status(