ticketfrei/mastodonbot.py

98 lines
2.9 KiB
Python
Raw Normal View History

2017-06-17 18:49:30 +00:00
#!/usr/bin/env python3
2018-03-24 15:26:35 +00:00
import logging
2017-06-17 18:49:30 +00:00
import mastodon
import re
import report
from user import User
2017-06-17 18:49:30 +00:00
2018-03-24 15:26:35 +00:00
logger = logging.getLogger(__name__)
class MastodonBot(object):
2018-03-24 15:26:35 +00:00
def __init__(self, uid, db):
self.user = User(db, uid)
2018-03-24 15:26:35 +00:00
client_id, client_secret, access_token, instance_url = \
self.user.get_masto_credentials()
self.m = mastodon.Mastodon(
client_id=client_id,
client_secret=client_secret,
access_token=access_token,
api_base_url=instance_url
)
2017-06-17 18:49:30 +00:00
# load state
try:
self.seen_toots = self.user.get_seen_toot()
except TypeError:
self.seen_toots = 0
2017-06-17 18:49:30 +00:00
def save_last(self):
self.user.save_seen_toot(self.seen_toots)
def crawl(self):
"""
Crawl mentions from Mastodon.
:return: list of statuses
"""
mentions = []
try:
notifications = self.m.notifications()
except: # mastodon.Mastodon.MastodonAPIError is unfortunately not in __init__.py
2018-03-24 15:26:35 +00:00
logger.error("Unknown Mastodon API Error.", exc_info=True)
return mentions
for status in notifications:
2018-03-24 15:26:35 +00:00
if (status['type'] == 'mention' and
status['status']['id'] > self.seen_toots):
# save state
self.seen_toots = status['status']['id']
self.save_last()
# add mention to mentions
text = re.sub(r'<[^>]*>', '', status['status']['content'])
2018-03-24 15:26:35 +00:00
text = re.sub(
"(?<=^|(?<=[^a-zA-Z0-9-_.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
"", text)
mentions.append(report.Report(status['account']['acct'],
"mastodon",
text,
status['status']['id'],
status['status']['created_at']))
return mentions
def repost(self, mention):
"""
Retoots a mention.
:param mention: (report.Report object)
"""
2018-03-24 15:26:35 +00:00
logger.info('Boosting toot from %s' % (
mention.format()))
self.m.status_reblog(mention.id)
def post(self, report):
"""
Toots a report from other sources.
:param report: (report.Report object)
"""
toot = report.format()
self.m.toot(toot)
def flow(self, trigger, reports=()):
2017-06-17 18:49:30 +00:00
# toot external provided messages
for report in reports:
self.post(report)
2017-06-17 18:49:30 +00:00
# boost mentions
retoots = []
for mention in self.crawl():
if not trigger.is_ok(mention.text):
continue
self.repost(mention)
retoots.append(mention)
2017-06-17 18:49:30 +00:00
# return mentions for mirroring
return retoots