-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathphase3_handler.py
More file actions
142 lines (119 loc) · 5.62 KB
/
phase3_handler.py
File metadata and controls
142 lines (119 loc) · 5.62 KB
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
"""Retrieves aged comment entries from the DB and crossposts them"""
import logging
import textwrap
import os
import datetime
from distutils import util
import praw
import pytimeparse
import consts
import phase2_handler
import racb_db
import reddit_instantiator
import my_i18n as i18n
def process_comment_entries():
logging.info('Beginning phase 3 processing')
PHASE3_WAITING_PERIOD = os.environ.get('PHASE3_WAITING_PERIOD')
waiting_period_seconds = pytimeparse.timeparse.timeparse(PHASE3_WAITING_PERIOD)
comment_entries = racb_db.get_comments_older_than(waiting_period_seconds)
for comment_entry in comment_entries:
handle_comment(comment_entry)
racb_db.delete_comment(comment_entry)
logging.info('Finished phase 3 processing')
def handle_comment(comment_entry):
logging.info(f'Begin processing comment entry : {comment_entry["permalink"]}')
result = phase2_handler.run_filters(comment_entry)
if not result.passes_filter:
return
source_comment = result.comment
target_subreddit = result.target_subreddit
exec_crosspost(source_comment, target_subreddit)
def exec_crosspost(source_comment, target_subreddit, reply_to_crosspost_flag = True):
class Result:
success = False
crosspost = None
failure_reason = None
result = Result()
crosspost_title = get_crosspost_title_for_crosspost(source_comment.submission, target_subreddit)
try:
cross_post = source_comment.submission.crosspost(subreddit=target_subreddit, title=crosspost_title, send_replies=False)
logging.info(f'Crosspost succesful. link to post: www.reddit.com{cross_post.permalink}')
result.success = True
result.crosspost = cross_post
if reply_to_crosspost_flag:
reply_to_crosspost(source_comment, cross_post, target_subreddit)
except Exception as e:
hce_res = handle_crosspost_exception(e, source_comment, target_subreddit)
if hce_res.handled_with_grace:
result.failure_reason = hce_res.error_type
else:
logging.error(f'Crosspost failed due to a problem: {str(e)}' + '\n\n'
+ f'This occured while attempting to crosspost based on this comment: {source_comment.permalink}')
logging.exception(e)
debug = bool(util.strtobool(os.environ.get('DEBUG')))
if debug:
raise
return result
def get_crosspost_title_for_crosspost(submission, target_subreddit):
if target_subreddit.lower() == 'totallynotrobots':
return submission.title.upper()
else:
# Will use this submission’s title if None (default: None).
# https://praw.readthedocs.io/en/latest/code_overview/models/submission.html#praw.models.Submission.crosspost
return None
def reply_to_crosspost(source_comment, cross_post, target_subreddit):
source_subreddit = source_comment.subreddit.display_name
text = i18n.get_translated_string(
'REPLY_TO_CROSSPOST',
target_subreddit,
bot_name=reddit_instantiator.AUTO_CROSSPOST_BOT_NAME,
)
PHASE3_WAITING_PERIOD = os.environ.get('PHASE3_WAITING_PERIOD')
timedelta_string = PHASE3_WAITING_PERIOD
if source_comment.author:
source_comment_author_name = f'/u/{source_comment.author.name}'
else:
source_comment_author_name = i18n.get_translated_string('THE_USER_WHO_COMMENTED', target_subreddit, add_suffix=False)
text = text.format(source_subreddit=source_subreddit,
target_subreddit=target_subreddit,
source_comment_permalink=f'https://reddit.com{source_comment.permalink}',
source_comment_score=source_comment.score,
source_submission_id=source_comment.submission.id,
timedelta_string=timedelta_string,
source_comment_author_name=source_comment_author_name,)
return cross_post.reply(text)
def handle_crosspost_exception(e, comment, target_subreddit):
class Result:
handled_with_grace = False
error_type = None
result = Result()
if not isinstance(e, praw.exceptions.RedditAPIException):
return result
familiar_error_types = ['NO_CROSSPOSTS',
'INVALID_CROSSPOST_THING',
'SUBREDDIT_NOTALLOWED',
'NO_IMAGES',
'NO_LINKS',
'NO_SELFS',
'NO_VIDEOS',
'OVER18_SUBREDDIT_CROSSPOST',
'THREAD_LOCKED',
'IMAGES_NOTALLOWED',
'SUBMIT_VALIDATION_BODY_BLACKLISTED_STRING',
'SUBMIT_VALIDATION_TITLE_BLACKLISTED_STRING',
'SUBMIT_VALIDATION_MIN_LENGTH',
'SUBMIT_VALIDATION_MAX_LENGTH',
'SUBMIT_VALIDATION_BODY_REQUIRED',
'SUBMIT_VALIDATION_BODY_NOT_ALLOWED',
'SUBMIT_VALIDATION_LINK_WHITELIST',
'SUBMIT_VALIDATION_LINK_BLACKLIST',
'SUBMIT_VALIDATION_REPOST',
'SUBMIT_VALIDATION_FLAIR_REQUIRED',
'SUBMIT_VALIDATION_TITLE_REGEX_REQUIREMENT',
'SUBMIT_VALIDATION_TITLE_REQUIREMENT',
'BANNED_FROM_SUBREDDIT',
]
if e.error_type in familiar_error_types:
result.handled_with_grace = True
result.error_type = e.error_type
return result