예제 #1
0
    def __init__(self):

        # list consisting of submissions that already proccessed but not emailed
        self.processed = []

        self.subreddits = settings.SUBREDDITS
        self.keywords = settings.KEYWORDS
        self.exclude = settings.EXCLUDE
        self.e = EmailHandler()
예제 #2
0
from bot import Bot
from emailhandler import EmailHandler

Bot.validate()
EmailHandler.register()
bot = Bot()
bot.run()
예제 #3
0
class Bot:
    def __init__(self):

        # list consisting of submissions that already proccessed but not emailed
        self.processed = []

        self.subreddits = settings.SUBREDDITS
        self.keywords = settings.KEYWORDS
        self.exclude = settings.EXCLUDE
        self.e = EmailHandler()

    @staticmethod
    def validate():
        try:
            if not bool(re.search('@gmail.com', settings.SENDER_EMAIL)):
                raise error.BotInvalidSenderEmail

            if not bool(re.search('@', settings.RECEPIENT_EMAIL)):
                raise error.BotInvalidRecepientEmail

            for subreddit in settings.SUBREDDITS:
                if str(subreddit) not in settings.KEYWORDS:
                    raise error.BotInvalidKeywords(
                        'Missing subreddit in keywords')

            if type(settings.SLEEP) != int:
                raise error.BotInvalidSleep

            if type(settings.KEYWORDS) != dict:
                raise error.BotInvalidKeywords(
                    'Invalid keywords data structure')

            if type(settings.EXCLUDE) != dict:
                raise error.BotInvalidExclude

            for subreddit, keywords_dict in settings.KEYWORDS.items():
                if type(subreddit) != str or type(keywords_dict) != dict:
                    raise error.BotInvalidKeywords(
                        'Invalid keywords data structure')
                for attribute, keyword in keywords_dict.items():
                    if type(attribute) != str or type(keyword) != list:
                        raise error.BotInvalidKeywords(
                            'Invalid keywords data structure')

            for subreddit, keywords_dict in settings.EXCLUDE.items():
                if type(subreddit) != str or type(keywords_dict) != dict:
                    raise error.BotInvalidExclude(
                        'Invalid exclude data structure')
                for attribute, keyword in keywords_dict.items():
                    if type(attribute) != str or type(keyword) != list:
                        raise error.BotInvalidExclude(
                            'Invalid exclude data structure')
        except AttributeError:
            print('Missing configuration, please check your settings')
            sys.exit()

    def log_match(self, subreddit, submission):
        print(
            str(datetime.datetime.now()) + " Match found in " + subreddit +
            " subreddit, adding result to mail ")
        print((str(datetime.datetime.now()) + ' title : ' + submission.title))
        print((str(datetime.datetime.now()) + ' url : ' + submission.url))

    def has_keyword(self, subreddit, submission):

        # get a dict of attributes and its keywords for current subreddit
        dict_of_keywords = self.keywords[subreddit]

        for attribute, keywords in dict_of_keywords.items():
            submission_attribute_value = getattr(submission, attribute).lower()

            for keyword in keywords:

                # each of submission attribute will be caselowered
                if keyword in submission_attribute_value \
                        and not self.has_exclude(subreddit, submission) == True \
                        and submission.id not in self.processed:
                    try:
                        keywords = "{'" + attribute + "': ['" + keyword + "']}"
                        self.e.add_header(keywords=keywords,
                                          subreddit=subreddit,
                                          exclude=str(self.exclude[subreddit]))
                    except KeyError:
                        keywords = "{'" + attribute + "': ['" + keyword + "']}"
                        self.e.add_header(keywords=keywords,
                                          subreddit=subreddit)
                    return True
            return False

    def has_exclude(self, subreddit, submission):

        try:
            dict_of_keywords = self.exclude[subreddit]
        except KeyError:
            return False

        for attribute, keywords in dict_of_keywords.items():
            submission_attribute_value = getattr(submission, attribute).lower()
            if any(keyword in submission_attribute_value
                   for keyword in keywords) == True:
                return True
        return False

    def process(self, connection):
        r = connection
        for subreddit in self.subreddits:
            subreddit_str = subreddit  # the subreddit string
            subreddit = r.get_subreddit(subreddit)  # this is an object

            try:  # connection error
                submissions = subreddit.get_hot(limit=50)
            except:
                print("Error has occured " + str(sys.exc_info()[0]))
                break

            for submission in submissions:
                has_keyword = self.has_keyword(subreddit=subreddit_str,
                                               submission=submission)

                if submission.id not in self.processed and has_keyword:
                    self.log_match(subreddit=subreddit_str,
                                   submission=submission)
                    self.e.add_result(submission=submission)
                    self.processed.append(submission.id)

            time.sleep(2)  # sleep between each subreddits

        if not self.e.content:
            print(
                str(datetime.datetime.now()) +
                " No match found, waiting for next run at " +
                str(datetime.datetime.now() +
                    datetime.timedelta(seconds=settings.SLEEP)))
        else:
            print(
                str(datetime.datetime.now()) + ' Sending results to ' +
                settings.RECEPIENT_EMAIL)
            self.e.send()
            print(
                str(datetime.datetime.now()) + ' Waiting for next run at ' +
                str(datetime.datetime.now() +
                    datetime.timedelta(seconds=settings.SLEEP)))

    def run(self):
        while True:
            try:  # connection error
                r = praw.Reddit(user_agent=settings.USER_AGENT)
            except:
                print("Error has occured " + str(sys.exc_info()[0]))
                break
            print(str(datetime.datetime.now()) + ' Starting bot')
            self.process(connection=r)
            time.sleep(settings.SLEEP)  # sleep between each run
