diff --git a/grawlix/__main__.py b/grawlix/__main__.py index 5524c13..5373faf 100644 --- a/grawlix/__main__.py +++ b/grawlix/__main__.py @@ -112,15 +112,12 @@ async def main() -> None: elif isinstance(result, Series): await download_series(source, result, args) logging.info("") - except GrawlixError as error: - # Don't abort a multi-url batch (e.g. `-f links.txt`) on one failure - error.print_error() - if logging.debug_mode: - traceback.print_exc() - if len(urls) == 1: - exit(1) except Exception as error: - logging.info(f"Skipping {url} - {type(error).__name__}: {error}") + # Don't abort a multi-url batch (e.g. `-f links.txt`) on one failure + if isinstance(error, GrawlixError): + error.print_error() + else: + logging.info(f"Skipping {url} - {type(error).__name__}: {error}") if logging.debug_mode: traceback.print_exc() if len(urls) == 1: @@ -141,13 +138,15 @@ async def download_series(source: Source, series: Series, args) -> None: book: Book = await source.download_book_from_id(book_id) await download_with_progress(book, progress, template) except AccessDenied: - logging.info("Skipping - Access Denied") + failed.append(book_id) + logging.info(f"Skipping {book_id} - Access Denied") except Exception as error: # Don't let one bad book abort the whole list; record and continue - failed.append((book_id, error)) + failed.append(book_id) logging.info(f"Skipping {book_id} - {type(error).__name__}: {error}") if failed: - logging.info(f"{len(failed)} book(s) could not be downloaded and were skipped") + logging.info(f"{len(failed)} book(s) could not be downloaded and were skipped: " + + ", ".join(str(b) for b in failed)) diff --git a/grawlix/sources/nextory.py b/grawlix/sources/nextory.py index 257f91a..656c600 100644 --- a/grawlix/sources/nextory.py +++ b/grawlix/sources/nextory.py @@ -129,6 +129,7 @@ class Nextory(Source): if want_to_read_id is None: raise InvalidUrl book_ids = [] + seen: set = set() page = 0 while True: response = await self._client.get( @@ -136,12 +137,18 @@ class Nextory(Source): params = { "page": page, "per": 1000, "id": want_to_read_id }, ) products = response.json().get("products", []) - if not products: - break + new = 0 for product in products: + pid = product["id"] + if pid in seen: + continue + seen.add(pid) + new += 1 if any(f.get("type") == "epub" for f in product.get("formats", [])): - book_ids.append(product["id"]) - if len(products) < 1000: + book_ids.append(pid) + # Stop on an empty page, a short (final) page, or a page that adds + # nothing new (guards against an API that ignores `page`). + if not products or new == 0 or len(products) < 1000: break page += 1 return Series(