def check_user_posts(self, thing): user, _ = UserModel.get_or_create( username=thing.author.name.lower(), subreddit=thing.subreddit.display_name) if user.tracked: message = utils.SlackResponse("New post by user /u/" + user.username) try: title = thing.submission.title except AttributeError: title = thing.title attachment = message.add_attachment(title=title, title_link=thing.permalink, text=thing.body, color='#5c96ab', callback_id="check_user_posts") attachment.add_button("Verify", value="verify", style='primary') attachment.add_button("Untrack", value="untrack_" + user.username) if self.botbans and not user.shadowbanned: attachment.add_button("Botban", value="botban_" + user.username, style='danger') elif self.botbans and user.shadowbanned: attachment.add_button("Unbotban", "unbotban_" + user.username, style='danger') self.webhook.send_message(message)
def scan_submissions(self): db.connect() submissions = self.subreddit.new(limit=50) if self.flair_enforcer is not None: self.flair_enforcer.check_submissions() for submission in submissions: try: self.already_done_helper.add(submission.id, self.subreddit_name) except IntegrityError: continue if self.flair_enforcer is not None and submission.link_flair_text is None: self.flair_enforcer.add_submission(submission) try: user = UserModel.get( UserModel.username == submission.author.name.lower() and UserModel.subreddit == submission.subreddit.display_name) except DoesNotExist: continue if user.shadowbanned: self.subreddit.mod.remove(submission) if self.user_warnings is not None: if user.tracked: self.user_warnings.send_warning(submission) self.user_warnings.check_user_offenses(user) db.close()
def scan_comments(self): db.connect() comments = self.subreddit.comments(limit=100) sticky_comments_ids = [ "t1_" + submission.sticky_cmt_id for submission in SubmissionModel.select() ] for comment in comments: try: self.already_done_helper.add(comment.id, self.subreddit_name) except IntegrityError: continue try: user = UserModel.get( UserModel.username == comment.author.name.lower(), UserModel.subreddit == comment.subreddit.display_name) except DoesNotExist: continue if user.shadowbanned: self.subreddit.mod.remove(comment) if user.tracked: self.user_warnings.send_warning(comment) if self.watch_stickies and comment.parent_id in sticky_comments_ids: self.subreddit.mod.remove(comment) self.user_warnings.check_user_offenses(user) db.close()
def untrack_user(self, user, replace_original=False): response = snoohelper.utils.slack.SlackResponse( replace_original=replace_original) try: redditor = self.r.redditor(user) username = redditor.name except prawcore.exceptions.NotFound: response.add_attachment(title="Error: user not found.", color='danger') return response if self.user_warnings is not None: user, _ = UserModel.get_or_create(username=redditor.name.lower(), subreddit=self.subreddit_name) if user.tracked: user.tracked = False user.save() response.add_attachment( title="Ceasing to track user /u/%s." % user.username, title_link="https://reddit.com/u/" + user.username, color='good') else: raise snoohelper.utils.exceptions.UserAlreadyUntracked() else: response.add_attachment( text='Error: user tracking is not enabled for this team.', color='danger') return response
def unbotban(self, user, author, replace_original=False): response = snoohelper.utils.slack.SlackResponse( replace_original=replace_original) try: redditor = self.r.redditor(user) username = redditor.name except prawcore.exceptions.NotFound: response.add_attachment(title="Error: user not found.", color='danger') return response if self.botbans: user, _ = UserModel.get_or_create(username=redditor.name.lower(), subreddit=self.subreddit_name) if user.shadowbanned: user.shadowbanned = False user.save() attachment = response.add_attachment( title="User /u/%s has been unbotbanned." % user.username, title_link="https://reddit.com/u/" + user.username, color='good', callback_id="unbotban") attachment.add_field("Author", author) else: raise snoohelper.utils.exceptions.UserAlreadyUnbotbanned else: response.add_attachment( text='Error: botbans are not enabled for this team.', color='danger') return response
def import_botbans(self, botbans_string): botbans_string = botbans_string.replace("'", "") botbans_string = botbans_string.replace('"', "") botbans_string = botbans_string.replace("[", "") botbans_string = botbans_string.replace("]", "") users = botbans_string.split(',') n = 0 db.connect() for user in users: user_record, _ = UserModel.get_or_create( username=user.lower(), subreddit=self.subreddit_name) user_record.shadowbanned = True user_record.save() n += 1 db.close() response = snoohelper.utils.slack.SlackResponse() response.add_attachment( text="Botbans imported successfully. Number of botbans imported: {}." .format(n), color='good') return response
def check_user_offenses(self, user): message = utils.SlackResponse() send = False attachment = None if isinstance(user, str): user, _ = UserModel.get_or_create(username=user.lower(), subreddit=self.subreddit) if user.removed_comments > self.comment_threshold: attachment = message.add_attachment( title="Warning regarding user /u/" + user.username, title_link="https://reddit.com/u/" + user.username, color='#5c96ab', text= "User has had %s> comments removed. Please check profile history." % str(self.comment_threshold), callback_id="check_user_offenses") send = True if user.removed_submissions > self.submission_threshold: attachment = message.add_attachment( title="Warning regarding user /u/" + user.username, title_link="https://reddit.com/u/" + user.username, color='#5c96ab', text="User has had %s> submissions removed. Please check profile" " history." % str(self.submission_threshold), callback_id="check_user_offenses") send = True if user.bans > self.ban_threshold: attachment = message.add_attachment( title="Warning regarding user /u/" + user.username, title_link="https://reddit.com/u/" + user.username, color='#5c96ab', text= "User has been banned %s> times. Please check profile history." % str(self.ban_threshold), callback_id="check_user_offenses") send = True try: last_warned_ts = user.last_warned.timestamp() except AttributeError: last_warned_ts = 0 if not user.warnings_muted and send and time.time( ) - last_warned_ts > 86400: attachment.add_button("Verify", value="verify", style='primary') if not user.tracked: attachment.add_button("Track", value="track_" + user.username) else: attachment.add_button("Untrack", value="untrack_" + user.username) if self.botbans and not user.shadowbanned: attachment.add_button("Botban", value="botban_" + user.username, style='danger') elif self.botbans and user.shadowbanned: attachment.add_button("Unbotban", value="unbotban_" + user.username, style='danger') attachment.add_button("Mute user's warnings", value="mutewarnings_" + user.username, style='danger') user.last_warned = time.time() user.save() self.webhook.send_message(message)
def unmute_user_warnings(user, subreddit): user = UserModel.get(UserModel.username == user.lower() and UserModel.subreddit == subreddit) user.warnings_muted = False user.save()
def scan_modlog(self): subreddit = self.subreddit relevant_actions = ('removecomment', 'removelink', 'approvelink', 'approvecomment', 'banuser', 'sticky') db.connect() modlog = list(subreddit.mod.log(limit=20)) new_items = 0 for item in modlog: try: self.already_done_helper.add(item.id, item.subreddit) new_items += 1 except IntegrityError: continue if item.action in relevant_actions: user, _ = UserModel.get_or_create( username=item.target_author.lower(), subreddit=item.subreddit) if item.action == 'removecomment': user.removed_comments += 1 elif item.action == 'removelink': user.removed_submissions += 1 elif item.action == 'approvelink': user.approved_submissions += 1 elif item.action == 'approvecomment': user.approved_comments += 1 elif item.action == 'sticky' and "watchstickies" in self.config.modules and \ item.target_fullname.startswith('t1'): comment = self.thread_r.comment( item.target_fullname.strip("t1")) try: submission = comment.submission except praw.exceptions.PRAWException as e: print("PRAW Exception, " + str(e)) try: if "flair" not in comment.body: SubmissionModel.create( submission_id=submission.id, sticky_cmt_id=comment.id, subreddit=submission.subreddit.display_name) except (TypeError, praw.exceptions.PRAWException) as e: print("PRAW Exception, " + str(e)) elif item.action == 'banuser': try: ban_length = int(re.findall('\d+', item.details)[0]) except IndexError: ban_length = None ban_target = item.target_author ban_author = item._mod ban_reason = item.description + " | /u/" + ban_author if ban_target != "[deleted]" and is_banned(self.subreddit, user) and \ "| /u/" not in item.description: # Change to True to issue bans if False: self.subreddit.banned.add(ban_target, ban_reason=ban_reason, duration=ban_length) print("Banned: {}, reason: {}, duration: {}".format( ban_target, ban_reason, ban_length)) if self.un is not None: snoohelper.utils.reddit.add_ban_note(self.un, item) user.bans += 1 elif item.action == 'unbanuser': if self.un is not None: snoohelper.utils.reddit.add_ban_note(self.un, item, unban=True) user.save() self.user_warnings.check_user_offenses(user) db.close()
def generate_quick_summary(self, username): r = self.r response = utils.slack.SlackResponse() try: user = r.redditor(username) username = user.name except prawcore.exceptions.NotFound: response.add_attachment(fallback="Summary error.", title="Error: user not found.", color='danger') return response user_track, _ = UserModel.get_or_create(username=username.lower(), subreddit=self.subreddit) combined_karma = user.link_karma + user.comment_karma account_creation = str(datetime.datetime.fromtimestamp(user.created_utc)) last_note = None if self.un is not None: notes = list(self.un.get_notes(username)) if len(notes): last_note = str(notes[0].note) attachment = response.add_attachment(title='Overview for /u/' + user.name, title_link="https://www.reddit.com/user/" + username, color='#5c96ab', callback_id='user_' + username) attachment.add_field("Combined karma", combined_karma) attachment.add_field("Redditor since", account_creation) if self.spamcruncher is not None: results = self.spamcruncher.analyze_user(username) spammer_likelihood = 'Low' if results.spammer_likelihood > 100: spammer_likelihood = 'Moderate' if results.spammer_likelihood > 180: spammer_likelihood = 'High' attachment.add_field("Spammer likelihood", spammer_likelihood) if self.users_tracked: if user_track is not None: user_is_shadowbanned = "No" user_is_tracked = "No" comment_removals = user_track.removed_comments submission_removals = user_track.removed_submissions bans = user_track.bans approvals = user_track.approved_comments + user_track.approved_submissions if user_track.shadowbanned: user_is_shadowbanned = "Yes" if user_track.tracked: user_is_tracked = "Yes" if not comment_removals: comment_removals = "None recorded" if not submission_removals: submission_removals = "None recorded" if not bans: bans = "None recorded" if not approvals: approvals = "None recorded" attachment.add_field("Removed comments", comment_removals) attachment.add_field("Removed submissions", submission_removals) attachment.add_field("Bans", bans) attachment.add_field("Approvals", approvals) attachment.add_field("Shadowbanned", user_is_shadowbanned) attachment.add_field("Tracked", user_is_tracked) if last_note is not None: attachment.add_field("Latest usernote", last_note, short=False) attachment.add_button("Summary (500)", "summary_500_" + username, style='primary') attachment.add_button("Summary (1000)", "summary_1000_" + username, style='primary') if self.users_tracked and not user_track.tracked: attachment.add_button("Track", "track_" + user.name) elif self.users_tracked and user_track.tracked: attachment.add_button("Untrack", "untrack_" + user.name) if self.botbans and not user_track.shadowbanned: attachment.add_button("Botban", "botban_" + user.name, style='danger') elif self.botbans and user_track.shadowbanned: attachment.add_button("Unbotban", "unbotban_" + user.name, style='danger') return response