# ============================================================ # File: scraper/progress.py # Purpose: Track chapter counters for WebGUI progress. # ============================================================ import os import redis REDIS_URL = os.getenv("REDIS_BROKER", "redis://redis:6379/0") r = redis.Redis.from_url(REDIS_URL, decode_responses=True) # ------------------------------------------------------------ # SET TOTAL # ------------------------------------------------------------ def set_total(book_id: str, total: int): r.set(f"progress:{book_id}:total", total) # ------------------------------------------------------------ # COUNTERS # ------------------------------------------------------------ def inc_completed(book_id: str): r.incr(f"progress:{book_id}:completed") def inc_skipped(book_id: str): r.incr(f"progress:{book_id}:skipped") def inc_failed(book_id: str): r.incr(f"progress:{book_id}:failed") # ------------------------------------------------------------ # FAILED CHAPTER LIST # ------------------------------------------------------------ def add_failed_chapter(book_id: str, chapter: int, reason: str): entry = f"Chapter {chapter}: {reason}" r.rpush(f"progress:{book_id}:failed_list", entry) def get_failed_list(book_id: str): return r.lrange(f"progress:{book_id}:failed_list", 0, -1) # ------------------------------------------------------------ # READ STRUCT FOR UI # ------------------------------------------------------------ def get_progress(book_id: str): total = int(r.get(f"progress:{book_id}:total") or 0) completed = int(r.get(f"progress:{book_id}:completed") or 0) skipped = int(r.get(f"progress:{book_id}:skipped") or 0) failed = int(r.get(f"progress:{book_id}:failed") or 0) abort = r.exists(f"abort:{book_id}") == 1 failed_list = get_failed_list(book_id) return { "book_id": book_id, "total": total, "completed": completed, "skipped": skipped, "failed": failed, "failed_list": failed_list, "abort": abort, }