social media crossposting tool. 3rd time's the charm
mastodon misskey crossposting bluesky
at next 1.3 kB view raw
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)