social media crossposting tool. 3rd time's the charm
mastodon
misskey
crossposting
bluesky
1from dataclasses import dataclass
2from pathlib import Path
3from typing import Any, override
4
5from cross.service import OutputService
6from mastodon.info import InstanceInfo, MastodonService
7from util.util import LOGGER
8
9ALLOWED_POSTING_VISIBILITY: list[str] = ["public", "unlisted", "private"]
10
11
12@dataclass(kw_only=True)
13class MastodonOutputOptions:
14 token: str
15 instance: str
16 visibility: str = "public"
17
18 @classmethod
19 def from_dict(cls, data: dict[str, Any]) -> "MastodonOutputOptions":
20 data["instance"] = (
21 data["instance"][:-1]
22 if data["instance"].endswith("/")
23 else data["instance"]
24 )
25
26 if "visibility" in data:
27 if data["visibility"] not in ALLOWED_POSTING_VISIBILITY:
28 raise ValueError(f"Invalid visibility option {data['visibility']}!")
29
30 return MastodonOutputOptions(**data)
31
32
33# TODO
34class MastodonOutputService(MastodonService, OutputService):
35 def __init__(self, db: Path, options: MastodonOutputOptions) -> None:
36 super().__init__(options.instance, db)
37 self.options: MastodonOutputOptions = options
38
39 LOGGER.info("Verifying %s credentails...", self.url)
40 responce = self.verify_credentials()
41 self.user_id: str = responce["id"]
42
43 LOGGER.info("Getting %s configuration...", self.url)
44 responce = self.fetch_instance_info()
45 self.instance_info = InstanceInfo.from_api(responce)
46
47 @override
48 def _get_token(self) -> str:
49 return self.options.token