新增 iMessage 通道适配器完整实现,包含: 1. 核心适配器与工具工厂导出 2. 运行时存储、反射防护、会话路由等基础组件 3. 消息信封、线程管理、回复上下文格式化 4. Tapback 表情反应处理、自定义异常体系 5. 审批按钮、联系人解析、速率限制功能 6. 文本净化、目标解析、缓存管理模块 7. 配置 schema、多账户支持、安装向导等配置模块 8. 审计日志、媒体AI处理等扩展功能
52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
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")
|