#!/usr/bin/python3.8 import sys import os import re import argparse import time import json import requests parent = os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(os.path.join(parent, 'config.json')): generate_config("Wardyn's feditools", "read write follow push") with open(os.path.join(parent, 'config.json'), 'r') as config_file: config = json.load(config_file) session = requests.Session() session.headers.update({"Authorization" : "Bearer " + config['user_token']}) parser = argparse.ArgumentParser(description='Remove follow requests that match the following filters:\n1: Has less than n (defaults to 1) posts\n2: Has no profile picture\n3: Has no bio\n', formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('-t', '--threshold', action='store', type=int, help='The amount of filters the request has to pass to not be automatically declined, defaults to 1 (setting this to a number higher than the amount of availible filters will deny every request in the list)', default=1, dest='threshold' ) parser.add_argument('-i', '--instances', action='store', type=str, help='block follow requests from these instances (comma seperated list)', default=None, dest='instances' ) parser.add_argument('-b', '--blank', action='store', type=str, default=None, help='If your instance has a custom image for blank pfps set, please specify the url to the image with this flag', dest='custompfp' ) parser.add_argument('-p', '--posts', action='store', type=int, help='The minimum number of posts a user must have to pass the posts filter (does not include boosts), defaults to 1', default=1, dest='minposts' ) parser.add_argument('-y', '--yes', action='store_const', const=True, help='Skips asking for confirmation before denying requests, use this if you want to automate this script.', default=False, dest='auto' ) parser.add_argument('-s', '--simulate', action='store_const', const=True, help='Simulates the process without modifying anything', default=False, dest='simulate' ) parser.add_argument('-a', '--accept', action='store_const', const=True, help='Automatically accept requests that arent rejected', default=False, dest='accept' ) parser.add_argument('-l', '--loop', action='store', type=int, help='Loop command every x hours', default=None, dest='loop' ) args = parser.parse_args() threshold = args.threshold minposts = args.minposts auto = args.auto simulate = args.simulate accept= args.accept loop = args.loop instances = args.instances custompfp = args.custompfp if instances is not None: instances = instances.split(", ") if type(loop) == int: loop = loop * 60 * 60 blanks = [config['instance'] + '/avatars/original/missing.png', config['instance'] + '/images/avi.png'] if custompfp: blanks.append(custompfp) def filterposts(min, follow_request): posts = follow_request['statuses_count'] if posts >= min: return(True) else: return(False) def filterbio(follow_request): if follow_request['note'] == '

': return(False) else: return(True) def filterpfp(follow_request): if follow_request['avatar'] in blanks: return(False) else: return(True) while True: denied=[] accepted=[] follow_requests = session.get(config['instance'] + '/api/v1/follow_requests', params={'limit':80}).json() if len(follow_requests) > 0: for follow_request in follow_requests: postcheck = filterposts(minposts, follow_request) pfpcheck = filterpfp(follow_request) biocheck = filterbio(follow_request) following = session.get(config['instance'] + '/api/v1/accounts/relationships', params={'id':follow_request['id']}).json()[0]['following'] blockedinstance = False if instances is not None: blockedinstance = follow_request['fqn'].split('@')[-1] in instances if postcheck + biocheck + pfpcheck < threshold and following == False or blockedinstance == True: denied.append(follow_request) elif accept == True: accepted.append(follow_request) print('DENIED: ') for follow_request in denied: print(follow_request['fqn']) confirm = None if auto == False: while True: confirm = input('Deny these requests? (y/n): ') if confirm == 'n': pass elif not confirm == 'y': print('Not recognized, try again') continue break if auto == True or confirm == 'y': for follow_request in denied: if simulate: print('This is where ' + follow_request['fqn'] + ' would be rejected') else: session.post(config['instance'] + '/api/v1/follow_requests/' + follow_request['id'] + '/reject') for follow_request in accepted: if simulate: print('This is where ' + follow_request['fqn'] + ' would be accepted') else: session.post(config['instance'] + '/api/v1/follow_requests/' + follow_request['id'] + '/authorize') if loop == None: break else: time.sleep(loop)