Beispiel #1
0
def process_override(reply, config):
    """
    This process is for moderators of ToR to force u/transcribersofreddit
    to mark a post as complete and award flair when the bot refutes a
    `done` claim. The comment containing "!override" must be in response to
    the bot's comment saying that it cannot find the transcript.

    :param reply: the comment reply object from the moderator.
    :param config: the global config object.
    :return: None.
    """

    # don't remove this check, it's not covered like other admin_commands
    # because it's used in reply to people, not as a PM
    if not from_moderator(reply, config):
        reply.reply(_(random.choice(config.no_gifs)))
        logging.info(f'{reply.author.name} just tried to override. Lolno.')

        return

    # okay, so the parent of the reply should be the bot's comment
    # saying it can't find it. In that case, we need the parent's
    # parent. That should be the comment with the `done` call in it.
    reply_parent = config.r.comment(id=clean_id(reply.parent_id))
    parents_parent = config.r.comment(id=clean_id(reply_parent.parent_id))
    if 'done' in parents_parent.body.lower():
        logging.info(
            f'Starting validation override for post {parents_parent.fullname}, '
            f'approved by {reply.author.name}')
        process_done(parents_parent, config, override=True)
def process_override(reply, r, tor, config):
    """
    This process is for moderators of ToR to force u/transcribersofreddit
    to mark a post as complete and award flair when the bot refutes a
    `done` claim. The comment containing "!override" must be in response to
    the bot's comment saying that it cannot find the transcript.

    :param reply: the comment reply object from the moderator.
    :param r: the active Reddit instance.
    :param tor: the TranscribersOfReddit subreddit object.
    :param config: the global config object.
    :return: None.
    """
    # first we verify that this comment comes from a moderator and that
    # we can work on it.
    if not from_moderator(reply, config):
        reply.reply(_(random.choice(config.no_gifs)))
        logging.info('{} just tried to override. Lolno.'.format(
            reply.author.name))
        return
    # okay, so the parent of the reply should be the bot's comment
    # saying it can't find it. In that case, we need the parent's
    # parent. That should be the comment with the `done` call in it.
    reply_parent = r.comment(id=clean_id(reply.parent_id))
    parents_parent = r.comment(id=clean_id(reply_parent.parent_id))
    if 'done' in parents_parent.body.lower():
        logging.info('Starting validation override for post {}'
                     ', approved by {}'.format(parents_parent.fullname,
                                               reply.author.name))
        process_done(parents_parent, r, tor, config, override=True)
Beispiel #3
0
def process_reply(reply, config):
    # noinspection PyUnresolvedReferences
    try:
        if any([regex.search(reply.body) for regex in MOD_SUPPORT_PHRASES]):
            process_mod_intervention(reply, config)
            reply.mark_read()
            return

        r_body = reply.body.lower()  # cache that thing

        if 'i accept' in r_body:
            process_coc(reply, config)
            reply.mark_read()
            return

        if 'claim' in r_body:
            process_claim(reply, config)
            reply.mark_read()
            return

        if ('done' in r_body or 'deno' in r_body  # we <3 u/Lornescri
            ):
            alt_text = True if 'done' not in r_body else False
            process_done(reply, config, alt_text_trigger=alt_text)
            reply.mark_read()
            return

        if 'thank' in r_body:  # trigger on "thanks" and "thank you"
            process_thanks(reply, config)
            reply.mark_read()
            return

        if '!override' in r_body:
            process_override(reply, config)
            reply.mark_read()
            return

        # If we made it this far, it's something we can't process automatically
        forward_to_slack(reply, config)
        reply.mark_read()  # no spamming the slack channel :)

    except (RedditClientException, AttributeError) as e:
        logging.warning(e)
        logging.warning(
            f"Unable to process comment {reply.submission.shortlink} "
            f"by {reply.author}")
        # the only way we should hit this is if somebody comments and then
        # deletes their comment before the bot finished processing. It's
        # uncommon, but common enough that this is necessary.
        pass
Beispiel #4
0
def process_reply(reply, config):
    # noinspection PyUnresolvedReferences
    try:
        if any([regex.search(reply.body) for regex in MOD_SUPPORT_PHRASES]):
            process_mod_intervention(reply, config)
            reply.mark_read()
            return

        if 'i accept' in reply.body.lower():
            process_coc(reply, config)
            reply.mark_read()
            return

        if 'claim' in reply.body.lower():
            process_claim(reply, config)
            reply.mark_read()
            return

        if 'done' in reply.body.lower():
            process_done(reply, config)
            reply.mark_read()
            return

        if 'thank' in reply.body.lower():  # trigger on "thanks" and "thank you"
            process_thanks(reply, config)
            reply.mark_read()
            return

        if '!override' in reply.body.lower():
            process_override(reply, config)
            reply.mark_read()
            return

        # If we made it this far, it's something we can't process automatically
        forward_to_slack(reply, config)
        reply.mark_read()  # no spamming the slack channel :)

    except (AttributeError, RedditClientException):
        # the only way we should hit this is if somebody comments and then
        # deletes their comment before the bot finished processing. It's
        # uncommon, but common enough that this is necessary.
        pass
