<commit_before>import logging
import re

from praw.exceptions import ClientException as RedditClientException
from praw.models import Comment as RedditComment
from praw.models import Message as RedditMessage
from tor.core import validation
from tor.core.admin_commands import process_command, process_override
from tor.core.helpers import send_to_modchat
from tor.core.mentions import process_mention
from tor.core.strings import reddit_url
from tor.core.user_interaction import (process_claim, process_coc,
                                       process_done, process_message,
                                       process_thanks, process_unclaim,
                                       process_wrong_post_location)

MOD_SUPPORT_PHRASES = [
    re.compile('fuck', re.IGNORECASE),
    # re.compile('unclaim', re.IGNORECASE),
    re.compile('undo', re.IGNORECASE),
    # re.compile('(?:good|bad) bot', re.IGNORECASE),
]


def forward_to_slack(item, cfg):
    username = item.author.name

    send_to_modchat(
        f'<{reddit_url.format(item.context)}|Unhandled message>'
        f' by'
        f' <{reddit_url.format("/u/" + username)}|u/{username}> -- '
        f'*{item.subject}*:\n{item.body}', cfg
    )
    logging.info(
        f'Received unhandled inbox message from {username}. \n Subject: '
        f'{item.subject}\n\nBody: {item.body} '
    )


def process_mod_intervention(post, cfg):
    """
    Triggers an alert in slack with a link to the comment if there is something
    offensive or in need of moderator intervention
    """
    if not isinstance(post, RedditComment):
        # Why are we here if it's not a comment?
        return

    # Collect all offenses (noted by the above regular expressions) from the
    # original
    phrases = []
    for regex in MOD_SUPPORT_PHRASES:
        matches = regex.search(post.body)
        if not matches:
            continue

        phrases.append(matches.group())

    if len(phrases) == 0:
        # Nothing offensive here, why did this function get triggered?
        return

    # Wrap each phrase in double-quotes (") and commas in between
    phrases = '"' + '", "'.join(phrases) + '"'

    send_to_modchat(
        f':rotating_light::rotating_light: Mod Intervention Needed '
        f':rotating_light::rotating_light: '
        f'\n\nDetected use of {phrases} {post.submission.shortlink}',
        cfg
    )


def process_reply(reply, cfg):
    # noinspection PyUnresolvedReferences
    try:
        if any([regex.search(reply.body) for regex in MOD_SUPPORT_PHRASES]):
            process_mod_intervention(reply, cfg)
            return

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

        if (
            'image transcription' in r_body or
            validation._footer_check(reply, cfg) or
            validation._footer_check(reply, cfg, new_reddit=True)
        ):
            process_wrong_post_location(reply, cfg)
            return

        if 'i accept' in r_body:
            process_coc(reply, cfg)
            return

        if 'unclaim' in r_body or 'cancel' in r_body:
            process_unclaim(reply, cfg)
            return

        if (
            'claim' in r_body or
            'dibs' in r_body
        ):
            process_claim(reply, cfg)
            return

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

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

        if '!override' in r_body:
            process_override(reply, cfg)
            return

        # If we made it this far, it's something we can't process automatically
        forward_to_slack(reply, cfg)

    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


def check_inbox(cfg):
    """
    Goes through all the unread messages in the inbox. It deliberately
    leaves mail which does not fit into either category so that it can
    be read manually at a later point.

    :return: None.
    """
    # Sort inbox, then act on it
    # Invert the inbox so we're processing oldest first!<commit_msg>Fewer return statements with the same logic<commit_after>import logging
import re

from praw.exceptions import ClientException as RedditClientException
from praw.models import Comment as RedditComment
from praw.models import Message as RedditMessage
from tor.core import validation
from tor.core.admin_commands import process_command, process_override
from tor.core.helpers import send_to_modchat
from tor.core.mentions import process_mention
from tor.core.strings import reddit_url
from tor.core.user_interaction import (process_claim, process_coc,
                                       process_done, process_message,
                                       process_thanks, process_unclaim,
                                       process_wrong_post_location)

MOD_SUPPORT_PHRASES = [
    re.compile('fuck', re.IGNORECASE),
    # re.compile('unclaim', re.IGNORECASE),
    re.compile('undo', re.IGNORECASE),
    # re.compile('(?:good|bad) bot', re.IGNORECASE),
]


def forward_to_slack(item, cfg):
    username = item.author.name

    send_to_modchat(
        f'<{reddit_url.format(item.context)}|Unhandled message>'
        f' by'
        f' <{reddit_url.format("/u/" + username)}|u/{username}> -- '
        f'*{item.subject}*:\n{item.body}', cfg
    )
    logging.info(
        f'Received unhandled inbox message from {username}. \n Subject: '
        f'{item.subject}\n\nBody: {item.body} '
    )


def process_mod_intervention(post, cfg):
    """
    Triggers an alert in slack with a link to the comment if there is something
    offensive or in need of moderator intervention
    """
    if not isinstance(post, RedditComment):
        # Why are we here if it's not a comment?
        return

    # Collect all offenses (noted by the above regular expressions) from the
    # original
    phrases = []
    for regex in MOD_SUPPORT_PHRASES:
        matches = regex.search(post.body)
        if not matches:
            continue

        phrases.append(matches.group())

    if len(phrases) == 0:
        # Nothing offensive here, why did this function get triggered?
        return

    # Wrap each phrase in double-quotes (") and commas in between
    phrases = '"' + '", "'.join(phrases) + '"'

    send_to_modchat(
        f':rotating_light::rotating_light: Mod Intervention Needed '
        f':rotating_light::rotating_light: '
        f'\n\nDetected use of {phrases} {post.submission.shortlink}',
        cfg
    )


def process_reply(reply, cfg):
    # noinspection PyUnresolvedReferences
    try:
        r_body = reply.body.lower()  # cache that thing

        if any([regex.search(reply.body) for regex in MOD_SUPPORT_PHRASES]):
            process_mod_intervention(reply, cfg)

        elif (
            'image transcription' in r_body
            or validation._footer_check(reply, cfg)
            or validation._footer_check(reply, cfg, new_reddit=True)
        ):
            process_wrong_post_location(reply, cfg)

        elif 'i accept' in r_body:
            process_coc(reply, cfg)

        elif 'unclaim' in r_body or 'cancel' in r_body:
            process_unclaim(reply, cfg)

        elif 'claim' in r_body or 'dibs' in r_body:
            process_claim(reply, cfg)

        elif 'done' in r_body or 'deno' in r_body or 'doen' in r_body:
            alt_text = True if 'done' not in r_body else False
            process_done(reply, cfg, alt_text_trigger=alt_text)

        elif 'thank' in r_body:  # trigger on "thanks" and "thank you"
            process_thanks(reply, cfg)

        elif '!override' in r_body:
            process_override(reply, cfg)

        else:
            # If we made it this far, it's something we can't process automatically
            forward_to_slack(reply, cfg)

    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


def check_inbox(cfg):
    """
    Goes through all the unread messages in the inbox. It deliberately
    leaves mail which does not fit into either category so that it can
    be read manually at a later point.

    :return: None.
    """
    # Sort inbox, then act on it
    # Invert the inbox so we're processing oldest first!
{'fraction_non_alphanumeric': 0.08508323359808509, 'fraction_numerical': 0.0003264062670003264, 'mean_word_length': 2.347414420975965, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3347139', 'n_tokens_mistral': 2698, 'n_tokens_neox': 2620, 'n_words': 813}