69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
|
|
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)
|