-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRemovalBot.py
151 lines (133 loc) · 5.03 KB
/
RemovalBot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import praw
import csv
import json
import os
import re
import sys
import yaml
from praw.models import MoreComments
#===Constants===#
CONFIG_FILE = os.path.join(os.path.dirname(__file__),"config.yaml")
CACHE_FILE = os.path.join(os.path.dirname(__file__), "cache.json")
#===Globals===#
#Config file
config = None
def s_to_f(non_f_str: str, submissionObject):
# If you have the username being eval'd in this string and the user deleted their post, this will cause errors
# So this is handled with a try catch later
return eval(f'f"""{non_f_str}"""')
def testTemplates():
#Intialize
loadConfig()
reddit = initReddit()
removalReasons = getRemovalReasons(reddit)
#Local vars
submissions = []
submissionId = config['templateTestId']
mySubmission = reddit.submission(id=submissionId)
rules = config['regexes'].keys()
for rule in rules:
submissions.append({"rule": rule, "_self": mySubmission})
#Leave removal reason comments
for submission in submissions:
submissionObject = submission["_self"]
submissionRule = submission["rule"]
result = postComment(submissionObject, submissionRule, removalReasons)
if result:
print("Comment Submitted")
def loadConfig():
global config
#Load configs
try:
config = yaml.load(open(CONFIG_FILE).read(), Loader=yaml.FullLoader)
except:
print("'config.yaml' could not be located. Please ensure 'config.example' has been renamed")
exit()
def initReddit():
client = config["client"]
reddit = praw.Reddit(**client)
return reddit
def loadCache():
postCache = {}
try:
with open(CACHE_FILE, "r") as fin:
postCache = json.load(fin)
except Exception as e:
print (e)
return postCache
def getRuleFromRegexMatch(flair):
regexes = config["regexes"]
if not flair:
return None
#Remove whitespace and force lowercase for the flair
flair = flair.strip().replace(" ", "").lower()
#If we match a single rule return back with the first one (we can add additional logic to grab all rules violated)
for regex in regexes:
if (re.search(regexes[regex], flair)):
return regex
return None
def getRemovalReasons(reddit):
#Grab the removal reasons from the wiki
wikiPage = reddit.subreddit(config["wiki_subreddit"]).wiki[config["removal_reasons_wiki"]].content_md
return yaml.load(wikiPage, Loader=yaml.FullLoader)
def checkForDuplicateComments(submissionObj):
#Check top level comments in the submission object
submissionObj.comments.replace_more(limit=0)
return any(comment.distinguished for comment in submissionObj.comments)
def postComment(submissionObject, submissionRule, removalReasons):
try:
#Build up comment body from wiki
commentBody = ""
commentBody += s_to_f(removalReasons["header"], submissionObject)
commentBody += removalReasons["rules"][submissionRule]
commentBody += removalReasons["footer"]
#Leave a comment
comment = submissionObject.reply(commentBody)
comment.mod.distinguish(how="yes",sticky=True)
comment.mod.lock()
return comment
except Exception as e:
print (e)
#If anything bad happens, return back false
return False
def saveCache(postCache):
with open(CACHE_FILE, "w") as fout:
for chunk in json.JSONEncoder().iterencode(postCache):
fout.write(chunk)
if __name__ == "__main__":
#Run tests
if len(sys.argv) >= 1:
if sys.argv[1] == '--test':
print("Running Tests...")
testTemplates()
exit()
#Intialize
loadConfig()
postCache = loadCache()
reddit = initReddit()
moderator = reddit.subreddit(config["subreddit"]).mod
removalReasons = getRemovalReasons(reddit)
#Local vars
submissions = {}
#Only check for removelink actions, grab last X since we dont want to spend too much time grabbing post information
for log in moderator.log(action="removelink",limit=config["mod_log_depth"]):
if log._mod not in config["ignore_mods"]:
submissionId = log.target_fullname.split("_")[1]
if submissionId not in postCache:
submissionObject = reddit.submission(id=submissionId)
if submissionObject.removed:
submissionFlair = submissionObject.link_flair_text
rule = getRuleFromRegexMatch(submissionFlair)
if rule != None:
submissions[submissionId] = {"rule": rule, "_self": submissionObject}
#Leave removal reason comments
for submission in submissions:
submissionObject = submissions[submission]["_self"]
submissionRule = submissions[submission]["rule"]
if not checkForDuplicateComments(submissionObject):
result = postComment(submissionObject, submissionRule, removalReasons)
if result:
postCache[submission] = result.id
#Write out
if postCache:
saveCache(postCache)