ForcePilot/backend/package/yuxi/channels/adapters/nostr/send_cache.py

69 lines
2.2 KiB
Python
Raw Normal View History

from __future__ import annotations
import time
from collections import OrderedDict
from dataclasses import dataclass, field
@dataclass
class SendCacheEntry:
event_id: str
content: str = ""
status: str = "sent"
timestamp: float = field(default_factory=time.time)
class SendCache:
def __init__(self, max_size: int = 100):
self._max_size = max_size
self._store: OrderedDict[str, SendCacheEntry] = OrderedDict()
def record(self, event_id: str, content: str = "", status: str = "sent") -> None:
if event_id in self._store:
self._store.move_to_end(event_id)
self._store[event_id].status = status
self._store[event_id].timestamp = time.time()
return
self._store[event_id] = SendCacheEntry(event_id=event_id, content=content[:200], status=status)
while len(self._store) > self._max_size:
self._store.popitem(last=False)
def update_status(self, event_id: str, status: str) -> None:
entry = self._store.get(event_id)
if entry:
entry.status = status
def get(self, event_id: str) -> SendCacheEntry | None:
return self._store.get(event_id)
def list_recent(self, limit: int = 10) -> list[SendCacheEntry]:
return list(self._store.values())[-limit:]
def to_dict_list(self) -> list[dict]:
return [
{
"event_id": e.event_id,
"content": e.content[:100],
"status": e.status,
"timestamp": e.timestamp,
}
for e in reversed(list(self._store.values()))
][: self._max_size]
@classmethod
def from_dict_list(cls, entries: list[dict], max_size: int = 100) -> SendCache:
cache = cls(max_size=max_size)
for entry in entries:
eid = entry.get("event_id", "")
if eid:
cache._store[eid] = SendCacheEntry(
event_id=eid,
content=entry.get("content", ""),
status=entry.get("status", "sent"),
timestamp=entry.get("timestamp", time.time()),
)
return cache
def __len__(self) -> int:
return len(self._store)