social media crossposting tool. 3rd time's the charm
mastodon
misskey
crossposting
bluesky
1from abc import ABC, abstractmethod
2from pathlib import Path
3import time
4from typing import Generic, TypeVar, override
5import pickle
6
7K = TypeVar("K")
8V = TypeVar("V")
9
10class Cacheable(ABC):
11 @abstractmethod
12 def dump_cache(self, path: Path):
13 pass
14
15 @abstractmethod
16 def load_cache(self, path: Path):
17 pass
18
19class TTLCache(Generic[K, V], Cacheable):
20 def __init__(self, ttl_seconds: int = 3600) -> None:
21 self.ttl: int = ttl_seconds
22 self.__cache: dict[K, tuple[V, float]] = {}
23
24 def get(self, key: K) -> V | None:
25 if key in self.__cache:
26 value, timestamp = self.__cache[key]
27 if time.time() - timestamp < self.ttl:
28 return value
29 else:
30 del self.__cache[key]
31 return None
32
33 def set(self, key: K, value: V) -> None:
34 self.__cache[key] = (value, time.time())
35
36 def clear(self) -> None:
37 self.__cache.clear()
38
39 @override
40 def dump_cache(self, path: Path) -> None:
41 path.parent.mkdir(parents=True, exist_ok=True)
42 with open(path, 'wb') as f:
43 pickle.dump(self.__cache, f)
44
45 @override
46 def load_cache(self, path: Path):
47 if path.exists():
48 with open(path, 'rb') as f:
49 self.__cache = pickle.load(f)