blastodon/blastodon/client/client.py

56 lines
2 KiB
Python

from typing import Self
from pathlib import Path
from atproto import Client as BskyClient
from mastodon import Mastodon, MastodonError
import magic
from blastodon import auth
from blastodon.client import RetreivedPost, CreatedPost
class Client:
"""A wrapper around both Mastodon and Bsky clients"""
mastodon: Mastodon
bsky: BskyClient
def __init__(self, mastodon: Mastodon, bsky: BskyClient):
self.mastodon = mastodon
self.bsky = bsky
@classmethod
def init_cli(cls) -> Self:
return cls(
mastodon=auth.cli.auth_mastodon(),
bsky=auth.cli.auth_bsky()
)
def most_recent_posts(self) -> RetreivedPost:
return RetreivedPost.most_recent(client=self)
def send_text_post(self, text: str):
bsky_post = self.bsky.send_post(text=text)
try:
mastodon_post = self.mastodon.status_post(status=text)
except MastodonError as err:
print('error posting to mastodon after posting to bsky. Deleting bsky post.')
self.bsky.delete_post(bsky_post.uri)
raise err
return CreatedPost(bsky=bsky_post, mastodon=mastodon_post)
def send_image_post(self, post_text: str, image_path: Path | str, alt_text: str):
with open(image_path, mode='rb') as file:
image = file.read()
bsky_post = self.bsky.send_image(text=post_text, image=image, image_alt=alt_text)
try:
mime = magic.from_buffer(image, mime=True)
media_upload = self.mastodon.media_post(media_file=image, mime_type=mime, description=alt_text)
mastodon_post = self.mastodon.status_post(status=post_text, media_ids=[media_upload.id])
except MastodonError as err:
print('error posting to mastodon after posting to bsky. Deleting bsky post.')
self.bsky.delete_post(bsky_post.uri)
raise err
mastodon_post.url
return CreatedPost(bsky=bsky_post, mastodon=mastodon_post)