Example #1
0
def contest_message(message, path: str = 'data/mapporn.db'):
    """Parse the praw message object and create a list for each map contest submission

    :param message: praw message object
    :type message: obj
    :param path: path to database (available for using a test database)

    """

    submission = functions.split_message(message.body)
    submission = [w.replace('Link:', '') for w in submission
                  ]  # Replace the title 'Link: ' with blankspace.
    submission = [w.replace('Map Name:', '') for w in submission]
    for i, v in enumerate(submission):
        submission[i] = submission[i].lstrip().rstrip()
    cont_db = classes.ContestDB(path=path)
    map_name = submission[0]
    url = submission[1]
    if url == 'http://imgur.com/replacethis.png':
        my_title = 'Problem with Map Contest Submission'
        my_message = 'There was a problem with your map contest submission for: ' + map_name + '   \n' + \
                  'The URL: ' + url + ' appears to be invalid.   \n' + \
                  '[Please resubmit your submission.](https://www.reddit.com/message/compose/?to=mappornbot&subject=' \
                  'Map%20Contest%20Submission&message=Map%20Name:%20Your%20Map%27s%20Name%0A%0ALink:%20' \
                  'http://imgur.com/replacethis.png%0A%0ADescription:%20Replace%20with%201-3%20Sentences.)'
        functions.send_reddit_message_to_user(title=my_title,
                                              message=my_message,
                                              user=str(message.author))
        message.mark_read()
        return
    if len(submission) > 3:
        submission[2] = str(submission[2]) + '\n' + str(submission[3])
    desc = submission[2]
    if desc.startswith("Description: "):
        desc = str(desc)[13:]
    author = message.author
    raw_id = str(message.id)
    my_list = [str(map_name), str(url), str(desc), str(author), str(raw_id)]

    my_table = "Title|Text\n-|-\n"
    my_table += "Map Name:|{}\n".format(str(map_name))
    my_table += "URL:|{}\n".format(str(url))
    my_table += "Desc:|{}\n".format(str(desc))
    my_table += "Author:|{}\n".format(str(author))
    my_table += "Raw ID:|{}\n".format(str(raw_id))
    if path == 'data/mapporn.db':
        functions.send_reddit_message_to_self(title='New Map Submitted!',
                                              message=my_table)

    row_obj = classes.ContRow(schema=cont_db.schema,
                              row=my_list,
                              table=cont_db.table,
                              path=path)
    row_obj.add_row_to_db(script=script)
    message.reply(MessageReply)
    message.mark_read()
Example #2
0
def dayinhistory_message(message, path: str = 'data/mapporn.db') -> None:
    """Parses dayinhistory message and adds it to HistoryDB

    :param message: Praw message object
    :type message: obj
    :param path: database path
    :type path: str

    """
    # Split message into a list
    dih_message = functions.split_message(message.body)
    day_of_year = ''
    raw_id = ''
    title = ''
    table = 'historymaps'
    # Parse Message
    for item in dih_message:

        try:
            item = int(item)
        except ValueError:
            pass
        if isinstance(item, int) and 0 < item < 366:
            day_of_year = item
        elif str(item).startswith("https://redd.it/"):
            raw_id = item.lstrip().rstrip()[-6:]
        else:
            title = item

    # Validate all parameters are included
    if title == '' or raw_id == '' or day_of_year == '':
        error_message = 'Error: Missing parameters \n'
        for line in dih_message:
            error_message += (line + '\n')
        functions.send_reddit_message_to_self(
            title='Error processing day in history', message=error_message)
        message.mark_read()
        return
    title = classes.ShotgunBlast.remove_text_inside_brackets(
        title.replace("\"", "'"))

    # Create MapRow and add to database
    my_maprow_list = [raw_id, title, day_of_year]
    my_maprow = classes.HistRow(schema=classes.schema_dict[table],
                                row=my_maprow_list,
                                table=table,
                                path=path)
    try:
        my_maprow.add_row_to_db(script=script)
    except Exception as e:
        functions.send_reddit_message_to_self(
            title='error adding to database',
            message="history Script Problem: {}   \n{}".format(e, script))
    message.mark_read()