예제 #4
0
def load_config():
    """
    Load handlers and other appropriate state.
    Returns a dict of handler identifier -> EmailHandler object
    """
    # globals shared among all handlers
    global target_class
    global target
    global default_interval

    scp = ConfigParser.SafeConfigParser()

    # bail on a bad read
    logger.info("Loading config.")
    if (scp.read(os.path.expanduser(config_file)) == []):
        print "Failed to read config file at %s." % config_file
        sys.exit(1)

    handlers = {}

    target = scp.get(global_section, "recipient")
    target_class = "MAIL"
    if scp.has_option(global_section, "class"):
        target_class = scp.get(global_section, "class")

    if scp.has_option(global_section, "interval"):
        default_interval = scp.getint(global_section, "interval")

    # loop through each account
    for section in scp.sections():
        if section == global_section: continue # zephyr is for globals
        
        logger.info("Parsing section %s." % section)
        kwargs = {}
        kwargs['server'] = server = scp.get(section, "server")
        use_gssapi = False
        kwargs['username'] = username = scp.get(section, "username")
        if scp.has_option(section, 'use_gssapi') and scp.getboolean(section, 'use_gssapi'):
            kwargs['use_gssapi'] = use_gssapi = True
            kwargs['username'] = kwargs['password'] = None
        else:
            if scp.has_option(section, "password"):
                password = scp.get(section, "password")
            else:
                password = getpass.getpass("Password for server %s, username %s: " % (server, username))

                kwargs['password'] = password
            
        # determine whether to use ssl; defaults to yes
    
        if scp.has_option(section, "ssl") and not scp.getboolean(section, "ssl"):
            ssl = False
            default_port = 143
        else:
            ssl = True
            default_port = 993

        kwargs['use_ssl'] = ssl

        if scp.has_option(section, "port"):
            port = scp.getint("port")
        else:
            port = default_port

        kwargs['port'] = port

        if scp.has_option(section, "interval"):
            interval = scp.getint(section, "interval")
        else:
            interval = default_interval

        interval = max(interval, 10) # don't want to be constantly checking.


        if scp.has_option(section, "regex"):
            is_regex = scp.get(section, "regex")
        else:
            is_regex = False

        if scp.has_option(section, "include"):
            include = scp.get(section, "include")
            if is_regex: include_re = include
            else: include_re = clude_to_re(include)
        else: include_re = "^.*$"

        if scp.has_option(section, "exclude"):
            exclude = scp.get(section, "exclude")
            if is_regex: exclude_re = exclude
            else: exclude_re = clude_to_re(exclude)
        else: exclude_re = "^$"

        kwargs['include'] = include_re
        kwargs['exclude'] = exclude_re

        
        logger.debug("Constructing handler for section %s: server %s, username %s, ssl %s, port %d, interval %d, is_regex %s, include_re %s, exclude_re %s, use_gssapi %s."
                     % (section, server, username, ssl, port, interval, is_regex, include_re, exclude_re, use_gssapi))
        handlers[section] = EmailHandler(**kwargs)
        handlers[section].interval = interval

    return handlers