#!/usr/bin/env python2.5
#
# This script will parse a bugs mailing list file for e-mails indicating
# that a bug has been tagged with a specific tag, sys.argv[1], and
# return bug numbers with the tag and the date they were tagged
#
# Example:
# tagged-bugs.py "regression-potential" 2008-10
#
# Copyright 2008 Canonical, Ltd
# Author: Brian Murray <brian@ubuntu.com>
# Licensed under the GNU General Public License, version 3.

from mailbox import PortableUnixMailbox
from email import message_from_file
from email.errors import MessageParseError
from email.utils import parseaddr
from email.utils import parsedate
from email.utils import getaddresses
from sys import argv, stderr, exit
from operator import itemgetter
from re import search

import time

# adjust as appropriate
report_folder = ""

MESSAGE_NOT_PARSEABLE = object()



def message_factory(fp):
    try:
        return message_from_file(fp)
    except MessageParseError:
        # Don't return None since that will stop the mailbox iterator.
        return MESSAGE_NOT_PARSEABLE


def show_progress(iterator, interval=100):
    """Show signs of progress."""
    for count, item in enumerate(iterator):
        if count % interval == 0:
            stderr.write('.')
        yield item


def scan_bugs(messages):
    for count, message in enumerate(messages):
        # Skip broken messages.
        if message is MESSAGE_NOT_PARSEABLE:
            continue

        # Skip replies.
        # Every message has as a reference in it for some reason
#        references = message['references']
#        if references is not None:
#            yield 'reply'
#            continue 

        # Check it's from a Launchpad bug.
        reply_to = message['reply-to']
        if reply_to is None:
            continue
        reply_name, reply_address = parseaddr(reply_to)
        reply_local_part, reply_domain = reply_address.split('@')
        if not (reply_domain == 'bugs.launchpad.net' and
                reply_local_part.isdigit()):
            continue
        bug_id = int(reply_local_part)

        sent_date = message['date']

        action_date = time.mktime(parsedate(sent_date))

        payload = message.get_payload()
        # this should catch bugs reported with the tag
        if 'Tags: ' + tag in payload:
            tagged[bug_id] = action_date
            continue
        # tags added to an existing bug report
        if 'Tags added: ' + tag in payload:
            tagged[bug_id] = action_date

if __name__ == '__main__':
    # Check if the amount of arguments is correct
    if len(argv) < 3 or argv[1] in ('help', '-h', '--help'):
        print 'Usage: %s <tag> <bug_mailinglist_file> [<bug_mailinglist_file> ...]' % argv[0]
        exit(1)

    tag = argv[1]

    tagged = {}

    for mailbox_file in argv[2:]:
        mailbox = PortableUnixMailbox(
            open(mailbox_file, 'rb'), message_factory)
        scan_bugs(show_progress(mailbox))

    templatefile = open('template.html', 'r')
    datafile = open('%stagged-%s.html' % (report_folder, tag), 'w')

    for line in templatefile:
        if line.strip() == "<!-- *** Title Space *** -->":
	    datafile.write("Bugs tagged with %s\n" % tag)
	elif line.strip() == "<!-- *** Header Space *** -->":
	    datafile.write("Bugs tagged with %s\n" % tag)
	elif line.strip() == "<!-- *** Paragraph Space *** -->":
	    # no paragraph text?
            datafile.write("\n")
	elif line.strip() == "<!-- *** Table Header Space *** -->":
            datafile.write("<th>Bug</th><th>Date</th>\n")
	elif line.strip() == "<!-- *** Table Body Space *** -->":
            for k,v in sorted(tagged.items(), key=itemgetter(1), reverse=False):
                datafile.write('<tr><td><a href="http://launchpad.net/bugs/%s">%s</a></td><td>%s</td></tr>\n' % (k, k, time.strftime("%Y-%m-%d", time.gmtime(v))))
        elif line.strip() == "<!-- *** Last Paragraph Space *** -->":
	    # no last paragraph text?
            datafile.write("\n")
	else:
            datafile.write(line)

    datafile.close()