Beispiel #5
0
def process_override(user: Redditor, blossom_submission: Dict, parent_id: str,
                     cfg):
    """
    This process is for moderators of ToR to force u/transcribersofreddit
    to mark a post as complete and award flair when the bot refutes a
    `done` claim. The comment containing "!override" must be in response to
    the bot's comment saying that it cannot find the transcript.

    :param user: The user requesting the override
    :param blossom_submission: The relevant Submission of Blossom
    :param parent_id: The ID of the parent comment of the override
    :param cfg: the global config object.
    """

    # TODO: turn this into a decorator
    # don't remove this check, it's not covered like other admin_commands
    # because it's used in reply to people, not as a PM
    if not is_moderator(user.name, cfg):
        logging.info(f"{user.name} just tried to override. Lolno.")
        return _(random.choice(cfg.no_gifs)), None

    # okay, so the parent of the reply should be the bot's comment
    # saying it can't find it. In that case, we need the parent's
    # parent. That should be the comment with the `done` call in it.
    reply_parent = cfg.r.comment(id=clean_id(parent_id))
    grandparent = cfg.r.comment(id=clean_id(reply_parent.parent_id))
    if grandparent.body.lower() in (CLAIM_PHRASES + DONE_PHRASES):
        logging.info(
            f"Starting validation override for post {grandparent.fullname}, "
            f"approved by {user.name}")
        return process_done(grandparent.author,
                            blossom_submission,
                            grandparent,
                            cfg,
                            override=True)
    return "Cannot process - no target comment found.", None
Beispiel #6
0
     blossom_submission = get_blossom_submission(submission, cfg)
     if "i accept" in r_body:
         message, flair = process_coc(username, reply.context,
                                      blossom_submission, cfg)
     elif check_for_phrase(r_body, UNCLAIM_PHRASES):
         message, flair = process_unclaim(username, blossom_submission,
                                          submission, cfg)
     elif check_for_phrase(r_body, CLAIM_PHRASES):
         message, flair = process_claim(username, blossom_submission,
                                        cfg)
     elif check_for_phrase(r_body, DONE_PHRASES):
         alt_text = "done" not in r_body
         message, flair = process_done(
             reply.author,
             blossom_submission,
             reply,
             cfg,
             alt_text_trigger=alt_text,
         )
     elif "!override" in r_body:
         message, flair = process_override(reply.author,
                                           blossom_submission,
                                           reply.parent_id, cfg)
     elif "!debug" in r_body:
         message, flair = process_debug(reply.author,
                                        blossom_submission, cfg)
     else:
         # If we made it this far, it's something we can't process automatically
         forward_to_slack(reply, cfg)
 if message:
     send_reddit_reply(reply, message)
def check_inbox(config):
    """
    Goes through all the unread messages in the inbox. It has two
    loops within this section, each one dealing with a different type
    of mail. Also deliberately leaves mail which does not fit into
    either category so that it can be read manually at a later point.

    The first loop handles username mentions.
    The second loop sorts out and handles comments that include 'claim'
        and 'done'.
    :return: None.
    """
    # Sort inbox, then act on it
    mentions = []
    replies = []
    # grab all of our messages and filter
    for item in config.r.inbox.unread(limit=None):
        if item.author.name == 'transcribot':
            item.mark_read()
            continue
        if item.subject == 'username mention':
            mentions.append(item)
            item.mark_read()
        if item.subject == 'comment reply':
            replies.append(item)
            # we don't mark as read here so that any comments that are not
            # ones we're looking for will eventually get emailed to me as
            # things I need to look at
        if 'reload' in item.subject.lower():
            item.mark_read()
            reload_config(item, config)
            item.reply('Config reloaded!')
            continue
        if 'update' in item.subject.lower():
            item.mark_read()
            update_and_restart(item, config)
            # there's no reason to do anything else here because the process
            # will terminate and respawn

        # ARE YOU ALIVE?!
        if item.subject.lower() == 'ping':
            item.mark_read()
            item.reply('Pong!')

    # sort them and create posts where necessary
    for mention in mentions:
        logging.info('Received mention! ID {}'.format(mention))

        if not is_valid(mention.parent_id, config):
            # Do our check here to make sure we can actually work on this one and
            # that we haven't already posted about it. We use the full ID here
            # instead of the cleaned one, just in case.
            logging.info(id_already_handled_in_db.format(mention.parent_id))
            continue

        # noinspection PyUnresolvedReferences
        try:
            process_mention(mention, config)
        except (AttributeError, praw.exceptions.ClientException):
            # apparently this crashes with an AttributeError if someone calls
            # the bot and immediately deletes their comment. This should fix
            # that.
            continue

    # comment replies
    for reply in replies:
        # noinspection PyUnresolvedReferences
        try:
            if 'i accept' in reply.body.lower():
                process_coc(reply, config)
                reply.mark_read()
                return

            if 'claim' in reply.body.lower():
                process_claim(reply, config)
                reply.mark_read()
                return

            if 'done' in reply.body.lower():
                process_done(reply, config)
                reply.mark_read()
                return

            if '!override' in reply.body.lower():
                process_override(reply, config)
                reply.mark_read()
                return

        except (AttributeError, praw.exceptions.ClientException):
            # the only way we should hit this is if somebody comments and then
            # deletes their comment before the bot finished processing. It's
            # uncommon, but common enough that this is necessary.
            continue