#!/usr/local/bin/python
# -*- mode: python -*-

"""
jb2bz.py - a nonce script to import bugs from JitterBug to Bugzilla
Written by Tom Emerson, tree@basistech.com

This script is provided in the hopes that it will be useful.  No
rights reserved. No guarantees expressed or implied. Use at your own
risk. May be dangerous if swallowed. If it doesn't work for you, don't
blame me. It did what I needed it to do.

This code requires a recent version of Andy Dustman's MySQLdb interface,

    http://sourceforge.net/projects/mysql-python

Share and enjoy.
"""

import rfc822, mimetools, multifile, mimetypes
import sys, re, glob, StringIO, os, stat, time
import MySQLdb, getopt

# mimetypes doesn't include everything we might encounter, yet.
if not mimetypes.types_map.has_key('.doc'):
    mimetypes.types_map['.doc'] = 'application/msword'

if not mimetypes.encodings_map.has_key('.bz2'):
    mimetypes.encodings_map['.bz2'] = "bzip2"

bug_status='NEW'
component="default"
version=""
product="" # this is required, the rest of these are defaulted as above

"""
Each bug in JitterBug is stored as a text file named by the bug number.
Additions to the bug are indicated by suffixes to this:

<bug>
<bug>.followup.*
<bug>.reply.*
<bug>.notes

The dates on the files represent the respective dates they were created/added.

All <bug>s and <bug>.reply.*s include RFC 822 mail headers. These could include
MIME file attachments as well that would need to be extracted.

There are other additions to the file names, such as

<bug>.notify

which are ignored.

Bugs in JitterBug are organized into directories. At Basis we used the following
naming conventions:

<product>-bugs         Open bugs
<product>-requests     Open Feature Requests
<product>-resolved     Bugs/Features marked fixed by engineering, but not verified
<product>-verified     Resolved defects that have been verified by QA

where <product> is either:

<product-name>

or

<product-name>-<version>
"""

def process_notes_file(current, fname):
    try:
        new_note = {}
        notes = open(fname, "r")
        s = os.fstat(notes.fileno())

        new_note['text']  = notes.read()
        new_note['timestamp'] = time.gmtime(s[stat.ST_MTIME])

        notes.close()

        current['notes'].append(new_note)

    except IOError:
        pass

def process_reply_file(current, fname):
    new_note = {}
    reply = open(fname, "r")
    msg = rfc822.Message(reply)
    new_note['text'] = "%s\n%s" % (msg['From'], msg.fp.read())
    new_note['timestamp'] = rfc822.parsedate_tz(msg['Date'])
    current["notes"].append(new_note)

def add_notes(current):
    """Add any notes that have been recorded for the current bug."""
    process_notes_file(current, "%d.notes" % current['number'])

    for f in glob.glob("%d.reply.*" % current['number']):
        process_reply_file(current, f)

    for f in glob.glob("%d.followup.*" % current['number']):
        process_reply_file(current, f)

def maybe_add_attachment(current, file, submsg):
    """Adds the attachment to the current record"""
    cd = submsg["Content-Disposition"]
    m = re.search(r'filename="([^"]+)"', cd)
    if m == None:
        return
    attachment_filename = m.group(1)
    if (submsg.gettype() == 'application/octet-stream'):
        # try get a more specific content-type for this attachment
        type, encoding = mimetypes.guess_type(m.group(1))
        if type == None:
            type = submsg.gettype()
    else:
        type = submsg.gettype()

    try:
        data = StringIO.StringIO()
        mimetools.decode(file, data, submsg.getencoding())
    except:
        return

    current['attachments'].append( ( attachment_filename, type, data.getvalue() ) )

def process_mime_body(current, file, submsg):
    data = StringIO.StringIO()
    mimetools.decode(file, data, submsg.getencoding())
    current['description'] = data.getvalue()



def process_text_plain(msg, current):
    print "Processing: %d" % current['number']
    current['description'] = msg.fp.read()

def process_multi_part(file, msg, current):
    print "Processing: %d" % current['number']
    mf = multifile.MultiFile(file)
    mf.push(msg.getparam("boundary"))
    while mf.next():
        submsg = mimetools.Message(file)
        if submsg.has_key("Content-Disposition"):
            maybe_add_attachment(current, mf, submsg)
        else:
            # This is the message body itself (always?), so process
            # accordingly
            process_mime_body(current, mf, submsg)

