Created
May 12, 2012 15:19
-
-
Save aperson/2667143 to your computer and use it in GitHub Desktop.
Python script to remove shadowbanned and stagnant user from a subreddit's ban list.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin env python3 | |
import json | |
import urllib.request | |
import time | |
import sys | |
import signal | |
from urllib.parse import urlencode | |
import http.cookiejar | |
def sigint_handler(signal, frame): | |
'''Handles ^c''' | |
print('Recieved SIGINT! Exiting...') | |
sys.exit(0) | |
class Reddit(object): | |
"""Base class to perform the tasks of a redditor.""" | |
def __init__(self, username, password): | |
self.username = username | |
self.password = password | |
self.cj = http.cookiejar.CookieJar() | |
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cj)) | |
self.opener.addheaders = [('User-agent', 'prune_bans.py')] | |
self._login() | |
def _request(self, url, body=None): | |
if body is not None: | |
body = urlencode(body).encode('utf-8') | |
with self.opener.open(url, data=body) as w: | |
time.sleep(2) | |
return json.loads(w.read().decode('utf-8')) | |
def _login(self): | |
print("Logging in as {}.".format(self.username)) | |
body = {'user' :self.username, 'passwd' : self.password, 'api_type' : 'json'} | |
resp = self._request('https://www.reddit.com/api/login', body) | |
self.modhash = resp['json']['data']['modhash'] | |
def post(self, url, body): | |
"""Sends a POST to the url and returns the json as a dict.""" | |
if 'api_type' not in body: body['api_type'] = 'json' | |
body['uh'] = self.modhash | |
return self._request(url, body) | |
def get(self, url): | |
if not url.endswith('.json'): url += '.json' | |
return self._request(url) | |
def process_subreddit(redditor, subreddit, months=None): | |
print("Processing the bans in {}.".format(subreddit)) | |
processed = 0 | |
found = 0 | |
r = redditor | |
banned_list = r.get('http://www.reddit.com/r/{}/about/banned/'.format(subreddit)) | |
try: | |
with open('banned_list.json') as f: | |
cache = json.loads(f.read()) | |
except IOError: | |
cache = dict() | |
for i in banned_list['data']['children']: | |
found += 1 | |
if i['name'] not in cache: | |
print('Getting info on: ' + i['name']) | |
try: | |
u = r.get('http://www.reddit.com/user/' + i['name']) | |
# since they're not banned, we'll cache the last activity time | |
data = u['data']['children'] | |
if data: | |
cache[i['name']] = data[0]['data']['created_utc'] | |
else: | |
cache[i['name']] = 0 | |
except urllib.error.HTTPError: | |
# since they are banned, we'll just add that as such | |
cache[i['name']] = 'banned' | |
finally: | |
with open('banned_list.json', 'w') as f: | |
f.write(json.dumps(cache)) | |
if cache[i['name']] == 'banned': | |
print("{} is shadowbanned, removing from /r/{}'s ban list.".format( | |
i['name'], subreddit)) | |
body = {'executed' : 'removed', 'type' : 'banned', 'r' : subreddit, 'id' : i['id']} | |
r.post('http://www.reddit.com/api/unfriend', body) | |
processed +=1 | |
elif months: | |
months_secs = months * 2592000 | |
if cache[i['name']] < (time.time() - months_secs): | |
print("{} is inactive over {} month[s], removing from /r/{}'s ban list.".format( | |
i['name'], months, subreddit)) | |
body = {'executed' : 'removed', 'type' : 'banned', | |
'r' : subreddit, 'id' : i['id']} | |
r.post('http://www.reddit.com/api/unfriend', body) | |
processed += 1 | |
print("Found {} bans; processed {}".format(found, processed)) | |
if __name__ == '__main__': | |
signal.signal(signal.SIGINT, sigint_handler) | |
args = sys.argv[1:] | |
if len(args) >= 3: | |
redditor = Reddit(args[0], args[1]) | |
try: | |
months = int(args[2]) | |
for i in args[3:]: | |
process_subreddit(redditor, i, months=months) | |
except ValueError: | |
for i in args[2:]: | |
process_subreddit(redditor, i) | |
else: | |
print("USAGE:\npython3 prune_bans.py <username> <password> [subreddit,]", | |
"\n-OR-\npython3 prune_bans.py <username> <password> <months> [subreddit,]", | |
"\nMonths can be in any amount as long as it's a number. Subreddits", | |
"\ncan be ran in batches by listing multiples or just singly.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment