예제 #1
0
    def func_wrapper(script):
        """

        :param script:
        :type script:
        """
        my_diag = classes.Diagnostic(script=script)
        try:
            func()
            classes.LoggingDB().add_row_to_db(diagnostics=my_diag.make_dict(), passfail=1)
        except Exception as e:
            my_diag.traceback = e
            classes.LoggingDB().add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
예제 #2
0
def main():
    '''Main Script'''
    hist_db = classes.HistoryDB()
    today_list = hist_db.get_rows_by_date(get_todays_date())

    if len(today_list) == 0:
        my_diag = classes.Diagnostic(script=os.path.basename(__file__))
        my_diag.table = 'historymaps'
        log_db = classes.LoggingDB()
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=1)
        log_db.close()
        exit()

    maprow = random.choice(today_list)
    maprow.post_to_social_media(script=os.path.basename(__file__))
예제 #3
0
def test_add_entries(num_of_entries: int) -> None:
    """Tests methods for adding entries to database

    :param num_of_entries: How many entries to add
    :type num_of_entries: int

    """
    # Add random new entries to database
    init()
    print("Adding {} random entries to all databases for testing...".format(
        str(num_of_entries)))
    for _ in range(num_of_entries):
        rand_hist_id = functions.create_random_string(6)
        rand_soc_id = functions.create_random_string(6)
        rand_title = functions.create_random_string(10)
        rand_log_text = functions.create_random_string(11)
        rand_boolean = random.randint(0, 1)
        test_hist_db.add_row_to_db(raw_id=rand_hist_id,
                                   text=functions.create_random_string(10),
                                   day_of_year=random.randint(1, 365))
        my_diag_dic = classes.Diagnostic(
            script=(functions.create_random_string(8)) + '.py')
        my_diag_dic.raw_id = functions.create_random_string(6)
        my_diag_dic.severity = random.randint(1, 9)
        my_diag_dic.table = functions.create_random_string(6)
        my_diag_dic.traceback = functions.create_random_string(15)
        my_diag_dic.tweet = "http://" + str(functions.create_random_string(8))
        my_diag_dic.title = rand_title
        test_log_db.add_row_to_db(diagnostics=my_diag_dic.make_dict(),
                                  error_text=rand_log_text,
                                  passfail=rand_boolean)
        init()

        # Integrity checks will make sure all fresh == 0 rows include a date_posted.
        # This logic ensures that test won't fail.
        if rand_boolean == 0:
            date_posted = time.time()
        else:
            date_posted = 'NULL'
        test_soc_db.add_row_to_db(raw_id=rand_soc_id,
                                  text=functions.create_random_string(11),
                                  time_zone=random.randint(-10, 12),
                                  fresh=rand_boolean,
                                  date_posted=date_posted)
        test_jour_db.update_todays_status(benchmark_time=.5)
        test_close_all()
        init()
        if rand_boolean == 0:
            assert rand_log_text in str(
                test_log_db.get_fails_previous_24(current_time=time.time()))
            # TODO make a better assertion for checking diagnositcs in previous 24 hours
            assert my_diag_dic.raw_id in str(
                test_log_db.get_fails_previous_24(current_time=time.time()))
        elif rand_boolean == 1:
            assert rand_log_text in str(
                test_log_db.get_successes_previous_24(
                    current_time=time.time()))
            assert my_diag_dic.raw_id in str(
                test_log_db.get_successes_previous_24(
                    current_time=time.time()))
        assert test_soc_db.check_if_already_in_db(raw_id=rand_soc_id) is True
        assert test_soc_db.check_if_already_in_db(raw_id=rand_hist_id) is False
    test_close_all()
    init()
    test_row_count(delta=num_of_entries)