def process_jitterbug(filename):
    current = {}
    current['number'] = int(filename)
    current['notes'] = []
    current['attachments'] = []
    current['description'] = ''
    current['date-reported'] = ()
    current['short-description'] = ''
    
    file = open(filename, "r")
    msg = mimetools.Message(file)

    msgtype = msg.gettype()

    add_notes(current)
    current['date-reported'] = rfc822.parsedate_tz(msg['Date'])
    current['short-description'] = msg['Subject']

    if msgtype[:5] == 'text/':
        process_text_plain(msg, current)
    elif msgtype[:10] == "multipart/":
        process_multi_part(file, msg, current)
    else:
        # Huh? This should never happen.
        print "Unknown content-type: %s" % msgtype
        sys.exit(1)

    # At this point we have processed the message: we have all of the notes and
    # attachments stored, so it's time to add things to the database.
    # The schema for JitterBug 2.14 can be found at:
    #
    #    http://www.trilobyte.net/barnsons/html/dbschema.html
    #
    # The following fields need to be provided by the user:
    #
    # bug_status
    # product
    # version
    # reporter
    # component
    # resolution

    # change this to the user_id of the Bugzilla user who is blessed with the
    # imported defects
    reporter=6

    # the resolution will need to be set manually
    resolution=""

    db = MySQLdb.connect(db='bugs',user='root',host='localhost')
    cursor = db.cursor()

    cursor.execute( "INSERT INTO bugs SET " \
                    "bug_id=%s," \
                    "bug_severity='normal',"  \
                    "bug_status=%s," \
                    "creation_ts=%s,"  \
                    "delta_ts=%s,"  \
                    "short_desc=%s," \
                    "product=%s," \
                    "rep_platform='All'," \
                    "assigned_to=%s,"
                    "reporter=%s," \
                    "version=%s,"  \
                    "component=%s,"  \
                    "resolution=%s",
                    [ current['number'],
                      bug_status,
                      time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
                      time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
                      current['short-description'],
                      product,
                      reporter,
                      reporter,
                      version,
                      component,
                      resolution] )

    # This is the initial long description associated with the bug report
    cursor.execute( "INSERT INTO longdescs VALUES (%s,%s,%s,%s)",
                    [ current['number'],
                      reporter,
                      time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
                      current['description'] ] )

    # Add whatever notes are associated with this defect
    for n in current['notes']:
        cursor.execute( "INSERT INTO longdescs VALUES (%s,%s,%s,%s)",
                        [current['number'],
                         reporter,
                         time.strftime("%Y-%m-%d %H:%M:%S", n['timestamp'][:9]),
                         n['text']])

    # add attachments associated with this defect
    for a in current['attachments']:
        cursor.execute( "INSERT INTO attachments SET " \
                        "bug_id=%s, creation_ts=%s, description='', mimetype=%s," \
                        "filename=%s, thedata=%s, submitter_id=%s",
                        [ current['number'],
                          time.strftime("%Y-%m-%d %H:%M:%S", current['date-reported'][:9]),
                          a[1], a[0], a[2], reporter ])

    cursor.close()
    db.close()

def usage():
    print """Usage: jb2bz.py [OPTIONS] Product

Where OPTIONS are one or more of the following:

  -h                This help information.
  -s STATUS         One of UNCONFIRMED, NEW, ASSIGNED, REOPENED, RESOLVED, VERIFIED, CLOSED
                    (default is NEW)
  -c COMPONENT      The component to attach to each bug as it is important. This should be
                    valid component for the Product.
  -v VERSION        Version to assign to these defects.

Product is the Product to assign these defects to.

All of the JitterBugs in the current directory are imported, including replies, notes,
attachments, and similar noise.
"""
    sys.exit(1)


def main():
    global bug_status, component, version, product
    opts, args = getopt.getopt(sys.argv[1:], "hs:c:v:")

    for o,a in opts:
        if o == "-s":
            if a in ('UNCONFIRMED','NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED'):
                bug_status = a
        elif o == '-c':
            component = a
        elif o == '-v':
            version = a
        elif o == '-h':
            usage()

    if len(args) != 1:
        sys.stderr.write("Must specify the Product.\n")
        sys.exit(1)

    product = args[0]

    for bug in filter(lambda x: re.match(r"\d+$", x), glob.glob("*")):
        process_jitterbug(bug)
        

if __name__ == "__main__":
    main()
