Skip to main content
2 of 5
added 744 characters in body
Graipher
  • 41.1k
  • 7
  • 69
  • 133

My main comment is that you should separate the different concerns of you code into descriptive functions. This will make it a lot more readable (and re-usable).

One comment before I get started: Your login function, which looks like it would log you in with the reddit API seems to be unused atm. I guess this is a copy&paste error from censoring?


Your first concern is to log-in with gmail to get the mail object. This can be pasted directly into a separate function:

def mail_login():
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    while True:
        try:
            emailpass = getpass.getpass(
                'Please enter the password for xxxxxxx@xxxxx: ')
            mail.login('[email protected]', emailpass)
            break
        except imaplib.IMAP4.error:
            print('Incorrect password')
    mail.select("inbox")
    return mail

The second task, which is repeated quite often, is to print a message with the current timestamp preceeding it:

def log(text):
    print('\t{:%Y-%m-%d %H:%M:%S} - {}'.format(datetime.now(), text))

Note that I used the custom format options of str.format here.


Another task is to post an alert to reddit, once it is found:

def post_alert(alert, r):
    alert_text = """
    {}

     ********

     *^^I ^^am ^^a ^^bot. ^^For ^^any ^^questions, ^^comments, ^^or ^^concerns, ^^please ^^email [^^xxxxxxx@xxxxx](mailto://xxxxxxx@xxxxx)*
     """
    while True:
        try:
            r.submit(subreddit='xxxxxxxxxxxx', title=alert,
                     text=alert_text.format(alert))
            print('\t{}'.format(alert), end=' ')
            break
        except praw.errors.ExceptionList as e:
            log('Reddit error! {}'.format(e))
            time.sleep(300)

I build the alert text first and filled it with str.format and used the log function.


Final code:

import praw
import imaplib
import email
import time
import getpass
import RUAlerts
from datetime import datetime

app_id = 'xxxxxxxxxxxx'
app_secret = 'xxxxxxxxxxxx'
app_uri = 'xxxxxxxxxxxx'
app_scopes = 'account creddits edit flair history identity mysubreddits privatemessages read report save submit subscribe vote'
app_ua = 'xxxxxxxxxxxx'
app_account_code = 'xxxxxxxxxxxx'
app_refresh = 'xxxxxxxxxxxx'

class ShortTimeOut(Exception):
    pass


def login():
    r = praw.Reddit(app_ua)
    r.set_oauth_app_info(app_id, app_secret, app_uri)
    r.refresh_access_information(app_refresh)
    return r


def log(text):
    print('\t{:%Y-%m-%d %H:%M:%S} - {}'.format(datetime.now(), text))


def mail_login():
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    while True:
        try:
            emailpass = getpass.getpass(
                'Please enter the password for xxxxxxx@xxxxx: ')
            mail.login('[email protected]', emailpass)
            break
        except imaplib.IMAP4.error:
            print('Incorrect password')
    mail.select("inbox")
    return mail


def post_alert(alert, r):
    alert_text = """
    {}

     ********

     *^^I ^^am ^^a ^^bot. ^^For ^^any ^^questions, ^^comments, ^^or ^^concerns, ^^please ^^email [^^xxxxxxx@xxxxx](mailto://xxxxxxx@xxxxx)*
     """
    while True:
        try:
            r.submit(subreddit='xxxxxxxxxxxx', title=alert,
                     text=alert_text.format(alert))
            print('\t{}'.format(alert), end=' ')
            break
        except praw.errors.ExceptionList as e:
            log('Reddit error! {}'.format(e))
            time.sleep(300)


def search_for_alerts(mail):
    result, response = mail.uid('search', None, "(UNSEEN)")
    unread_msg_nums = response[0].split()

    result, data = mail.uid('search', None, "ALL")
    latest_email_uid = data[0].split()[-1]
    result, data = mail.uid('fetch', latest_email_uid, '(RFC822)')
    raw_email = data[0][1]

    email_message = email.message_from_bytes(raw_email)

    if unread_msg_nums:
        log('Something\'s wrong!')
        for part in email_message.walk():
            if part.get_content_type() == 'text/plain':
                yield part.get_payload()
    else:
        raise ShortTimeOut

def main():
    while True:
        try:
            r = RUAlerts.login()
            mail = mail_login()
            try:
                for alert in search_for_alerts(mail):
                    post_alert(alert, r)
            except ShortTimeOut:
                log('All clear on the RU front')
                time.sleep(30)
    
        except Exception as e:
            log("{}! Retrying in 5 minutes".format(e))
            time.sleep(300)

if __name__ == "__main__":
    main()
Graipher
  • 41.1k
  • 7
  • 69
  • 133