diff --git a/arte_api.py b/arte_api.py index 1acde61..93a516d 100644 --- a/arte_api.py +++ b/arte_api.py @@ -1,4 +1,5 @@ import re +import sqlite3 import time import logging import asyncio @@ -11,8 +12,51 @@ import tmdb as _tmdb logger = logging.getLogger(__name__) CACHE_TTL = 6 * 3600 +DB_PATH = "arte_dl.db" _cache: dict = {"data": [], "ts": 0} + +def _db(): + conn = sqlite3.connect(DB_PATH) + conn.row_factory = sqlite3.Row + return conn + + +def _init_concerts_cache_table(): + with _db() as conn: + conn.execute(""" + CREATE TABLE IF NOT EXISTS concerts_cache ( + id INTEGER PRIMARY KEY CHECK (id = 1), + data TEXT NOT NULL, + ts REAL NOT NULL + ) + """) + + +_init_concerts_cache_table() + + +def _load_db_cache() -> tuple[list, float]: + try: + with _db() as conn: + row = conn.execute("SELECT data, ts FROM concerts_cache WHERE id=1").fetchone() + if row: + return json.loads(row["data"]), row["ts"] + except Exception: + pass + return [], 0.0 + + +def _save_db_cache(data: list, ts: float): + try: + with _db() as conn: + conn.execute( + "INSERT OR REPLACE INTO concerts_cache (id, data, ts) VALUES (1, ?, ?)", + (json.dumps(data), ts), + ) + except Exception as e: + logger.warning("Failed to save concerts cache: %s", e) + PLAYER_API = "https://api.arte.tv/api/player/v2/config/fr/{pid}" SEARCH_URL = "https://www.arte.tv/fr/search/?q={q}" @@ -157,11 +201,21 @@ async def get_all_concerts() -> list[dict]: now = time.time() if _cache["data"] and now - _cache["ts"] < CACHE_TTL: return _cache["data"] + + # Try SQLite cache before hitting the network + db_data, db_ts = _load_db_cache() + if db_data and now - db_ts < CACHE_TTL: + logger.info("Concerts cache loaded from DB (%d concerts)", len(db_data)) + _cache["data"] = db_data + _cache["ts"] = db_ts + return _cache["data"] + loop = asyncio.get_event_loop() data = await loop.run_in_executor(None, _fetch_all_sync) if data: _cache["data"] = data _cache["ts"] = now + _save_db_cache(data, now) return _cache["data"] @@ -208,5 +262,10 @@ async def fetch_concerts(page: int = 1, search: str = "", page_size: int = 24, c async def invalidate_cache() -> int: _cache["ts"] = 0 + try: + with _db() as conn: + conn.execute("DELETE FROM concerts_cache") + except Exception: + pass data = await get_all_concerts() return len(data)