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.
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 LongTimeOut(Exception):
pass
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:
raise LongTimeOut(
'Reddit error! {}'.format(e))
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
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 LongTimeOut as e:
log('{} Retrying in 5 minutes'.format(e))
time.sleep(300)