root/webmail.py

Revision 3, 4.0 kB (checked in by davea, 3 years ago)

re-jig to use mod_python instead of CGI. now does proper authentication, meaning anyone with a valid IMAP account can login

Line 
1 #!/usr/bin/env python
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       # get the message
58       msg = self.server.fetch(mid, "(FLAGS BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])")
59      
60       # highlight the row if this is an unseen or deleted message
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       # parse headers
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       # output the message line
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)
Note: See TracBrowser for help on using the browser.