From 78c01cf5f23a2d065b5fc85a369f1694148eb454 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Wed, 22 Apr 2026 22:01:22 -0400 Subject: [PATCH] riddle/trivia: persist dedup caches to disk so restarts don't reset them riddle_cache.json: stores last 30 riddle texts + answers trivia_cache.json: stores last 20 questions per category Both files are capped at their respective maxes so they never grow unboundedly. Loaded on startup, saved after each new question. Co-Authored-By: Claude Sonnet 4.6 --- matrixbot/commands.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/matrixbot/commands.py b/matrixbot/commands.py index 3c989f5..ba589a1 100644 --- a/matrixbot/commands.py +++ b/matrixbot/commands.py @@ -6,6 +6,7 @@ import time import logging from collections import Counter from datetime import datetime +from pathlib import Path import aiohttp @@ -1006,8 +1007,25 @@ _TRIVIA_FALLBACKS: dict[str, list[dict]] = { # Per-category cache of recently asked question texts (avoids duplicates) -_trivia_recent: dict[str, list[str]] = {} _TRIVIA_RECENT_MAX = 20 +_TRIVIA_CACHE_FILE = Path("trivia_cache.json") + + +def _load_trivia_cache() -> dict[str, list[str]]: + try: + return json.loads(_TRIVIA_CACHE_FILE.read_text()) + except Exception: + return {} + + +def _save_trivia_cache(cache: dict[str, list[str]]) -> None: + try: + _TRIVIA_CACHE_FILE.write_text(json.dumps(cache, indent=2)) + except Exception as e: + logger.warning("Failed to save trivia cache: %s", e) + + +_trivia_recent: dict[str, list[str]] = _load_trivia_cache() async def _generate_trivia_question(category: str) -> dict | None: @@ -1072,6 +1090,7 @@ async def _generate_trivia_question(category: str) -> dict | None: bucket.append(parsed["q"]) if len(bucket) > _TRIVIA_RECENT_MAX: bucket.pop(0) + _save_trivia_cache(_trivia_recent) return parsed except Exception: pass @@ -1783,9 +1802,26 @@ async def cmd_wyr(client: AsyncClient, room_id: str, sender: str, args: str): # --------------------------------------------------------------------------- _RIDDLE_ACTIVE: dict[str, dict] = {} -_riddle_recent: list[str] = [] # past riddle texts -_riddle_recent_answers: list[str] = [] # past answers (lowercase) _RIDDLE_RECENT_MAX = 30 +_RIDDLE_CACHE_FILE = Path("riddle_cache.json") + + +def _load_riddle_cache() -> tuple[list[str], list[str]]: + try: + data = json.loads(_RIDDLE_CACHE_FILE.read_text()) + return data.get("riddles", []), data.get("answers", []) + except Exception: + return [], [] + + +def _save_riddle_cache(riddles: list[str], answers: list[str]) -> None: + try: + _RIDDLE_CACHE_FILE.write_text(json.dumps({"riddles": riddles, "answers": answers}, indent=2)) + except Exception as e: + logger.warning("Failed to save riddle cache: %s", e) + + +_riddle_recent, _riddle_recent_answers = _load_riddle_cache() async def _generate_riddle() -> dict | None: @@ -1842,6 +1878,7 @@ async def _generate_riddle() -> dict | None: _riddle_recent_answers.append(answer.lower()) if len(_riddle_recent_answers) > _RIDDLE_RECENT_MAX: _riddle_recent_answers.pop(0) + _save_riddle_cache(_riddle_recent, _riddle_recent_answers) return {"riddle": riddle, "answer": answer} except Exception as e: logger.error(f"riddle generation error: {e}", exc_info=True)