| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
import imaplib |
|---|
| 4 |
import email |
|---|
| 5 |
import email.Utils |
|---|
| 6 |
import re |
|---|
| 7 |
import os |
|---|
| 8 |
import sys |
|---|
| 9 |
|
|---|
| 10 |
import wmutils |
|---|
| 11 |
|
|---|
| 12 |
class Webmail: |
|---|
| 13 |
def __init__(self, user, passwd, req): |
|---|
| 14 |
self.req = req |
|---|
| 15 |
|
|---|
| 16 |
self.server = imaplib.IMAP4_SSL("sucs.org") |
|---|
| 17 |
self.server.login(user, passwd) |
|---|
| 18 |
|
|---|
| 19 |
self.server.select("INBOX") |
|---|
| 20 |
self.current_folder = "INBOX" |
|---|
| 21 |
|
|---|
| 22 |
self.mail_folders = [] |
|---|
| 23 |
pattern = re.compile("\([^)]*\) \"/\" (.*)") |
|---|
| 24 |
for folder in self.server.lsub()[1]: |
|---|
| 25 |
matches = pattern.match(folder) |
|---|
| 26 |
if len(matches.groups()) >= 1: |
|---|
| 27 |
name = matches.group(1).replace('"', '') |
|---|
| 28 |
unread = int(self.server.status(name, "(UNSEEN)")[1][0].replace('"%s" (UNSEEN ' % name, "").replace(")", "")) |
|---|
| 29 |
self.mail_folders.append((name, unread)) |
|---|
| 30 |
self.mail_folders.sort() |
|---|
| 31 |
|
|---|
| 32 |
def get_folders(self): |
|---|
| 33 |
ret_string = "<div class='folders'>" |
|---|
| 34 |
ret_string += "<b>Folder List</b><br />" |
|---|
| 35 |
for name, unread in self.mail_folders: |
|---|
| 36 |
if unread > 0: |
|---|
| 37 |
ret_string += "<b><a href='?folder=%s'>%s (%d)</a></b><br />" % (name, name, unread) |
|---|
| 38 |
else: |
|---|
| 39 |
ret_string += "<a href='?folder=%s'>%s</a><br />" % (name, name) |
|---|
| 40 |
ret_string += "</div>" |
|---|
| 41 |
ret_string += "<hr />" |
|---|
| 42 |
return ret_string |
|---|
| 43 |
|
|---|
| 44 |
def get_messages(self): |
|---|
| 45 |
ret_string = "<div class='messagelist'>" |
|---|
| 46 |
ret_string += "<table>" |
|---|
| 47 |
messages = self.server.search(None, "(ALL)")[1][0].split(' ') |
|---|
| 48 |
messages.reverse() |
|---|
| 49 |
p = re.compile("[0-9]+ \(FLAGS \(([^\)]*)\) INTERNALDATE \"([^\"]*)\".*") |
|---|
| 50 |
if self.req.form.has_key("start"): |
|---|
| 51 |
start = int(self.req.form['start'].value) |
|---|
| 52 |
else: |
|---|
| 53 |
start = 0 |
|---|
| 54 |
for mid in messages[start:start+50]: |
|---|
| 55 |
if mid == "": |
|---|
| 56 |
continue |
|---|
| 57 |
|
|---|
| 58 |
msg = self.server.fetch(mid, "(FLAGS BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])") |
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
if msg[1][0][0].count("\\Seen") == 0: |
|---|
| 62 |
msg_class = "msg_row_unseen" |
|---|
| 63 |
elif msg[1][0][0].count("\\Deleted") > 0: |
|---|
| 64 |
msg_class = "msg_row_deleted" |
|---|
| 65 |
else: |
|---|
| 66 |
msg_class = "msg_row" |
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 |
for header in msg[1][0][1].splitlines(): |
|---|
| 70 |
if header.startswith("From: "): |
|---|
| 71 |
msg_from = wmutils.get_from_addr(header[6:]) |
|---|
| 72 |
elif header.startswith("Subject: "): |
|---|
| 73 |
msg_subject = header[9:] |
|---|
| 74 |
elif header.startswith("Date: "): |
|---|
| 75 |
try: |
|---|
| 76 |
msg_date = email.Utils.formatdate(email.Utils.mktime_tz(email.Utils.parsedate_tz(header[6:])), True) |
|---|
| 77 |
except OverflowError, e: |
|---|
| 78 |
msg_date = header[6:] |
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
ret_string += "<tr onclick='javascript:load_msg(\"%s\", \"%s\")' id='msg%s' class='%s'><td>%s</td><td>%s</td><td>%s</td></tr>" % (mid, self.current_folder, mid, msg_class, msg_date, msg_from, msg_subject) |
|---|
| 82 |
|
|---|
| 83 |
ret_string += "</table>" |
|---|
| 84 |
ret_string += "</div>" |
|---|
| 85 |
return ret_string |
|---|
| 86 |
|
|---|
| 87 |
def get_message(self, id): |
|---|
| 88 |
ret_string = "" |
|---|
| 89 |
ret_string += "<div class='message'>" |
|---|
| 90 |
ret_string += "<table>" |
|---|
| 91 |
msg = email.message_from_string(self.server.fetch(str(id), "(RFC822)")[1][0][1]) |
|---|
| 92 |
ret_string += "<tr><td>From:</td><td>%s</td><td>Date:</td><td>%s</td></tr>" % (wmutils.get_from_addr(msg['from']), msg['date']) |
|---|
| 93 |
ret_string += "<tr><td>Subject:</td><td colspan='3'>%s</td></tr>" % msg['subject'] |
|---|
| 94 |
if msg.is_multipart(): |
|---|
| 95 |
msgbody = "" |
|---|
| 96 |
for part in msg.walk(): |
|---|
| 97 |
if part.get_content_type() == "text/plain": |
|---|
| 98 |
msgbody += wmutils.wrap(part.get_payload(), 80) |
|---|
| 99 |
msgbody += "\n== NEXT PART ==\n" |
|---|
| 100 |
else: |
|---|
| 101 |
msgbody += part.get_content_type() |
|---|
| 102 |
msgbody += "\n== NEXT PART ==\n" |
|---|
| 103 |
else: |
|---|
| 104 |
msgbody = wmutils.wrap(msg.get_payload(), 80) |
|---|
| 105 |
ret_string += "<tr><td colspan='4'><pre>%s</pre></td></tr>" % msgbody |
|---|
| 106 |
ret_string += "</table>" |
|---|
| 107 |
return ret_string |
|---|
| 108 |
|
|---|
| 109 |
def set_folder(self, folder=None): |
|---|
| 110 |
if folder is None: |
|---|
| 111 |
self.server.select() |
|---|
| 112 |
self.current_folder = "INBOX" |
|---|
| 113 |
else: |
|---|
| 114 |
self.server.select(folder) |
|---|
| 115 |
self.current_folder = str(folder) |
|---|