masto-bridges/masto_git_bridge/bot.py

107 lines
3.3 KiB
Python
Raw Normal View History

2022-11-08 06:13:05 +00:00
import pdb
2022-11-08 03:13:35 +00:00
from typing import Optional
from datetime import datetime
from masto_git_bridge.config import Config
2022-11-08 06:13:05 +00:00
from masto_git_bridge.models import Account, List
from masto_git_bridge.post import Post, Status
from masto_git_bridge.logger import init_logger
from masto_git_bridge.repo import Repo
2022-11-08 03:13:35 +00:00
from mastodon import Mastodon, StreamListener
class Listener(StreamListener):
def __init__(self, client: Mastodon, config:Optional[Config]=None):
2022-11-08 06:13:05 +00:00
super(Listener, self).__init__()
2022-11-08 03:13:35 +00:00
self.client = client
if config is None:
config = Config()
self.config = config
2022-11-08 06:13:05 +00:00
self.logger = init_logger('mastogit_bot-stream', basedir=self.config.LOGDIR)
self.repo = Repo(path=config.GIT_REPO)
def on_update(self, status:dict):
status = Status(**status)
if status.visibility in ('private', 'direct'):
# not xposting dms
self.logger.info('Not xposting private messages')
return
post = Post.from_status(status)
if post.text.startswith('xpost'):
self.logger.info('Not xposting an xpost')
return
success = self.repo.post(post.format_commit())
if success:
self.logger.info('Posted to git!')
else:
self.logger.exception('Failed to post to git!')
2022-11-08 03:13:35 +00:00
class Bot:
2022-11-08 06:13:05 +00:00
def __init__(self, config:Optional[Config]=None, post_length=500):
2022-11-08 03:13:35 +00:00
self._me = None # type: Optional[Account]
2022-11-08 06:13:05 +00:00
self._me_list = None # type: Optional[List]
2022-11-08 03:13:35 +00:00
if config is None:
config = Config()
self.config = config
self.config.LOGDIR.mkdir(exist_ok=True)
2022-11-08 06:13:05 +00:00
self.post_length = post_length
self.logger = init_logger('mastogit_bot', basedir=self.config.LOGDIR)
2022-11-08 03:13:35 +00:00
self.client = Mastodon(
access_token=self.config.MASTO_TOKEN,
api_base_url=self.config.MASTO_URL
)
2022-11-08 06:13:05 +00:00
def init_stream(self, run_async:bool=True):
# Listen to a stream consisting of just us.
listener = Listener(client=self.client, config=self.config)
self.logger.info('Initializing streaming')
self.client.stream_list(
self.me_list.id,
listener = listener,
run_async=run_async
)
def post(self, post:str):
# TODO: Split long posts
if len(post)>self.post_length:
raise NotImplementedError(f"Cant split long posts yet, got post of length {len(post)} when max length is {self.post_length}")
self.client.status_post(post)
self.logger.info(f"Posted:\n{post}")
2022-11-08 03:13:35 +00:00
@property
def me(self) -> Account:
if self._me is None:
self._me = Account(**self.client.me())
return self._me
2022-11-08 06:13:05 +00:00
def _make_me_list(self) -> List:
me_list = List(**self.client.list_create('me'))
self.client.list_accounts_add(me_list.id, [self.me.id])
self.logger.info('Created list with just me in it!')
return me_list
2022-11-08 03:13:35 +00:00
2022-11-08 06:13:05 +00:00
@property
def me_list(self) -> List:
if self._me_list is None:
lists = self.client.lists()
me_list = [l for l in lists if l.get('title', '') == 'me']
if len(me_list)>0:
self._me_list = List(**me_list[0])
else:
self._me_list = self._make_me_list()
return self._me_list