Example #3
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()
Example #4
0
    def _parse_message(self):

        msg = functions.split_message(self.msg_obj.body)
        try:
            assert len(msg) == 2
        except AssertionError:
            functions.send_reddit_message_to_self(
                title="Error with Where World Inbox Check",
                message='Length of message not two lines.')
            self.script_execution = False
            return False
        if msg[0].startswith("http"):
            self.url = msg[0]
            self.answer_text = msg[1]
        else:
            self.url = msg[1]
            self.answer_text = msg[0]
def main() -> str:
    """Main script to run voting post

    :returns: shortlink to voint post
    :rtype: str

    """
    error_message = ''
    year_voting_text = prepare_voting_text()
    submission = r.subreddit(subreddit).submit(post_message, selftext=year_voting_text)  # Submits the post to Reddit
    submission.mod.contest_mode()
    submission.mod.distinguish()
    shortlink = submission.shortlink
    functions.send_reddit_message_to_self(title='Reminder', message='[Remember to request Reddit Gold]'
                                                                    '(https://redd.it/a335e1)    +\n/r/MapPorn '
                                                                    '/u/Petrarch1603 ' + shortlink)
    title_to_finalist = 'The Annual Best Map of the Year contest is now live!'
    message_to_finalist = ('**The Annual Best Map of the Year contest is now live!**    \nThank you for contributing a '
                           'map. [The voting on the contest is open now at this link.](' + shortlink + ')    \n' +
                           bot_disclaimer_text)

    authors_list = []
    for map_row in finalists_list:
        submission.reply('[' + str(map_row.map_name) + '](' + str(map_row.url) + ')   \n'
                         '' + str(map_row.desc) + '\n\n----\n\n^^^^' + str(map_row.raw_id))
        authors_list.append(map_row.author)

    authors_list = set(authors_list)  # This will remove duplicate names from the authors list
    if dryrun is False:
        print('Sending message to a user')
        for author in authors_list:
            try:
                r.redditor(author).message(title_to_finalist, message_to_finalist)
            except Exception as ee:
                error_message += 'Error sending message to ' + author + '   \n' + str(ee)
    generalcomment = submission.reply('General Comment Thread')
    generalcomment.mod.distinguish(sticky=True)
    generalcomment.reply('**What is with the ^^^small characters?**    \nThis contest is automated with a bot. The bot '
                         'uses these random characters to index the maps and to calculate the winner at the end of the '
                         'contest.\n\n----\n\n ^^^[Github](https://github.com/petrarch1603/MapPornBot)')
    if error_message != '':
        functions.send_reddit_message_to_self(title="error", message=error_message)
    submission.mod.approve()  # Unsure if these two work
    submission.mod.sticky()
    return shortlink
def post_advertisement_to_soc_media(shortlink: str, image_file_name: str = '') -> str:
    """Advertises the voting contest on social media


    :param image_file_name: path to image that is to be posted to social media, default is none.
    :type image_file_name: str

    :param shortlink: shortlink to Reddit contest
    :type shortlink: str

    :return: URL to advertisement Tweet
    :rtype: str

    """
    error_message = ''
    post_message_with_url = (post_message + '\n' + shortlink + '\n#MapPorn #Cartography #Contest')

    if image_file_name == '':
        # Get random image_file_name from the directory of vote images.
        imagecount = len([name for name in os.listdir('voteimages/')])  # counts how many images are in the directory
        randraw = random.randint(1, imagecount)  # Creates a random number between 1 and the image count.

        # Return a random number with a leading zero if necessary. (i.e. 02 instead of 2)
        image_file_name = str(randraw).zfill(2)

        # Look in the directory and create a list of files with the name of the image.
        image_file_name = fnmatch.filter(os.listdir('voteimages/'), image_file_name + '.*')
        image_file_name = image_file_name[0]

        # Post to social media
        image_file_name = ('voteimages/' + image_file_name)
    try:
        social_media_post = classes.GenericPost(filename=image_file_name, title=post_message_with_url)
        socialmediadict = social_media_post.post_to_all_social()
        functions.send_reddit_message_to_self('New Voting Post Posted',
                                              'A new votingpost.py has been run. Check the post to make'
                                              ' sure the bot did it right.   \nHere\'s the link to the '
                                              'post: ' + shortlink + '   \nHere\'s the social media '
                                              'links:    \n' + str(socialmediadict['tweet_url']))
        return str(socialmediadict['tweet_url'])
    except Exception as eee:
        error_message += "Could not post results to social media.   \n{}    \n\n".format(str(eee))
    if error_message != '':
        functions.send_reddit_message_to_self(title="error", message=error_message)
Example #7
0
 def _download_image(self):
     try:
         assert len(str(self.next_date)) == 4
     except AssertionError:
         functions.send_reddit_message_to_self(
             title="Error with Where World Check inbox",
             message="Problem getting file name right, cannot"
             "download image.")
         self.script_execution = False
         return False
     req = requests.get(self.url)
     my_file_name = 'WW/' + str(self.next_date) + '.png'
     print("New File Name: " + str(my_file_name))
     with open(my_file_name, 'wb') as f:
         f.write(req.content)
     fsize = os.stat(my_file_name).st_size
     if fsize >= 3200000:
         functions.send_reddit_message_to_self(title='ww error',
                                               message='image too big!')
     print('Finished Downloading')
Example #8
0
def main():
    """Main script for posting the weekly mystery map to social media."""
    image_number = str(get_image_name())
    image_file_name = image_number + '.png'
    print("Looking for image: " + str(image_file_name))

    try:
        # Post to Social Media
        os.chdir('WW')

        socmediadict = classes.GenericPost(image_file_name, post_message).post_to_all_social()
        my_diag.tweet = socmediadict['tweet_url']
        os.chdir('..')

    except tweepy.error.TweepError as e:
        if str(e) == 'Unable to access file: No such file or directory':
            os.chdir('..')
            error_message = "No where in the world maps left. Add more!     \n{}    \n\n".format(e)
            my_diag.traceback = error_message
            functions.send_reddit_message_to_self(title="No where world maps left", message=error_message)
            log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
        else:
            error_message = e
            my_diag.traceback = error_message
            functions.send_reddit_message_to_self(title='ERROR posting Where World', message=str(error_message))
            log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
    except Exception as e:
        os.chdir('..')
        my_diag.traceback = "error:    \n{}    \n\n".format(e)
        my_diag.severity = 2
        functions.send_reddit_message_to_self(title="Error with WhereWorld", message=my_diag.traceback)
        log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=0)
    with open('data/locations.csv') as current_csv:
        csvreader = csv.reader(current_csv)
        for row in csvreader:
            try:
                if image_number == row[0]:
                    true_location = row[1]
                    functions.send_reddit_message_to_self(
                        title="Where in world answer",
                        message='The correct location is: ' + str(true_location) + '    '
                                                                                   '\nThe Twitter thread is here: ' +
                                str(my_diag.tweet))
            except Exception as e:
                print(str(e))
    log_db.add_row_to_db(diagnostics=my_diag.make_dict(), passfail=1)
Example #9
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)
Example #10
0
            print('Error encountered: \n' + str(shotgun_error))
            return stack
    else:
        print('Stack Empty!')
        return stack


mapstackold = postsocmedia(mapstackold)

# Post another map if the stack has more than two days worth of maps.
if mapstackold.size() > 50 and mapstackold.size() % 2 == 0:
    mapstackold = postsocmedia(mapstackold)

if mapstackold.size() <= 2:
    send_reddit_message_to_self(
        "Stack size at 2",
        "Stack size at 2, consider adding some more maps to the stack.")

# Check Messages for new maps to add to Stack
for message in r.inbox.unread():
    newMessage = 'true'
if newMessage is 'false':
    logdict['time'] = time.time()
    logdict['type'] = 'noNewMail'
    addToMongo(logdict)

for message in r.inbox.unread():
    if message.subject == "socmedia":
        logdict['type'] = 'socmediastack'
        logdict['time'] = time.time()
        socmediamap = message.body
Example #11
0
def socmedia_message(message, path: str = 'data/mapporn.db'):
    """Parses social media message and adds it to SocMediaDB

    :param message: Praw message object
    :type message: obj
    :param path: path to database
    :type path: str

    """
    socmediamap = functions.split_message(message.body)
    for i, v in enumerate(socmediamap):
        socmediamap[i] = socmediamap[i].lstrip().rstrip()

    # Verify that there is a Reddit shortlink in the message
    try:
        assert socmediamap[0].startswith("https://redd.it/")
    except Exception as e:
        error_message = (
            "Error detected: Message does not include a valid URL   \n{}   \n\n"
            .format(e) + str(message.body))
        functions.send_reddit_message_to_self(title="Socmedia Message Error",
                                              message=error_message)
        message.mark_read()
        return

    # Get raw_id and set default values for fresh_status and date_posted
    raw_id = socmediamap[0][-6:]
    fresh_status = 1
    date_posted = 'NULL'
    post_error = 0
    table = 'socmediamaps'

    # Get title and clean it up - adjust fresh status if third line is 0
    if len(socmediamap) > 2 and str(socmediamap[2]) == '0':
        fresh_status = 0
        date_posted = int(time.time())
        title = socmediamap[1]
    elif len(socmediamap) > 1:
        title = socmediamap[1]
    else:
        r = praw.Reddit(
            'bot1'
        )  # Leave this line for testing (need to patch this call in unittests)
        title = r.submission(id=raw_id).title

    # Remove double quotes, very important for inserting into database
    title = classes.ShotgunBlast.remove_text_inside_brackets(
        title.replace("\"", "'"))

    # Get time_zone
    time_zone = functions.get_time_zone((functions.strip_punc(title)))
    if time_zone == 99 and path == 'data/mapporn.db':
        my_message = ("No time zone parsed from this title.    \n"
                      "Check it and see if there are any "
                      "locations to add to the CSV.    \n" + str(title) +
                      "   \n" + str(soc_db.fresh_count))
        functions.send_reddit_message_to_self(title="No time zones found",
                                              message=my_message)

    # Put all the variables in the list to pass to MapRow
    my_maprow_list = [
        raw_id, title, time_zone, fresh_status, date_posted, post_error
    ]

    # Create MapRow Object and add to database
    my_maprow = classes.SocRow(schema=classes.schema_dict[table],
                               row=my_maprow_list,
                               table=table,
                               path=path)
    try:
        my_maprow.add_row_to_db()
    except Exception as e:

        functions.send_reddit_message_to_self(
            title='error adding to database',
            message="Socmedia Script Problem: {}   "
            "\n{}    \n{}".format(e, script, my_maprow_list))
    message.mark_read()
Example #12
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)
Example #13
0
def main():
    """Main script to prepare and post voting post for Map Contest"""
    error_message = ''
    voting_text = prepare_voting_text()
    date_7_days_ago = datetime.now() - timedelta(days=7)
    contest_month = date_7_days_ago.strftime("%B")
    contest_year = date_7_days_ago.date().year
    month_year = (str(contest_month) + ' ' + str(contest_year))
    post_message = ('Vote Now for the ' + month_year + ' Map Contest!')
    yyyymm = int(str(contest_year) + str(date_7_days_ago.strftime("%m")))

    submission = r.subreddit('mapporn').submit(post_message, selftext=voting_text)  # Submits the post to Reddit
    submission.mod.contest_mode()
    submission.mod.distinguish()
    shortlink = submission.shortlink

    my_urls_list = []  # List of urls of all maps being submitted, used to make grid collage

    # Post each map as a comment
    for obj in cont_db.live_list:
        submission.reply('[' + str(obj.map_name) + '](' + str(obj.url) + ')   \n'
                         '' + str(obj.desc) + '\n\n----\n\n^^^^' + str(obj.raw_id))

        # Send a message to each contestant letting them know it's live.
        try:
            r.redditor(obj.author).message('The monthly map contest is live!',
                                           'Thank you for contributing a map. '
                                           '[The voting on the monthly contest is '
                                           'open now at this link.](' + shortlink + ')    \n' + botDisclaimerText)
        except praw.exceptions.APIException as e:
            print('Could not send message to ' + obj.author + '   \n' + str(e))
        try:
            cont_db.add_date_to_submission(raw_id=obj.raw_id, yearmonth=yyyymm)
        except Exception as e:
            functions.send_reddit_message_to_self(title='Voting post error',
                                                  message="could not add contest date "
                                                          "to {}\n    {}".format(obj.raw_id, e))
        my_urls_list.append(obj.url)  # Add URL to list for getting the grid collage

    # General Comment Thread so people don't post top level comments
    generalcomment = submission.reply('General Comment Thread')
    generalcomment.mod.distinguish(sticky=True)
    generalcomment.reply('**What is with the ^^^small characters?**    \n'
                         'This contest is automated with a bot. The bot uses these random characters to index the maps '
                         'and to calculate the winner at the end of the contest.\n\n----\n\n'
                         '^^^[Github](https://github.com/petrarch1603/MapPornBot)')

    # # Need to save the voting post raw_id for use in parsing the winner after a few days.
    raw_id = submission.id_from_url(shortlink)
    file = open('data/votingpostdata.txt', 'w')
    file.write(raw_id)
    file.close()

    # Advertise Contest on Social Media
    # TODO need to make sure all urls are image files...jpg, jpeg, png etc.
    print("Attempting to post on social media....")
    try:
        functions.advertise_on_socmedia(list_of_urls=my_urls_list, month_year=month_year, voting_url=shortlink)
    except Exception as e:
        print('Could not advertise on social media. Exception:  ' + str(e))

    try:
        submission.mod.approve()
    except Exception as e:
        print('Could not approve post. Exception: ' + str(e))
    try:
        submission.mod.sticky()
    except Exception as e:
        print('Could not sticky post. Exception: ' + str(e))
    print(error_message)

    try:
        cont_db.close()
        refreshed_cont_db = classes.ContestDB()
        assert refreshed_cont_db.current_count == numbersubmitted
    except AssertionError:
        functions.send_reddit_message_to_self(title="Error with current count",
                                              message="The current count in the ContestDB does not equal the number of"
                                                      "maps being voted on.")
    bot_disclaimer_text = functions.bot_disclaimer()
    contest_year = (datetime.now() - timedelta(days=10)).year
    cont_db = classes.ContestDB()
    finalists_list = cont_db.get_top_posts_of_year()

    # Verify that all the finalist maps have valid URLs:
    for obj in finalists_list:
        if urllib.request.urlopen(obj.url).getcode() != 200:
            finalists_list.remove(obj)

    post_message = 'Vote Now for the best map of ' + str(contest_year) + '!'
    r = praw.Reddit('bot1')
    shortlink = main()
    print(shortlink)

    # Create Grid Collage
    my_urls = []
    for i in finalists_list:
        my_urls.append(i.url)

    try:
        collage_filepath: str = GridCollage.create_grid(url_list=my_urls, text_content="Best of " + str(contest_year))
    except Exception as e:
        functions.send_reddit_message_to_self(title="Cannot create Grid Collage",
                                              message="Exception: " + str(e))
        collage_filepath = ''
    if dryrun is False:
        print(post_advertisement_to_soc_media(shortlink=shortlink, image_file_name=collage_filepath))
    else:
        print("Collage filepath: " + collage_filepath)
cont_db = classes.ContestDB()

date_10_days_ago = datetime.now() - timedelta(days=10)

if len(sys.argv) > 1 and sys.argv[1] == 'year':
    end_of_year = True
    finalists_list = cont_db.get_top_posts_of_year()
    contest_month_pretty = "Best of " + str(date_10_days_ago.year)
    votingpostdata = open('data/votingpostdata.txt', 'r')
elif len(sys.argv) == 1:
    end_of_year = False
    finalists_list = cont_db.current_list
    contest_month_pretty = str(date_10_days_ago.strftime("%B")) + "\'s Monthly"
    votingpostdata = open('data/votingpostdata.txt', 'r')
else:
    functions.send_reddit_message_to_self(
        title="error in script", message="illegal number of sysargv's ")
    exit()


def get_raw_id() -> object:
    """Get the raw ID of the voting post.

    :return: PRAW Object
    :rtype: object

    """
    raw_id = (votingpostdata.read())
    return r.submission(id=raw_id)


def main():