summaryrefslogtreecommitdiffstats
path: root/modules/mail.py
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mail.py')
-rw-r--r--modules/mail.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/modules/mail.py b/modules/mail.py
new file mode 100644
index 0000000..790845d
--- /dev/null
+++ b/modules/mail.py
@@ -0,0 +1,116 @@
+import re
+import os
+import gzip
+import stat
+import email
+import urllib2
+import logging
+
+from os.path import join, exists, dirname, isdir
+from mailbox import UnixMailbox
+from datetime import datetime, timedelta
+
+from devshell import DEVSHELL_DIR
+
+log = logging.getLogger(__name__)
+
+class Mail:
+ """ A module for searching/viewing mailing lists """
+
+ url = 'https://www.redhat.com/archives/%s/%s'
+
+ def search(self, mailinglist, text):
+ """ <list> <text>. Search specific mailing list for given text """
+ now = datetime.now()
+ while True:
+ fetch = True
+ filename = now.strftime("%Y-%B") + '.txt.gz'
+ try:
+ f = urllib2.urlopen(self.url % (mailinglist, filename))
+ except urllib2.HTTPError:
+ break
+ local = join(DEVSHELL_DIR, mailinglist, filename)
+
+ # Don't fetch the mbox if we already have a good local copy
+ if exists(local):
+ info = os.stat(local)
+ if info[stat.ST_SIZE] == int(f.headers.get('Content-Length')):
+ fetch = False
+ log.debug("Using local mbox: %s" % local)
+ if fetch:
+ if not exists(dirname(local)):
+ os.makedirs(dirname(local))
+ mbox = file(local, 'w')
+ log.debug("Downloading %s" % local)
+ mbox.write(f.read())
+ mbox.close()
+ f.close()
+
+ self.__search_mbox(local, text)
+
+ # Go back in time
+ now = now - timedelta(days=31)
+
+ def __search_mbox(self, mboxfile, text):
+ """
+ Search a compressed mbox for any specified keywords
+ """
+ num = 0
+ statinfo = os.stat(mboxfile)
+ gzmbox = gzip.open(mboxfile)
+ mbox = UnixMailbox(gzmbox, email.message_from_file)
+ while True:
+ msg = mbox.next()
+ if not msg: break
+ num += 1
+ fields = [msg['From'], msg['Subject']] + self.__body(msg)
+ for field in fields:
+ if re.search(text, field, re.IGNORECASE):
+ id = "%s.%s" % (statinfo[stat.ST_INO], num)
+ print "[%s] %s %s" % (id, msg['From'], msg['Subject'])
+ break
+ gzmbox.close()
+
+ def __body(self, msg):
+ """
+ Recursively gather multipart message bodies
+ """
+ body = []
+ if msg.is_multipart():
+ for payload in msg.get_payload():
+ for part in payload.walk():
+ body += self.__body(part)
+ else:
+ body = [msg.get_payload()]
+ return body
+
+ def show(self, id):
+ """ Show a message with a given ID """
+ inode, msgnum = map(int, id.split('.'))
+ olddir = os.getcwd()
+ os.chdir(DEVSHELL_DIR)
+ mboxfile = None
+ for dir in filter(isdir, os.listdir('.')):
+ for file in os.listdir(dir):
+ statinfo = os.stat(join(dir, file))
+ if statinfo[stat.ST_INO] == inode:
+ mboxfile = join(dir, file)
+ break
+ if mboxfile: break
+ if mboxfile:
+ gzmbox = gzip.open(mboxfile)
+ mbox = UnixMailbox(gzmbox, email.message_from_file)
+ num = 0
+ while num != msgnum:
+ msg = mbox.next()
+ num += 1
+ self.__print_msg(msg)
+ else:
+ log.error("Cannot find message %s" % id)
+ os.chdir(olddir)
+
+ def __print_msg(self, msg):
+ log.info("From: %s" % msg['From'])
+ log.info("To: %s" % msg['To'])
+ log.info("Subject: %s" % msg['Subject'])
+ log.info('\n'.join(self.__body(msg)))