예제 #4
0
def main():
    """Main Script for posting congratulations."""
    my_diag = classes.Diagnostic(script=str(os.path.basename(__file__)))
    voting_post = get_raw_id()
    my_diag.raw_id = voting_post.id
    my_diag.title = "Contest Congratulations"
    bot_disclaimer_text = functions.bot_disclaimer()
    voting_post.mod.sticky(state=False)

    # # Turn contest mode OFF on the original voting post
    # Need to do this in order to count the votes, otherwise all posts show 1 vote.
    voting_post.mod.contest_mode(state=False)

    # Prepare the loop for parsing contestant maps
    # Prepare the text of the post.
    # Congratulations_text is a boilerplate template for each month's congratulations post.
    # There are a number of variables that need to be changed on this template though.
    # We will do that in the for loop.
    with open('Congratulations_text.txt', 'r') as f:
        congrats_data = str(f.read())

    # Prepare a regex script to find the unique ID on each comment.
    id_regex = re.compile(r'\^\^\^\^\w\w\w\w\w\w')

    # # The Loop
    # Gets top four highest upvoted comments and iterates thru them doing operations each time.
    yyyymm = 0
    for comment in voting_post.comments:
        score = int(comment.score)
        found_id = id_regex.search(comment.body)  # Find those ID's
        if found_id is None:
            continue
        message_id = str(found_id.group()).replace('^^^^', '')

        for obj in cont_db.current_list:
            if message_id == str(obj.raw_id):
                mapcomment = comment.reply("Map by: " + str(obj.author))
                mapcomment.mod.distinguish(how='yes')
                cont_db.add_vote_count_to_submission(raw_id=message_id,
                                                     votecount=score)
                yyyymm = int(obj.cont_date)

    n = 0
    winner, win_map_url = '', ''
    for obj in cont_db.get_sorted_top_of_month(month=yyyymm)[:4]:
        n += 1
        if n == 1:
            winner = obj.author
            win_map_url = obj.url
        congrats_data = congrats_data.replace(str('%' + str(n) + 'PLACEUSER%'),
                                              str(obj.author))
        congrats_data = congrats_data.replace(
            str('%' + str(n) + 'PLACEVOTES%'), str(obj.votes))
        congrats_data = congrats_data.replace(str('%' + str(n) + 'PLACEMAP%'),
                                              str(obj.map_name))
        congrats_data = congrats_data.replace(str('%' + str(n) + 'PLACEURL%'),
                                              str(obj.url))
    # # Post congratulations post to reddit

# Put the contest post URL into the congratulations template.
    congrats_data = congrats_data.replace('%VOTINGPOSTURL%',
                                          voting_post.shortlink)
    congrats_data = congrats_data.replace('%MYUSERID%', functions.my_reddit_ID)
    post_title = (
        'Congratulations to /u/{}: winner of {}\'s Monthly Map Contest!'.
        format(winner, contest_month_pretty))
    congrats_submission = r.subreddit('mapporn').submit(post_title,
                                                        selftext=congrats_data)
    congrats_shortlink = congrats_submission.shortlink
    congrats_submission.mod.distinguish()
    try:
        congrats_submission.mod.approve()
        congrats_submission.mod.sticky()
    except Exception as e:
        functions.send_reddit_message_to_self(
            title='Error encountered',
            message=('Could not sticky this post: {}    \n{}    \n\n'.format(
                congrats_shortlink, str(e))))

    # # Post congratulations post to social media
    # Download the image locally
    winning_image = 'temp.jpg'
    request = requests.get(win_map_url, stream=True)
    if request.status_code == 200:
        with open(winning_image, 'wb') as image:
            for chunk in request:
                image.write(chunk)
        filesize = os.path.getsize('temp.jpg')
        if filesize > 3070000:  # If it's too big social media sites won't like it.
            os.remove(winning_image)
            winning_image = 'misc_images/01.png'  # This is a backup image to post in lieu of the winning map.
    else:
        winning_image = 'misc_images/01.png'

    # Post to social media.
    # Now that we have the image we can run the function to post it to the social media sites
    try:
        generic_post = classes.GenericPost(filename=winning_image,
                                           title=(post_title + ' ' +
                                                  congrats_shortlink))
        social_media_dict = generic_post.post_to_all_social()
        functions.send_reddit_message_to_self(title='The new Congratulations post has just posted.',
                                              message='The congrats post is here:    {}\n    \n{}    \n{}')\
            .format(str(congrats_shortlink), str(voting_post.shortlink), str(social_media_dict['tweet_url']))
    except Exception as e:
        functions.send_reddit_message_to_self(
            title='Could not post to social media',
            message='Could not post announcement to socialmeda:    \n{}    \n\n'
            .format(str(e)))

    # # Send message to winner congratulating them
    congrats_message = (
        '[Congratulations, you won this month\'s Map Contest!](' +
        congrats_shortlink + ')    \n' + bot_disclaimer_text)
    try:
        r.redditor(winner).message('Congratulations', congrats_message)
    except Exception as e:
        functions.send_reddit_message_to_self(
            title='Could not send message to winner',
            message='Error: {}'.format(str(e)))
    log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=1)
예제 #5
0
def other_message(message) -> None:
    """Receives all other messages sent to bot, and passes it on to a human for further processing

    :param message: praw message object
    :type message: obj

    """
    msg = message.body
    author = str(message.author)
    subject = message.subject
    functions.send_reddit_message_to_self(
        title='Message sent to Bot, Please check on it',
        message='*/u/{author}* sent this message to the bot. '
        'Please check on it.    \n**Subject:**{subj}     \n**Message:**   \n'
        '{msg}'.format(author=author, subj=subject, msg=msg))
    message.mark_read()


if __name__ == '__main__':
    functions.check_for_word_and_process()
    new_message = False
    init()
    for _ in r.inbox.unread():
        new_message = True
    if new_message is False:
        mydiag = classes.Diagnostic(script=str(os.path.basename(__file__)))
        mydiag.traceback = "No New Mail"
        log_db.add_row_to_db(diagnostics=mydiag.make_dict(), passfail=1)
        exit()
    main()
예제 #6
0
def main():
    """Main script to check status"""
    my_diag = classes.Diagnostic(script=str(os.path.basename(__file__)))
    message = "**Daily Status Check**   \n   \n"

    # Check Soc Media DB Fresh Count
    fresh_count = soc_db.fresh_count
    if fresh_count <= 10:
        message += "* *NOTE: ONLY {} FRESH SOC MEDIA MAPS LEFT!* *   \n\n".format(
            fresh_count)
    else:
        message += "{maps} Maps Left   \nThat's {days} days, {hours} hours of content.    \n\n".format(
            maps=fresh_count,
            days=int(fresh_count / 8),
            hours=((fresh_count % 8) * 3))

    # Test Functions
    functions_result = test_functions()
    if functions_result == '':
        message += 'Functions Test Passed    \n'
    else:
        message += 'Functions Test Failed:    \n{}    \n\n'.format(
            functions_result)
    message += "    \n***    \n"

    # Test database integrity
    message += test_db_integrity()
    message += "    \n***   \n"

    # Create report of quantities for each time zone group
    message += functions.create_time_zone_table(soc_db.zone_dict)

    # Make posts older than a year fresh again
    if soc_db.fresh_count < 10:
        try:
            soc_db.make_fresh_again(current_time=int(time.time()), limit=10)
            message += "Ran the Make Fresh Again script   \n"
        except Exception as e:
            error_message = (
                "Could not run soc_db.make_fresh_again   \n{}   \n{}    \n".
                format(str(e), str(type(e))))
            my_diag.traceback = error_message
            my_diag.severity = 2
            log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
            my_diag = classes.Diagnostic(script=str(
                os.path.basename(__file__)))  # Re-initialize the diagnostic
            print(error_message)

    # Get failures from last 24 hours and report on them
    message += functions.fails_last_24_report(db_obj=log_db)

    # Can get successes from last 24 hours and report on them, but removed it because it is too much text
    # Use the function success_last_24_report(db_obj=log_db) if you'd like to bring it back

    # Check Where in the World
    message += check_where_in_world()

    # Check count of remaining where in world maps
    message += remaining_where_in_world()

    # Post stats on the map contest
    message += check_map_contest()

    # Test the database
    test_db_time, report = main_test_db()

    message += "    \n---------------    \n"
    message += "Test_DB benchmark time = {}   \n".format(test_db_time)
    message += "Total rows in Soc Media DB = {}   \n    \n".format(
        soc_db.rows_count)
    message += "Total rows in History DB = {}    \n    \n".format(
        hist_db.rows_count)
    message += report + "    \n"

    # Send results to myself on Reddit
    print(message)
    try:
        functions.send_reddit_message_to_self(title="Status Report",
                                              message=message)
    except Exception as e:
        message += "Could not send message on Reddit.    \n{}     \n{}".format(
            str(e), str(type(e)))
        with open('data/daily_status.txt', 'w') as text_file:
            text_file.write(message)

    # Make backup
    try:
        make_backup()
        print("Backing up Database to Google Drive")
    except Exception as e:
        error_message = ("Could not make backup!    \n{}    \n{}   \n".format(
            str(e), str(type(e))))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message)

    # Log success of script
    log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=1)
    log_db.close()
    journal_db.update_todays_status(benchmark_time=test_db_time)
