ForcePilot/backend/package/yuxi/channels/adapters/imessage/sticker_cache.py

52 lines
1.8 KiB
Python
Raw Normal View History

from __future__ import annotations
import json
import time
from pathlib import Path
from typing import Any
class StickerCache:
def __init__(self, cache_dir: str | None = None, max_entries: int = 500):
self._cache_dir = Path(cache_dir or str(Path.home() / ".yuxi" / "imessage" / "stickers"))
self._max_entries = max_entries
self._index: dict[str, dict[str, Any]] = {}
self._cache_dir.mkdir(parents=True, exist_ok=True)
self._load_index()
def add(self, sticker_id: str, url: str, metadata: dict[str, Any] | None = None) -> None:
entry = {
"sticker_id": sticker_id,
"url": url,
"metadata": metadata or {},
"cached_at": time.time(),
}
self._index[sticker_id] = entry
if len(self._index) > self._max_entries:
oldest = min(self._index.values(), key=lambda e: e["cached_at"])
self._index.pop(oldest["sticker_id"], None)
self._save_index()
def get(self, sticker_id: str) -> dict[str, Any] | None:
return self._index.get(sticker_id)
def get_url(self, sticker_id: str) -> str | None:
entry = self._index.get(sticker_id)
return entry["url"] if entry else None
def clear(self) -> None:
self._index.clear()
self._save_index()
def _load_index(self) -> None:
index_path = self._cache_dir / "sticker_index.json"
if index_path.exists():
try:
self._index = json.loads(index_path.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError):
self._index = {}
def _save_index(self) -> None:
index_path = self._cache_dir / "sticker_index.json"
index_path.write_text(json.dumps(self._index, ensure_ascii=False, indent=2), encoding="utf-8")