Пример #1
0
    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)
Пример #2
0
    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()
Пример #3
0
    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()
Пример #4
0
    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
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
    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)
Пример #8
0
 def unmute_user_warnings(user, subreddit):
     user = UserModel.get(UserModel.username == user.lower()
                          and UserModel.subreddit == subreddit)
     user.warnings_muted = False
     user.save()
Пример #9
0
    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()
Пример #10
0
    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