Skip to content

Instantly share code, notes, and snippets.

@srsinvasionbot
Created May 1, 2012 11:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save srsinvasionbot/e796b65bf9d657cc6f3d to your computer and use it in GitHub Desktop.
Save srsinvasionbot/e796b65bf9d657cc6f3d to your computer and use it in GitHub Desktop.
SRS Banning Bot
#! /usr/bin/env python
########################################################################################
# SRS Banning Bot v0.2 #
# ==================== #
# #
# See banbot.py -h for usage. #
# #
# The Reddit API python wrapper is required for this script. #
# See https://github.com/mellort/reddit_api #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
########################################################################################
try:
import reddit
except ImportError:
raise ImportError('Reddit API python wrapper is required. See https://github.com/mellort/reddit_api for more details.')
import sys, time, argparse, string
########################################################################################
# Initialisation & Global Variables ####################################################
########################################################################################
parser = argparse.ArgumentParser(description='SRS Banning Bot v0.2. A thermonuclear Banning Bot for reddit.',epilog='Associated files to be located in the run directory:\n\t \'white\': Whitelisting text file. The bot will not ban users on this list from any sub.\n\t \'banlog\': Banning log for the bot.\n\nUse wisely.')
parser.add_argument('--launch', nargs='+', help='Subreddits doing the banning. Moderator privileges required.',required=True)
parser.add_argument('--username', help='Reddit Username',required=True)
parser.add_argument('--password', help='Reddit Password',required=True)
parser.add_argument('--target', nargs='+', help='Subreddits targeted for banning. Defaults to the fempire.',default=['ShitRedditSays','SRSDiscussion','SRSMeta','SRSAnime','SRSArt','SRSAustralia','SRSAuthors','SRSBooks','SRSBusiness','SRSCanada','SRSCinema','SRSComics','SRSDisabilities','SRSFartsAndCrafts','SRSFoodies','SRSFunny','SRSGaming','SRSGSM','SRSHappy','SRSImages','SRSIvoryTower','SRSMailbag','SRSMusic','SRSMusicals','SRSNews','SRSPets','SRSPolitics','SRSPonies','SRSPUA','SRSQuestions','SRSSex','SRSSkeptic','SRSTechnology','SRSTelevision','SRSTrees','SRSWorldProblems','AntiSRSCirclejerk','Daww','FitnessPlus','GoldRedditSays','SciFiAndFantasy'])
parser.add_argument('--depth', type=int, help='Scrape Depth. Specify to reduce depth, omit for maximum depth. ',default=None)
parser.add_argument('--maxpost', type=int, help='Maximum allowable karma from any single post. Default=20',default=20)
parser.add_argument('--maxkarma', type=int, help='Maximum allowable karma from total posts. Default=200',default=200)
args = parser.parse_args()
username = args.username
passwd = args.password
launchsubs = args.launch
targetsubs = args.target
maxpost = args.maxpost
maxkarma = args.maxkarma
depth = args.depth
########################################################################################
# Sub Routines #########################################################################
########################################################################################
# 1. Function for flattening multi-tier comments from a subreddit get into a single list.
def flatten_comments(mlcomments):
comm_list = []
for line in mlcomments:
if type(line) is reddit.objects.Comment:
comm_list.append(line)
elif type(line) is list:
for item in line:
mlcomments.append(item) # Append 2nd tier list items to 1st tier
elif type(line) is reddit.objects.MoreComments:
pass
else:
raise TypeError('List must contain only reddit.objects.Comment or lists. Type passed: '+str(type(line)))
return comm_list
# 2. Function that creates the banlist.
def extract_banlist(comm_list,maxpost,maxkarma):
banlist = []
for k in comm_list:
if (k.author_flair_text != None):
banlist.append({'banee':k.author.name,'targetsub':k.subreddit.display_name})
elif (k.ups-k.downs) > maxpost:
banlist.append({'banee':k.author.name,'targetsub':k.subreddit.display_name})
elif type(k.author) is reddit.objects.Redditor:
srsup,commenthistory = 0,[]
try:
history = list(k.author.get_comments())
for comment in history:
for sub in targetsubs:
if (comment.subreddit.display_name == sub):
srsup = srsup + comment.ups
if srsup > maxkarma:
banlist.append({'banee':k.author.name,'targetsub':k.subreddit.display_name})
except:
print 'Warning: Error reviewing history of: '+str(k.author.name)+'\n'
else:
sys.stdout.write('Warning: TypeError: k.author\n'+ str(type(k.author)))
return banlist
# 3. Function to scrape targeted subs for comments.
def scrape_comments(r, targetsubs, depth):
targets = []
for sub in targetsubs:
for t in list(r.get_subreddit(sub).get_comments(limit=depth)):
targets.append(t)
return targets
# 4. Banning function
def mass_ban(r,banlist,launchsubs):
try:
banfile = open('banlog','a')
except IOError as e:
raise IOError('Unable to open banlog for writing: '+str(e))
for banee in banlist:
for sub in launchsubs:
try:
banfile.write(str(banee['targetsub'])+' '+str(r.get_subreddit(sub).display_name)+' '+str(banee['banee'])+'\n')
r.get_subreddit(sub).ban(r.get_redditor(banee['banee']))
except:
e = sys.exc_info()[1]
print "fail: ",str(e)
banfile.close()
# 5. Duplicate removal function. Credit Tim Peters (http://code.activestate.com/recipes/52560/)
def remove_dupes(q):
n = len(q)
q.sort()
assert n > 0
last = q[0]
lasti = i = 1
while i < n:
if q[i] != last:
q[lasti] = last = q[i]
lasti += 1
i += 1
return q[:lasti]
# 6. Whitelisting removal.
def white(q):
white = open('white','r').read().splitlines()
for h in range(len(q)-1,-1,-1):
for k in white:
if k == q[h]:
q.pop(h)
return q
########################################################################################
# Main Routine #########################################################################
########################################################################################
print "=======================================\n\t SRS Banning Bot v0.2\n======================================="
print str(time.asctime(time.localtime()))+" - Logging into Reddit"
r = reddit.Reddit(user_agent='/u/'+username+' - SRS Banning Bot v0.2')
r.login(username,passwd)
print str(time.asctime(time.localtime()))+" - Scraping Comments"
targets = scrape_comments(r,targetsubs,depth)
print str(time.asctime(time.localtime()))+" - Preparing Comments"
comm_list = flatten_comments(targets)
print str(time.asctime(time.localtime()))+" - Creating Banlist"
banlist = extract_banlist(comm_list, maxpost, maxkarma)
print str(time.asctime(time.localtime()))+" - Preparing List"
banlist = white(remove_dupes(banlist))
print str(time.asctime(time.localtime()))+" - Banning users"
mass_ban(r,banlist,launchsubs)
print str(time.asctime(time.localtime()))+" - Fin"
########################################################################################
# Fin ##################################################################################
########################################################################################
#! /usr/bin/env python
########################################################################################
# SRS Unbanning Bot v0.2 #
# ====================== #
# #
# See ubanbot.py -h for usage. #
# #
# To be used in conjunction with SRS Banning Bot v0.2 #
# #
# The Reddit API python wrapper is required for this script. #
# See https://github.com/mellort/reddit_api #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
########################################################################################
try:
import reddit
except ImportError:
raise ImportError('Reddit API python wrapper is required. See https://github.com/mellort/reddit_api for more details.')
import sys, time, argparse, string
########################################################################################
# Initialisation & Global Variables ####################################################
########################################################################################
parser = argparse.ArgumentParser(description='SRS Unbanning Bot v0.2. The French military banning strategy for reddit.',epilog='Associated files to be located in the run directory:\n\t \'white\': Whitelisting text file. The unbanning bot appends to this list. Users on the whitelist will not be banned from any sub.\n\t \'banlog\': Banning log for the bot.\n\nUse wisely.')
parser.add_argument('--launch', nargs='+', help='Subreddits doing the unbanning. Moderator privileges required.',required=True)
parser.add_argument('--username', help='Reddit Username',required=True)
parser.add_argument('--password', help='Reddit Password',required=True)
parser.add_argument('--target', nargs='+', help='Subreddits targeted for unbanning. If this argument is omitted, the bot will unban all users in the banlog.')
args = parser.parse_args()
username = args.username
passwd = args.password
launchsubs = args.launch
targetsubs = args.target
########################################################################################
# Sub Routines #########################################################################
########################################################################################
# 1. Extract a trimmed banlist
def extract_ubanlist(targetsubs):
trimmed_ubanlist = []
try:
banlog = [line.strip().split() for line in open('banlog')]
except:
raise IOError('File \'banlog\' is required in the run directory.')
else:
if len(targetsubs) == 0:
trimmed_ubanlist = [line[2] for line in banlog] # Unban everyone if no target.
else:
for sub in targetsubs:
for line in banlog:
if line[0] == sub:
trimmed_ubanlist.append(line[2])
return trimmed_ubanlist
# 2. Unbanning function
def mass_uban(r,banlist,launchsubs):
for banee in banlist:
for sub in launchsubs:
try:
print banee+' '+str(r.get_subreddit(sub).display_name)
r.get_subreddit(sub).unban(r.get_redditor(banee['banee']))
except:
e = sys.exc_info()[1]
print "fail: ",str(e)
# 3. Whitelisting append.
def white(q):
try:
white = open('white','a')
for k in q:
white.write(k+"\n")
white.close
except:
raise IOError('Cannot open file \'white\' for writing.')
return None
########################################################################################
# Main Routine #########################################################################
########################################################################################
print "=======================================\n\t SRS Banning Bot v0.2\n======================================="
print str(time.asctime(time.localtime()))+" - Logging into Reddit"
r = reddit.Reddit(user_agent='/u/'+username+' - SRS Unbanning Bot v0.2 - Testing only')
r.login(username,passwd)
print str(time.asctime(time.localtime()))+" - Creating unbanlist"
ubanlist = list(set(extract_ubanlist(targetsubs)))
print str(time.asctime(time.localtime()))+" - Whitelisting users"
white(ubanlist)
print str(time.asctime(time.localtime()))+" - Unbanning users"
mass_uban(r,ubanlist,launchsubs)
print str(time.asctime(time.localtime()))+" - Fin"
########################################################################################
# Fin ##################################################################################
########################################################################################
@srsinvasionbot
Copy link
Author

banbot.py is designed to run as an daily cron job. Redirect the output for a log of errors:
cd 'dir containing bot'; ./banbot.py --user 'username' --password 'password' --launch [Banning Subs] --target [subs to scrape]

ubanbot.py is designed for a one-off run to undo the banbot's work.
./ubanbot.py --user 'username' --password 'password' --launch [Unbanning Subs] --target [Only unban this sub's posters]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment