Saturday, March 15, 2008

imap.py

Fed up with being limited to a GUI or Curses for mail access (my jailbroken iPod touch doesn't have a good VT), I decided to write an e-mail checker for IMAP over SSL. My checker gets all mail, but truncates the sender, subject, and date. In order to get it to sort by date, I had to work some regex magic with dates. In order to make use of it, you'll need to set the 'server' and 'username' strings.

imap.py

import re
import getpass, imaplib
from email.feedparser import FeedParser
import sys
import email.message
import datetime

add = re.compile('<([^>]+)>')
nl = re.compile('[\n\r]+')
spc = re.compile('^\s+')
dte = re.compile('^\s*[A-z]+,\s+([0-9]{1,2})\s+([A-z]+)\s+([0-9]{4})\s+([0-9]{2}):([0-9]{2}):([0-9]{2})')
months = {'Jan' : 1, 'Feb' : 2, 'Mar' : 3, 'Apr' : 4, 'May' : 5, 'Jun' : 6, 'Jul' : 7, 'Aug' : 8, 'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12}




M = imaplib.IMAP4_SSL('server', 993)
M.login('username', getpass.getpass())
M.select()
typ, data = M.search(None, 'ALL')
mails = {}
for num in data[0].split():
parse = FeedParser()
typ, data = M.fetch(num, '(RFC822)')
#print 'Message %s\n%s\n' % (num, data[0][1])
parse.feed(data[0][1])
msg = parse.close()
subject = msg['Subject']
frm = msg['From']
date = msg['Date']
content = ''
#tmp = msg.get_payload(0)
tmp = msg
while isinstance(tmp, email.message.Message):
if tmp.is_multipart():
tmp = tmp.get_payload(0)
else:
tmp = tmp.get_payload()
content = tmp
m = dte.search(date)
if m:
parts = m.groups()
dt = datetime.datetime(int(parts[2]), months[parts[1]], int(parts[0]), int(parts[3]), int(parts[4]), int(parts[5]))
mails[dt] = subject, frm, content, dt

s = mails.keys()
s.sort(reverse = True)

for i in s:
subject, frm, content, dt = mails[i]
m = add.search(frm)
if len(frm) > 40 and m:
frm = m.group(1)
if len(frm) > 20:
frm = frm[0:20] + '...'
content = nl.sub('', content)
content = spc.sub('', content)
print '- ' + (len(subject) > 40 and (subject[0:40] + '...') or subject) + '\n ' + frm + '\n ' + (len(content) > 40 and (content[0:40] + '...') or content) + '\n'
M.close()
M.logout()/

No comments: