#!/usr/bin/env python2.5
#
# This script will parse a bugs mailing list file for messages
# containing a string, sys.argv[1], and return the bug numbers that
# have that particular string in them.
#
# Example:
# body-searching.py "buffer overflow detected" 2008-08
#
# 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 getaddresses
from sys import argv, stderr
from operator import itemgetter
from re import search
import sys

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)

        payload = message.get_payload()
        if string in payload:
            yield '%s' % bug_id

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

    string = argv[1]


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

        counts = {}
        for test in scan_bugs(show_progress(mailbox)):
            counts[test] = counts.setdefault(test, 0) + 1
        print

        for k,v in sorted(counts.items(), key=itemgetter(1), reverse=True):
            print k
