class Tooter(Mastodon):
credentials: dict = {}
hostname: str = ''
files: dict = {}
def __init__(self, config, phase: str, server: str = ''):
self.debug = config.getint(phase, 'debug')
self.logger = logging.getLogger('tooter')
logging.basicConfig(format='%(levelname)s\t%(message)s')
self.logger.setLevel(self.debug)
if server != "":
self.logger.debug(f"Connecting to {server} anonymously")
super().__init__(
user_agent="mastoscore",
debug_requests=False,
feature_set="pleroma",
request_timeout=10,
api_base_url=server,
)
self.logger.info(f"Connected to {self.api_base_url} (anonymous)")
else:
self.cred_file = config.get(phase, 'cred_file')
self.name = config.get(phase, 'botusername')
self.acct = self.name
self.logger.debug(
f"Logging into {self.name} from {self.cred_file}")
super().__init__(
access_token=self.cred_file,
user_agent="mastoscore",
debug_requests=False,
feature_set="pleroma",
request_timeout=10,
)
account = self.me()
self.id = account['id']
self.logger.info(
f"Logged in as {account.username} on {self.api_base_url} (uid {account.id})")
def check_toot_ages(self, tootlist, interval=datetime.timedelta):
returnlist = []
oldest_date = datetime.datetime.utcnow() - interval
for toot in tootlist:
tootdate = toot['created_at']
if tootdate > oldest_date.astimezone(datetime.timezone.utc):
returnlist.append(toot)
return returnlist
def search_hashtag(self, hashtag=str, interval=datetime.timedelta, max=2000):
''' Given a hashtag, search the public timeline for that hashtag. Return only
the toots that are in the given interval. E.g., if interval is 7 days,
count back 7 days from right now, and return only toots on the hashtag
since that moment.
'''
toots = []
# According to https://docs.joinmastodon.org/methods/timelines/#tag
# max page size, by default, is 40
if max < 40:
pagesize = max
else:
pagesize = 40
page = self.timeline_hashtag(hashtag, limit=pagesize)
# page = self.timeline_public(limit=pagesize)
if len(page) == 0:
self.logger.debug(f"No toots found for hashtag: {hashtag}")
return toots
# Keep fetching toots until we get to one that is older than the interval
# or we get to the end.
while (len(page) > 0 and len(toots) < max):
# check to see if we have reached the oldest allowable toot
toots_to_keep = self.check_toot_ages(page, interval)
toots = toots + toots_to_keep
self.logger.info(
f"Added {len(toots_to_keep)} more toots, {len(toots)} total")
# if the check ages function returns fewer than we sent to it
# we have hit the end of the list of toots
if len(toots_to_keep) < len(page):
self.logger.debug("stopping due to age")
return toots
self.logger.debug(f"Requesting {pagesize} more toots")
page = self.fetch_next(page)
# According to https://docs.joinmastodon.org/api/rate-limits/#per-ip
# the rate limit is 300 calls in 5 minutes. If we have 2000 toots we have
# to fetch in pages of 40, that's 50 API calls + some authentication calls
if len(toots) > max:
# process what we just got and stop
toots_to_keep = self.check_toot_ages(page, interval)
toots = toots + toots_to_keep
self.logger.debug(
f"More than {max} toots. (We got {len(toots)}). Stopping")
break
return toots