Spaces:
Sleeping
Sleeping
| # services/cache.py | |
| import os, json, time, sqlite3, threading | |
| _DB_PATH = os.path.join(os.path.dirname(__file__), "..", "newsintel_cache.sqlite") | |
| _LOCK = threading.Lock() | |
| def _connect(): | |
| os.makedirs(os.path.dirname(_DB_PATH), exist_ok=True) | |
| conn = sqlite3.connect(_DB_PATH) | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS cache ( | |
| cache_key TEXT PRIMARY KEY, | |
| ts REAL NOT NULL, | |
| payload TEXT NOT NULL | |
| ) | |
| """) | |
| return conn | |
| def _key_for(*parts): | |
| return "|".join(str(p).strip().lower() for p in parts) | |
| def get_cache(*key_parts, max_age_sec=86400): | |
| """Return cached JSON (as dict) if not expired; else None.""" | |
| key = _key_for(*key_parts) | |
| with _LOCK: | |
| conn = _connect() | |
| try: | |
| row = conn.execute("SELECT ts, payload FROM cache WHERE cache_key=?", (key,)).fetchone() | |
| if not row: | |
| return None | |
| ts, payload = row | |
| if (time.time() - ts) > max_age_sec: | |
| return None | |
| return json.loads(payload) | |
| finally: | |
| conn.close() | |
| def set_cache(payload_obj, *key_parts): | |
| key = _key_for(*key_parts) | |
| blob = json.dumps(payload_obj, ensure_ascii=False) | |
| with _LOCK: | |
| conn = _connect() | |
| try: | |
| conn.execute( | |
| "REPLACE INTO cache (cache_key, ts, payload) VALUES (?, ?, ?)", | |
| (key, time.time(), blob) | |
| ) | |
| conn.commit() | |
| finally: | |
| conn.close() | |