# ============================================================ # File: db/repository.py # Purpose: # High-level BookScraper database interface. # This is the ONLY module Celery tasks and Flask should use. # # Uses low-level primitives from db.db, but exposes # domain-level operations: # - fetch_book / fetch_all_books # - create_or_update_book # - set_status # - incrementing counters # ============================================================ from db.db import ( upsert_book, _raw_get_book, _raw_get_all_books, ) # ------------------------------------------------------------ # FETCH OPERATIONS # ------------------------------------------------------------ def fetch_book(book_id): """Return a single book dict or None.""" return _raw_get_book(book_id) def fetch_all_books(): """Return all books ordered newest → oldest.""" return _raw_get_all_books() # ------------------------------------------------------------ # BOOK CREATION / METADATA # ------------------------------------------------------------ def create_or_update_book( book_id, title=None, author=None, chapters_total=None, cover_url=None, cover_path=None, status=None, ): fields = {} if title is not None: fields["title"] = title if author is not None: fields["author"] = author if chapters_total is not None: fields["chapters_total"] = chapters_total if cover_url is not None: fields["cover_url"] = cover_url if cover_path is not None: fields["cover_path"] = cover_path if status is not None: fields["status"] = status if fields: upsert_book(book_id, **fields) # ------------------------------------------------------------ # STATUS MANAGEMENT # ------------------------------------------------------------ def set_status(book_id, status): upsert_book(book_id, status=status) # ------------------------------------------------------------ # INCREMENTING COUNTERS (atomic) # ------------------------------------------------------------ def inc_downloaded(book_id, amount=1): book = _raw_get_book(book_id) if not book: return cur = book.get("downloaded", 0) or 0 upsert_book(book_id, downloaded=cur + amount) def inc_parsed(book_id, amount=1): book = _raw_get_book(book_id) if not book: return cur = book.get("parsed", 0) or 0 upsert_book(book_id, parsed=cur + amount) def inc_audio_done(book_id, amount=1): book = _raw_get_book(book_id) if not book: return cur = book.get("audio_done", 0) or 0 upsert_book(book_id, audio_done=cur + amount)