<commit_before>"""
==========================================
Author:             <NAME>
Username:           /u/tylerbrockett
Description:        Alert Bot (Formerly sales__bot)
Date Created:       11/13/2015
Date Last Edited:   12/19/2016
Version:            v2.0
==========================================
"""

from utils import inbox, times
from bot_modules.sleep_handler import SleepHandler
from bot_modules.database_handler import DatabaseHandlerException
from utils.logger import Logger
from utils.color import Color
from accounts import accountinfo
from utils.subscription import Subscription
from parsing.message_parser import MessageParser
from parsing.message_lexer import MessageLexer
import json
import traceback


class InboxHandler:

    @staticmethod
    def handle_message_from_reddit(reddit, message):
        Logger.log('Message from reddit')
        reddit.send_message(accountinfo.developerusername, 'FWD: ' + message.subject, message.body)
        reddit.send_message(accountinfo.developerusername2, 'FWD: ' + message.subject, message.body)
        message.mark_as_read()

    @staticmethod
    def handle_statistics_message(database, message):
        Logger.log('Stats message')
        formatted_message = inbox.compose_statistics(
            str(message.author),
            database.count_current_users(),
            database.count_all_users(),
            database.count_unique_subscriptions(),
            database.count_all_subscriptions(),
            len(database.get_unique_subreddits()),
            database.count_total_matches(),
            database.get_unique_subreddits())
        message.reply(formatted_message)
        message.mark_as_read()

    @staticmethod
    def handle_get_subscriptions_message(database, message):
        Logger.log('Get subs message')
        subscriptions = database.get_subscriptions_by_user(str(message.author))
        formatted_message = inbox.compose_all_subscriptions_message(str(message.author), subscriptions)
        message.reply(formatted_message)
        message.mark_as_read()

    @staticmethod
    def handle_subscription_message(database, reddit, message, payload):
        Logger.log('Sub message')
        new_sub = Subscription(payload, str(message.author), message.id)
        existing_subs = database.get_subscriptions_by_user(str(message.author))
        if new_sub.status == Subscription.STATUS_INVALID:
            message.reply(inbox.compose_reject_message(str(message.author), message.subject, message.body))
            message.mark_as_read()
            return
        elif new_sub.status == Subscription.STATUS_TOO_GENERIC:
            message.reply(inbox.compose_too_generic_message(str(message.author)))
            message.mark_as_read()
            return
        duplicate_subs = new_sub.check_against_existing(existing_subs)
        if duplicate_subs:
            Logger.log('Subscription already exists', Color.RED)
            message.reply(inbox.compose_duplicate_subscription_message(
                str(message.author),
                duplicate_subs[0],
                new_sub))
            message.mark_as_read()
            return
        invalid_subreddits = reddit.check_invalid_subreddits(new_sub.data[Subscription.SUBREDDITS])
        if invalid_subreddits:
            Logger.log('Subreddit(s) invalid: ' + str(invalid_subreddits), Color.RED)
            message.reply(inbox.compose_invalid_subreddit_message(str(message.author), invalid_subreddits, message))
            message.mark_as_read()
            return
        database.insert_subscription(str(message.author), str(message.id), new_sub.to_string(), times.get_current_timestamp())
        existing_subs.append(new_sub)
        # TODO Remove subreddit not specified stuff, taken care of in SubscriptionParser.py
        subreddit_not_specified = len(new_sub.data[Subscription.SUBREDDITS]) == 0
        message.reply(inbox.compose_subscribe_message(str(message.author), new_sub, existing_subs, subreddit_not_specified))
        database.commit()
        message.mark_as_read()

    @staticmethod
    def handle_unsubscribe_message(reddit, database, message):
        Logger.log('Unsub message')
        message_id = reddit.get_original_message(message, database).id
        removed_subs = database.remove_subscriptions_by_message_id(str(message.author), message_id)
        subs = database.get_subscriptions_by_user(str(message.author))
        if len(removed_subs) > 0:
            message.reply(inbox.compose_unsubscribe_message(str(message.author), removed_subs, subs))
        else:
            message.reply(inbox.compose_unsubscribe_invalid_sub_message(str(message.author), subs))
        message.mark_as_read()

    @staticmethod
    def handle_unsubscribe_from_num_message(database, message, payload):
        Logger.log('Unsub from num')
        removed = database.remove_subscription_by_number(str(message.author), int(payload))
        subs = database.get_subscriptions_by_user(str(message.author))
        if removed:
            message.reply(inbox.compose_unsubscribe_from_num_message(str(message.author), removed, subs))
        else:
            message.reply(inbox.compose_unsubscribe_invalid_sub_message(str(message.author), subs))
        message.mark_as_read()

    @staticmethod
    def handle_edit_message(database, message, payload):
        Logger.log('Edit message')
        message.reply(inbox.compose_edit_message(str(message.author)))
        message.mark_as_read()

    # TODO Handle if there are 0 subs for user
    @staticmethod
    def handle_unsubscribe_all_message(database, message):
        Logger.log('Unsub all message')
        removed_subscriptions = database.remove_all_subscriptions(str(message.author))
        message.reply(inbox.compose_unsubscribe_all_message(str(message.author)))
        message.mark_as_read()

    @staticmethod
    def handle_help_message(database, message):
        Logger.log('Help message')
        subs = database.get_subscriptions_by_user(str(message.author))
        message.reply(inbox.compose_help_message(str(message.author), subs))
        message.mark_as_read()

    @staticmethod
    def handle_feedback_message(reddit, message):
        Logger.log('Feedback message')
        reddit.send_message(accountinfo.developerusername,  'FEEDBACK', inbox.compose_feedback_forward(accountinfo.developerusername, str(message.author), message.body))
        reddit.send_message(accountinfo.developerusername2, 'FEEDBACK', inbox.compose_feedback_forward(accountinfo.developerusername2, str(message.author), message.body))
        message.reply(inbox.compose_feedback_message(str(message.author)))
        message.mark_as_read()

    @staticmethod
    def handle_username_mention_message(reddit, message):
        Logger.log('Username mention message')
        reddit.send_message(accountinfo.developerusername, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername, str(message.author), message.body))
        reddit.send_message(accountinfo.developerusername2, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername2, str(message.author), message.body))
        message.reply(inbox.compose_username_mention_reply(str(message.author)))
        message.mark_as_read()

    @staticmethod
    def handle_post_reply_message(reddit, message):
        Logger.log('Post reply message')
        reddit.send_message(accountinfo.developerusername, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername, str(message.author), message.body))
        reddit.send_message(accountinfo.developerusername, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername2, str(message.author), message.body))
        message.mark_as_read()

    @staticmethod<commit_msg>Added handler for commenting too frequently<commit_after>"""
==========================================
Author:             <NAME>
Username:           /u/tylerbrockett
Description:        Alert Bot (Formerly sales__bot)
Date Created:       11/13/2015
Date Last Edited:   12/19/2016
Version:            v2.0
==========================================
"""

