"""Cleanup old posts that did not have any interactions""" # ----- imports ----- # from os import getenv from dotenv import load_dotenv from mastodon import Mastodon, MastodonRatelimitError def cleanup(offset: int = 200, num_batches: int = 10, limit: int = 40, start_id: int | None = None): """Delete old posts without any interactions. Args: offset (int, optional): After how many posts should the function start. Defaults to 200. limit (int, optional): Size of posts batches. Defaults to 40. id (int | None, optional): Post ID from where to start cleanup. If this value is set, the offset will be ignored. Defaults to None. """ # ----- initialization ----- # # load .env load_dotenv() # initialize mastodon mastodon = Mastodon( access_token = getenv("MASTODON_USER_SECRET"), api_base_url = getenv("MASTODON_URL"), ratelimit_method="throw" ) # ----- go *limit* posts into the past, if manual id is not set ----- # def get_account_statuses(max_id: int, limit: int = 40) -> list: if id_oldest_of_last_posts == -1: return mastodon.account_statuses(getenv("MASTODON_USER_ID"), exclude_replies=True, limit=limit) else: return mastodon.account_statuses(getenv("MASTODON_USER_ID"), exclude_replies=True, max_id=max_id, limit=limit) if start_id is None: last_posts = [] id_oldest_of_last_posts = -1 iterations = offset // 40 remainder = offset % 40 # get latest posts until offset is reached for i in range(iterations): last_posts = get_account_statuses(max_id=id_oldest_of_last_posts, limit=40) if len(last_posts) == 0: print("Offset is higher than the number of posts in the past.") return id_oldest_of_last_posts = last_posts[-1]["id"] print(f"Currently at offset {(i + 1) * 40}, last ignored post: {last_posts[-1]['url']}") if remainder != 0: last_posts = get_account_statuses(max_id=id_oldest_of_last_posts, limit=remainder) if len(last_posts) == 0: print("Offset is higher than the number of posts in the past.") return id_oldest_of_last_posts = last_posts[-1]["id"] print(f"Currently at offset {iterations * 40 + remainder}, last ignored post: {last_posts[-1]['url']}") else: id_oldest_of_last_posts = start_id last_posts = mastodon.account_statuses(getenv("MASTODON_USER_ID"), exclude_replies=True, max_id=start_id, limit=limit) # return if there are no posts to check if len(last_posts) == 0: print("There are no older posts than the given id.") return # ----- delete old inactive posts ----- # # default: check 10 batches of 40 posts # this usually tries until the rate limit is triggered or there are no more posts # if hitting the rate limit is undesired, reduce the number of iterations for i in range(num_batches): # skip getting new batch in the first iteration if the id was set manually if i != 0 or start_id is None: # find id of the currently oldest post last_post = last_posts[-1] if last_post["favourites_count"] != 0 or last_post["reblogs_count"] != 0 or last_post["replies_count"] != 0: id_oldest_of_last_posts = last_post["id"] # get next batch of posts last_posts = mastodon.account_statuses(getenv("MASTODON_USER_ID"), exclude_replies=True, max_id=id_oldest_of_last_posts, limit=limit) # return if there are no more posts to check if len(last_posts) == 0: return # delete all old posts of the current batch for submission in last_posts: # if post has no favorites, boosts or replies, delete it if submission["favourites_count"] == 0 and submission["reblogs_count"] == 0 and submission["replies_count"] == 0: print("Deleting post:", submission["url"]) try: mastodon.status_delete(submission["id"]) except MastodonRatelimitError: print("Hit rate limit while trying to delete post:", submission["url"]) return else: print("Ignoring post:", submission["url"]) if __name__ == "__main__": cleanup(offset=100, num_batches=10, limit=40, start_id=None)