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.
125 lines
3.2 KiB
125 lines
3.2 KiB
import os
|
|
import redis
|
|
|
|
from scraper.logger_decorators import logcall
|
|
|
|
# GUI log (non-breaking)
|
|
from scraper.ui_log import push_ui
|
|
|
|
# ---------------------------------------------------------
|
|
# Default Redis connection (Docker workers)
|
|
# ---------------------------------------------------------
|
|
REDIS_URL = os.getenv("REDIS_URL", "redis://redis:6379/0")
|
|
r = redis.Redis.from_url(REDIS_URL, decode_responses=True)
|
|
|
|
# Debug mode (optional)
|
|
ABORT_DEBUG = os.getenv("ABORT_DEBUG", "1") == "1"
|
|
|
|
# Internal flag to avoid spamming the same message
|
|
_seen_debug_keys = set()
|
|
|
|
|
|
# =========================================================
|
|
# ABORT FLAG
|
|
# =========================================================
|
|
|
|
|
|
def _debug(msg: str):
|
|
"""Print + GUI log (non-breaking, minimal noise)."""
|
|
print(msg)
|
|
push_ui(msg)
|
|
|
|
|
|
def set_abort(book_id: str):
|
|
"""Enable abort mode for this book."""
|
|
key = f"abort:{book_id}"
|
|
r.set(key, "1")
|
|
|
|
if ABORT_DEBUG:
|
|
_debug(f"[ABORT] SET {key}")
|
|
|
|
|
|
def clear_abort(book_id: str):
|
|
"""Clear abort flag."""
|
|
key = f"abort:{book_id}"
|
|
r.delete(key)
|
|
|
|
if ABORT_DEBUG:
|
|
_debug(f"[ABORT] CLEAR {key}")
|
|
|
|
|
|
def abort_requested(book_id: str, redis_client=None) -> bool:
|
|
"""
|
|
Return True if abort flag is set.
|
|
|
|
redis_client:
|
|
- Docker workers → None → use default Redis (r)
|
|
- Local macOS audio → passes Redis(host=127.0.0.1)
|
|
"""
|
|
client = redis_client or r
|
|
key = f"abort:{book_id}"
|
|
|
|
try:
|
|
exists = client.exists(key)
|
|
|
|
if ABORT_DEBUG:
|
|
# Log once per key
|
|
if key not in _seen_debug_keys:
|
|
try:
|
|
conn = client.connection_pool.connection_kwargs
|
|
host = conn.get("host")
|
|
port = conn.get("port")
|
|
db = conn.get("db")
|
|
_debug(
|
|
f"[ABORT_DEBUG] first check book_id={book_id} "
|
|
f"redis={host}:{port} db={db}"
|
|
)
|
|
except Exception:
|
|
_debug(f"[ABORT_DEBUG] first check book_id={book_id}")
|
|
|
|
_seen_debug_keys.add(key)
|
|
|
|
# Only log abort ACTIVE
|
|
if exists == 1:
|
|
_debug(f"[ABORT] ACTIVE for {book_id}")
|
|
|
|
return exists == 1
|
|
|
|
except Exception as e:
|
|
if ABORT_DEBUG:
|
|
_debug(f"[ABORT_DEBUG] ERROR checking {key}: {e}")
|
|
|
|
return False
|
|
|
|
|
|
# =========================================================
|
|
# PER-CHAPTER STATE
|
|
# =========================================================
|
|
|
|
|
|
def mark_chapter_started(book_id: str, chapter_num: int):
|
|
key = f"started:{book_id}:{chapter_num}"
|
|
r.set(key, "1")
|
|
|
|
|
|
def chapter_started(book_id: str, chapter_num: int) -> bool:
|
|
key = f"started:{book_id}:{chapter_num}"
|
|
return r.exists(key) == 1
|
|
|
|
|
|
# =========================================================
|
|
# UTILITY: RESET FOR A BOOK
|
|
# =========================================================
|
|
|
|
|
|
def reset_book_state(book_id: str):
|
|
"""
|
|
Remove abort flag and all chapter-start markers.
|
|
"""
|
|
key = f"abort:{book_id}"
|
|
r.delete(key)
|
|
|
|
pattern = f"started:{book_id}:*"
|
|
for k in r.scan_iter(pattern):
|
|
r.delete(k)
|