import praw
from praw import exceptions
from utils import inbox, times
from bot_modules.sleep_handler import SleepHandler
from bot_modules.database_handler import DatabaseHandlerException
from utils.logger import Logger
from utils.color import Color
from accounts import accountinfo
from utils.subscription import Subscription
from parsing.message_parser import MessageParser
from parsing.message_lexer import MessageLexer
import json
import traceback


class InboxHandler:

    @staticmethod
    def handle_message_from_reddit(reddit, message):
        Logger.log('Message from reddit')
        reddit.send_message(accountinfo.developerusername, 'FWD: ' + message.subject, message.body)
        reddit.send_message(accountinfo.developerusername2, 'FWD: ' + message.subject, message.body)
        message.mark_as_read()

    @staticmethod
    def handle_statistics_message(database, message):
        Logger.log('Stats message')
        formatted_message = inbox.compose_statistics(
            str(message.author),
            database.count_current_users(),
            database.count_all_users(),
            database.count_unique_subscriptions(),
            database.count_all_subscriptions(),
            len(database.get_unique_subreddits()),
            database.count_total_matches(),
            database.get_unique_subreddits())
        message.reply(formatted_message)
        message.mark_as_read()

    @staticmethod
    def handle_get_subscriptions_message(database, message):
        Logger.log('Get subs message')
        subscriptions = database.get_subscriptions_by_user(str(message.author))
        formatted_message = inbox.compose_all_subscriptions_message(str(message.author), subscriptions)
        message.reply(formatted_message)
        message.mark_as_read()

    @staticmethod
    def handle_subscription_message(database, reddit, message, payload):
        Logger.log('Sub message')
        new_sub = Subscription(payload, str(message.author), message.id)
        existing_subs = database.get_subscriptions_by_user(str(message.author))
        if new_sub.status == Subscription.STATUS_INVALID:
            message.reply(inbox.compose_reject_message(str(message.author), message.subject, message.body))
            message.mark_as_read()
            return
        elif new_sub.status == Subscription.STATUS_TOO_GENERIC:
            message.reply(inbox.compose_too_generic_message(str(message.author)))
            message.mark_as_read()
            return
        duplicate_subs = new_sub.check_against_existing(existing_subs)
        if duplicate_subs:
            Logger.log('Subscription already exists', Color.RED)
            message.reply(inbox.compose_duplicate_subscription_message(
                str(message.author),
                duplicate_subs[0],
                new_sub))
            message.mark_as_read()
            return
        invalid_subreddits = reddit.check_invalid_subreddits(new_sub.data[Subscription.SUBREDDITS])
        if invalid_subreddits:
            Logger.log('Subreddit(s) invalid: ' + str(invalid_subreddits), Color.RED)
            message.reply(inbox.compose_invalid_subreddit_message(str(message.author), invalid_subreddits, message))
            message.mark_as_read()
            return
        database.insert_subscription(str(message.author), str(message.id), new_sub.to_string(), times.get_current_timestamp())
        existing_subs.append(new_sub)
        # TODO Remove subreddit not specified stuff, taken care of in SubscriptionParser.py
        subreddit_not_specified = len(new_sub.data[Subscription.SUBREDDITS]) == 0
        message.reply(inbox.compose_subscribe_message(str(message.author), new_sub, existing_subs, subreddit_not_specified))
        database.commit()
        message.mark_as_read()

    @staticmethod
    def handle_unsubscribe_message(reddit, database, message):
        Logger.log('Unsub message')
        message_id = reddit.get_original_message(message, database).id
        removed_subs = database.remove_subscriptions_by_message_id(str(message.author), message_id)
        subs = database.get_subscriptions_by_user(str(message.author))
        if len(removed_subs) > 0:
            message.reply(inbox.compose_unsubscribe_message(str(message.author), removed_subs, subs))
        else:
            message.reply(inbox.compose_unsubscribe_invalid_sub_message(str(message.author), subs))
        message.mark_as_read()

    @staticmethod
    def handle_unsubscribe_from_num_message(database, message, payload):
        Logger.log('Unsub from num')
        removed = database.remove_subscription_by_number(str(message.author), int(payload))
        subs = database.get_subscriptions_by_user(str(message.author))
        if removed:
            message.reply(inbox.compose_unsubscribe_from_num_message(str(message.author), removed, subs))
        else:
            message.reply(inbox.compose_unsubscribe_invalid_sub_message(str(message.author), subs))
        message.mark_as_read()

    @staticmethod
    def handle_edit_message(database, message, payload):
        Logger.log('Edit message')
        message.reply(inbox.compose_edit_message(str(message.author)))
        message.mark_as_read()

    # TODO Handle if there are 0 subs for user
    @staticmethod
    def handle_unsubscribe_all_message(database, message):
        Logger.log('Unsub all message')
        removed_subscriptions = database.remove_all_subscriptions(str(message.author))
        message.reply(inbox.compose_unsubscribe_all_message(str(message.author)))
        message.mark_as_read()

    @staticmethod
    def handle_help_message(database, message):
        Logger.log('Help message')
        subs = database.get_subscriptions_by_user(str(message.author))
        message.reply(inbox.compose_help_message(str(message.author), subs))
        message.mark_as_read()

    @staticmethod
    def handle_feedback_message(reddit, message):
        Logger.log('Feedback message')
        reddit.send_message(accountinfo.developerusername,  'FEEDBACK', inbox.compose_feedback_forward(accountinfo.developerusername, str(message.author), message.body))
        reddit.send_message(accountinfo.developerusername2, 'FEEDBACK', inbox.compose_feedback_forward(accountinfo.developerusername2, str(message.author), message.body))
        message.reply(inbox.compose_feedback_message(str(message.author)))
        message.mark_as_read()

    @staticmethod
    def handle_username_mention_message(reddit, message):
        try:
            Logger.log('Username mention message')
            message.reply(inbox.compose_username_mention_reply(str(message.author)))
            message.mark_as_read()
        except praw.exceptions.APIException as e:
            Logger.log(Color.RED, str(e))
            Logger.log(Color.RED, 'Handled RateLimitExceeded praw error - Commenting too frequently')
        reddit.send_message(accountinfo.developerusername, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername, str(message.author), message.body))
        reddit.send_message(accountinfo.developerusername2, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername2, str(message.author), message.body))

    @staticmethod
    def handle_post_reply_message(reddit, message):
        Logger.log('Post reply message')
        reddit.send_message(accountinfo.developerusername, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername, str(message.author), message.body))
        reddit.send_message(accountinfo.developerusername, 'USERNAME MENTION', inbox.compose_username_mention_forward(accountinfo.developerusername2, str(message.author), message.body))
        message.mark_as_read()

    @staticmethod
{'fraction_non_alphanumeric': 0.09969257795344752, 'fraction_numerical': 0.003513394817742644, 'mean_word_length': 3.802651401024405, 'pattern_counts': {'":': 0, '<': 5, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1985445', 'n_tokens_mistral': 4488, 'n_tokens_neox': 4437, 'n_words': 699}