68 lines
1.9 KiB
Python
68 lines
1.9 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import time
|
||
|
|
from dataclasses import dataclass, field
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass
|
||
|
|
class SentMessageEntry:
|
||
|
|
message_id: str
|
||
|
|
chat_id: str
|
||
|
|
text: str
|
||
|
|
sent_at: float
|
||
|
|
status: str = "sent"
|
||
|
|
metadata: dict[str, Any] = field(default_factory=dict)
|
||
|
|
|
||
|
|
|
||
|
|
class SentMessageCache:
|
||
|
|
MAX_ENTRIES = 500
|
||
|
|
TTL_SECONDS = 3600
|
||
|
|
|
||
|
|
def __init__(self, max_entries: int = MAX_ENTRIES):
|
||
|
|
self._entries: dict[str, SentMessageEntry] = {}
|
||
|
|
self._max_entries = max_entries
|
||
|
|
|
||
|
|
def put(self, message_id: str, chat_id: str, text: str, metadata: dict[str, Any] | None = None) -> None:
|
||
|
|
self._evict_if_needed()
|
||
|
|
self._entries[message_id] = SentMessageEntry(
|
||
|
|
message_id=message_id,
|
||
|
|
chat_id=chat_id,
|
||
|
|
text=text,
|
||
|
|
sent_at=time.monotonic(),
|
||
|
|
metadata=metadata or {},
|
||
|
|
)
|
||
|
|
|
||
|
|
def get(self, message_id: str) -> SentMessageEntry | None:
|
||
|
|
entry = self._entries.get(message_id)
|
||
|
|
if entry is None:
|
||
|
|
return None
|
||
|
|
if time.monotonic() - entry.sent_at > self.TTL_SECONDS:
|
||
|
|
del self._entries[message_id]
|
||
|
|
return None
|
||
|
|
return entry
|
||
|
|
|
||
|
|
def update_status(self, message_id: str, status: str) -> bool:
|
||
|
|
entry = self._entries.get(message_id)
|
||
|
|
if entry is None:
|
||
|
|
return False
|
||
|
|
entry.status = status
|
||
|
|
return True
|
||
|
|
|
||
|
|
def remove(self, message_id: str) -> bool:
|
||
|
|
if message_id in self._entries:
|
||
|
|
del self._entries[message_id]
|
||
|
|
return True
|
||
|
|
return False
|
||
|
|
|
||
|
|
def clear(self) -> None:
|
||
|
|
self._entries.clear()
|
||
|
|
|
||
|
|
def size(self) -> int:
|
||
|
|
return len(self._entries)
|
||
|
|
|
||
|
|
def _evict_if_needed(self) -> None:
|
||
|
|
while len(self._entries) >= self._max_entries:
|
||
|
|
oldest_key = next(iter(self._entries))
|
||
|
|
del self._entries[oldest_key]
|