Compare commits

...

3 Commits

Author SHA1 Message Date
Hazel Noack
511401cd51 added cache expiration 2025-06-11 12:05:44 +02:00
Hazel Noack
4c3527e702 add cache db 2025-06-11 11:55:31 +02:00
Hazel Noack
56e77aa861 cache db 2025-06-11 11:50:22 +02:00

View File

@ -1,12 +1,33 @@
from typing import Optional
from codecs import encode from codecs import encode
from hashlib import sha1 from hashlib import sha1
from pathlib import Path from pathlib import Path
import requests import requests
import pickle import pickle
import sqlite3
from datetime import datetime, timedelta
from . import CACHE_DIRECTORY from . import CACHE_DIRECTORY
# SQLite database file path
DB_FILE = Path(CACHE_DIRECTORY, "cache_metadata.db")
# Initialize the database
def _init_db():
with sqlite3.connect(DB_FILE) as conn:
conn.execute("""
CREATE TABLE IF NOT EXISTS url_cache (
url_hash TEXT PRIMARY KEY,
expires_at TIMESTAMP
)
""")
conn.commit()
# Initialize the database when module is imported
_init_db()
def get_url_hash(url: str) -> str: def get_url_hash(url: str) -> str:
return sha1(encode(url.strip(), "utf-8")).hexdigest() return sha1(encode(url.strip(), "utf-8")).hexdigest()
@ -16,7 +37,37 @@ def get_url_file(url: str) -> Path:
def has_cache(url: str) -> bool: def has_cache(url: str) -> bool:
return get_url_file(url).exists() url_hash = get_url_hash(url)
cache_file = get_url_file(url)
if not cache_file.exists():
return False
# Check if the cache has expired
with sqlite3.connect(DB_FILE) as conn:
cursor = conn.cursor()
cursor.execute(
"SELECT expires_at FROM url_cache WHERE url_hash = ?",
(url_hash,)
)
result = cursor.fetchone()
if result is None:
return False # No expiration record exists
expires_at = datetime.fromisoformat(result[0])
if datetime.now() > expires_at:
# Cache expired, clean it up
cache_file.unlink(missing_ok=True)
cursor.execute(
"DELETE FROM url_cache WHERE url_hash = ?",
(url_hash,)
)
conn.commit()
return False
return True
def get_cache(url: str) -> requests.Response: def get_cache(url: str) -> requests.Response:
@ -24,6 +75,27 @@ def get_cache(url: str) -> requests.Response:
return pickle.load(cache_file) return pickle.load(cache_file)
def write_cache(url: str, resp: requests.Response): def write_cache(
url: str,
resp: requests.Response,
expires_after: Optional[timedelta] = None
):
url_hash = get_url_hash(url)
# Default expiration: 24 hours from now
if expires_after is None:
expires_after = timedelta(hours=1)
expires_at = datetime.now() + expires_after
# Write the cache file
with get_url_file(url).open("wb") as url_file: with get_url_file(url).open("wb") as url_file:
pickle.dump(resp, url_file) pickle.dump(resp, url_file)
# Update the database
with sqlite3.connect(DB_FILE) as conn:
conn.execute(
"INSERT OR REPLACE INTO url_cache (url_hash, expires_at) VALUES (?, ?)",
(url_hash, expires_at.isoformat())
)
conn.commit()