You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.4 KiB
132 lines
4.4 KiB
# ============================================================
|
|
# File: db/state_redis.py (UPDATED for book_idx-only architecture)
|
|
# Purpose:
|
|
# Low-level Redis counters/state for BookScraper.
|
|
# Used ONLY by db.repository façade.
|
|
# ============================================================
|
|
|
|
import os
|
|
import time
|
|
import redis
|
|
|
|
from logbus.publisher import log
|
|
|
|
REDIS_URL = os.getenv("REDIS_BROKER", "redis://redis:6379/0")
|
|
r = redis.Redis.from_url(REDIS_URL, decode_responses=True)
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# INTERNAL KEY BUILDER
|
|
# ------------------------------------------------------------
|
|
def _key(book_idx: str) -> str:
|
|
return f"book:{book_idx}:state"
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# STATUS
|
|
# ------------------------------------------------------------
|
|
def redis_set_status(book_idx: str, status: str):
|
|
key = _key(book_idx)
|
|
r.hset(key, "status", status)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# TOTAL CHAPTERS
|
|
# ------------------------------------------------------------
|
|
def redis_set_chapters_total(book_idx: str, total: int):
|
|
key = _key(book_idx)
|
|
r.hset(key, "chapters_total", total)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# DOWNLOAD COUNTERS
|
|
# ------------------------------------------------------------
|
|
def redis_inc_download_done(book_idx: str, amount: int = 1):
|
|
key = _key(book_idx)
|
|
r.hincrby(key, "chapters_download_done", amount)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
def redis_inc_download_skipped(book_idx: str, amount: int = 1):
|
|
log(f"[DB-REDIS] Incrementing download skipped for {book_idx} by {amount}")
|
|
key = _key(book_idx)
|
|
r.hincrby(key, "chapters_download_skipped", amount)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# PARSE COUNTERS
|
|
# ------------------------------------------------------------
|
|
def redis_inc_parsed_done(book_idx: str, amount: int = 1):
|
|
key = _key(book_idx)
|
|
r.hincrby(key, "chapters_parsed_done", amount)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# AUDIO COUNTERS
|
|
# ------------------------------------------------------------
|
|
def redis_inc_audio_done(book_idx: str, amount: int = 1):
|
|
log(f"[DB-REDIS] Incrementing audio done for {book_idx} by {amount}")
|
|
key = _key(book_idx)
|
|
r.hincrby(key, "audio_done", amount)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
def redis_inc_audio_skipped(book_idx: str, amount: int = 1):
|
|
log(f"[DB-REDIS] Incrementing audio skipped for {book_idx} by {amount}")
|
|
"""
|
|
New: Count skipped audio chapters (timeouts, pre-existing files, abort, etc.)
|
|
SQL does NOT track this; Redis-only metric.
|
|
"""
|
|
key = _key(book_idx)
|
|
r.hincrby(key, "audio_skipped", amount)
|
|
r.hset(key, "last_update", int(time.time()))
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# INITIALISE BOOK STATE
|
|
# ------------------------------------------------------------
|
|
def init_book_state(book_id: str, title: str, url: str, chapters_total: int):
|
|
"""
|
|
Initialiseert de complete Redis state voor een nieuw boek.
|
|
LET OP:
|
|
- Als een key al bestaat → NIET resetten (progress behouden).
|
|
- Alleen missende velden worden toegevoegd.
|
|
"""
|
|
|
|
key = f"book:{book_id}:state"
|
|
|
|
# Bestaat al? Dan vullen we alleen missende velden aan.
|
|
exists = r.exists(key)
|
|
|
|
pipeline = r.pipeline()
|
|
|
|
# Basis metadata
|
|
pipeline.hsetnx(key, "book_id", book_id)
|
|
pipeline.hsetnx(key, "title", title or "")
|
|
pipeline.hsetnx(key, "url", url or "")
|
|
|
|
# State
|
|
pipeline.hsetnx(key, "status", "registered")
|
|
|
|
# Counters
|
|
pipeline.hsetnx(key, "chapters_total", chapters_total)
|
|
pipeline.hsetnx(key, "chapters_download_done", 0)
|
|
pipeline.hsetnx(key, "chapters_download_skipped", 0)
|
|
pipeline.hsetnx(key, "chapters_parsed_done", 0)
|
|
pipeline.hsetnx(key, "audio_done", 0)
|
|
pipeline.hsetnx(key, "audio_skipped", 0)
|
|
|
|
# Timestamp
|
|
pipeline.hset(key, "last_update", int(time.time()))
|
|
|
|
pipeline.execute()
|
|
|
|
if exists:
|
|
log(f"[DB-REDIS] init_book_state(): UPDATED existing state for {book_id}")
|
|
else:
|
|
log(f"[DB-REDIS] init_book_state(): CREATED new state for {book_id}")
|