예제 #7
0
def test_db_integrity():
    # TODO: add type annotation (waiting for rpi to upgrade to Python 3.6)
    """Tests integrity of databases

    :return: Error message
    :rtype: str

    """
    # Integrity Checks on databases
    init()
    error_message = ''
    my_diag = classes.Diagnostic(script=str(os.path.basename(__file__)))
    my_diag.traceback = 'test_db_integrity script'

    # hist_db_integrity check
    try:
        hist_db_integrity = hist_db.check_integrity()
        if hist_db_integrity.startswith("PASS"):
            error_message += " {}    \n".format(hist_db_integrity)
        else:
            error_message += "* *{}*   \n".format(hist_db_integrity)
    except Exception as e:
        error_message += (
            "Could not do hist_db Integrity Test    \n{}    \n{}".format(
                str(e), str(type(e))))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message)

    # soc_db_integrity check
    try:
        soc_db_integrity = soc_db.check_integrity()
        if soc_db_integrity.startswith("PASS"):
            error_message += " {}   \n".format(soc_db_integrity)
        else:
            error_message += "* *{}*   \n".format(soc_db_integrity)
    except Exception as e:
        error_message += (
            "Could not do soc_db Integrity Test   \n{}    \n{}    \n".format(
                str(e), str(type(e))))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message)

    # log_db_integrity check
    try:
        log_db_integrity = log_db.check_integrity()
        if log_db_integrity.startswith("PASS"):
            error_message += " {}    \n".format(log_db_integrity)
        else:
            error_message += "* *{}*   \n".format(log_db_integrity)
    except Exception as e:
        print(e)
        error_message += (
            "Could not do log_db Integrity Test    \n{}    \n{}    \n".format(
                str(e), str(type(e))))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message)

    # jour_db_integrity check
    try:
        jour_db_integrity = journal_db.check_integrity()
        if jour_db_integrity.startswith("PASS"):
            error_message += " {}    \n".format(jour_db_integrity)
        else:
            error_message += "* *{}*   \n".format(jour_db_integrity)
    except Exception as e:
        error_message += (
            "Could not do journal_db Integrity Test\n{}\n".format(
                str(e), str(type(e))))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message, my_diag)

    return error_message
예제 #8
0
def test_functions():
    # TODO Add type annotation
    """Tests functions

    :return: Error Message
    :rtype: str

    """
    init()
    error_message = ''
    my_diag = classes.Diagnostic(script=str(os.path.basename(__file__)))
    my_diag.traceback = 'test_function script'

    # Test Functions in Checkinbox.py
    try:  # Test get_time_zone()
        assert functions.get_time_zone('London') == 0
        assert functions.get_time_zone('909523[reteopipgfrtAfrica436i') == 1
        assert functions.get_time_zone('354tp4t[fds..dsfDenverre9sg') == -7
    except AssertionError as e:
        error_message += (
            "get_time_zone function not working    \n{}    \n".format(str(e)))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message)
    random_string = functions.create_random_string(10)
    try:
        assert functions.get_time_zone(random_string) == 99
    except AssertionError as e:
        error_message += (
            "get_time_zone function not working    \n{}    \n{}    \n".format(
                str(e), random_string))
        error_message += (
            "get_time_zone function not working    \n{}    \n".format(str(e)))
        my_diag.traceback = error_message
        my_diag.severity = 1
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic

    try:  # Test split_message()
        assert functions.split_message("https://redd.it/9cmxi1\ntext goes here\n12") == \
               ['https://redd.it/9cmxi1', 'text goes here', '12']
        assert functions.split_message("1\n2\n3") == ['1', '2', '3']
        assert functions.split_message('https://redd.it/9e6vbg') == [
            'https://redd.it/9e6vbg'
        ]
    except AssertionError as e:
        error_message += (
            "Could not run split_message() function   \n{}   \n\n".format(e))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        my_diag = classes.Diagnostic(script=str(
            os.path.basename(__file__)))  # Re-initialize the diagnostic
        print(error_message)

    # Test Functions in functions.py
    try:  # Test create_random_string() function
        for x in range(6, 15, 2):
            assert len(functions.create_random_string(x)) == x
    except AssertionError as e:
        error_message += (
            "create_random_string() test FAILED    \n{}    \n\n".format(e))
        my_diag.traceback = error_message
        my_diag.severity = 2
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)

        # Leaving this here in case more tests are added below
        my_diag = classes.Diagnostic(script=str(os.path.basename(__file__)))
        print(error_message, my_diag)

    return error_message