ForcePilot/backend/package/yuxi/channel/extensions/dingtalk/file_cache.py
Kris 472afc4d1e feat(dingtalk): 新增钉钉渠道插件完整实现
该提交实现了完整的钉钉聊天渠道插件,包含:
1. 基础配置、账号管理与凭证校验
2. WebSocket长连接网关与消息去重
3. 消息接收/解析/分发与安全校验
4. 媒体文件上传下载与缓存
5. 互动卡片流式更新与回调处理
6. 群管理、命令支持与诊断工具
7. 完整的插件元数据与依赖声明
2026-05-21 10:44:03 +08:00

41 lines
1.1 KiB
Python

from __future__ import annotations
import logging
import time
from collections import OrderedDict
logger = logging.getLogger(__name__)
DEFAULT_TTL_SECONDS = 120
class FileCacheEntry:
__slots__ = ("file_path", "cached_at")
def __init__(self, file_path: str):
self.file_path = file_path
self.cached_at = time.monotonic()
class FileCache:
def __init__(self, ttl_seconds: int = DEFAULT_TTL_SECONDS):
self._ttl = ttl_seconds
self._entries: OrderedDict[str, FileCacheEntry] = OrderedDict()
def add(self, session_key: str, file_path: str) -> None:
self._evict_expired()
self._entries[session_key] = FileCacheEntry(file_path)
def get(self, session_key: str) -> FileCacheEntry | None:
self._evict_expired()
return self._entries.get(session_key)
def clear(self, session_key: str) -> None:
self._entries.pop(session_key, None)
def _evict_expired(self) -> None:
now = time.monotonic()
expired = [k for k, v in self._entries.items() if now - v.cached_at > self._ttl]
for k in expired:
self._entries.pop(k, None)