social media crossposting tool. 3rd time's the charm
mastodon misskey crossposting bluesky
at next 42 lines 1.1 kB view raw
1from dataclasses import dataclass, field 2from typing import TypeVar 3 4from cross.attachments import Attachment 5from cross.tokens import Token 6 7 8T = TypeVar("T", bound=Attachment) 9 10 11class AttachmentKeeper: 12 def __init__(self) -> None: 13 self._map: dict[type, Attachment] = {} 14 15 def put(self, attachment: Attachment) -> None: 16 self._map[attachment.__class__] = attachment 17 18 def get(self, cls: type[T]) -> T | None: 19 instance = self._map.get(cls) 20 if instance is None: 21 return None 22 if not isinstance(instance, cls): 23 raise TypeError(f"Expected {cls.__name__}, got {type(instance).__name__}") 24 return instance 25 26 def __repr__(self) -> str: 27 return f"AttachmentKeeper(_map={self._map.values()})" 28 29 30@dataclass(kw_only=True) 31class PostRef: 32 id: str 33 author: str 34 service: str 35 36 37@dataclass(kw_only=True) 38class Post(PostRef): 39 parent_id: str | None 40 tokens: list[Token] 41 text_type: str = "text/plain" 42 attachments: AttachmentKeeper = field(default_factory=AttachmentKeeper)