Source

bugzilla_bitbucket / create_issues.py

Full commit
"""
read in the xml, and create the issues.

issues API:
	http://confluence.atlassian.com/display/BITBUCKET/Issues

	    title: The title of the new issue.
	    content: The content of the new issue.
	    component: The component associated with the issue.
	    milestone: The milestone associated with the issue.
	    version: The version associated with the issue.
	    responsible: The username of the person responsible for the issue.
	    status: The status of the issue (new, open, resolved, on hold, invalid, duplicate, or wontfix).
	    kind: The kind of issue (bug, enhancement, or proposal).

How to delete an issue:
	curl -X DELETE https://api.bitbucket.org/1.0/repositories/pygame/pygame/issues/3

Add --user username:password afterwards to authenticate, otherwise it does not work.

"""


import os,sys,urllib
import pprint
import glob
import xml.etree.cElementTree as ElementTree

issue_keys = "title content component milestone version responsible status kind".split()
valid_status = "new open resolved hold invalid duplicate wontfix".split()
valid_kind = "bug enhancement proposal".split()

def validate_issue(issue):
	for k in issue_keys:
		if k not in issue:
			raise ValueError("%s not in issue" % k)
	if issue.get('status') not in valid_status:
		raise ValueError(":%s: status is not one of %s" % (issue.get('status'), valid_status))
	if issue.get('kind') not in valid_kind:
		raise ValueError(":%s: kind is not one of %s" % (issue.get('kind'), valid_kind))

def create_issue(issue):

	validate_issue(issue)
	# create http post data from issue
	issue_data = urllib.urlencode(issue)
	return issue_data


def test_create_issue():
	i = dict(title="just a test issue", content="some content to test", component="pygameissues", milestone="bitbucketmigration", version="1.9.2", responsible="illume", status="new", kind="bug")
	print create_issue(i)
#test_create_issue()



# read bugzilla xml data.
def create_bugzilla_dicts():

    # convert xml to a dict.
    #http://code.activestate.com/recipes/410469-xml-as-dictionary/
    class XmlListConfig(list):
        def __init__(self, aList):
            for element in aList:
                if element:
                    # treat like dict
                    if len(element) == 1 or element[0].tag != element[1].tag:
                        self.append(XmlDictConfig(element))
                    # treat like list
                    elif element[0].tag == element[1].tag:
                        self.append(XmlListConfig(element))
                elif element.text:
                    text = element.text.strip()
                    if text:
                        self.append(text)
    class XmlDictConfig(dict):
        '''
        Example usage:

        >>> tree = ElementTree.parse('your_file.xml')
        >>> root = tree.getroot()
        >>> xmldict = XmlDictConfig(root)

        Or, if you want to use an XML string:

        >>> root = ElementTree.XML(xml_string)
        >>> xmldict = XmlDictConfig(root)

        And then use xmldict for what it is... a dict.
        '''
        def __init__(self, parent_element):
            if parent_element.items():
                self.update(dict(parent_element.items()))
            for element in parent_element:
                if element:
                    # treat like dict - we assume that if the first two tags
                    # in a series are different, then they are all different.
                    if len(element) == 1 or element[0].tag != element[1].tag:
                        aDict = XmlDictConfig(element)
                    # treat like list - we assume that if the first two tags
                    # in a series are the same, then the rest are the same.
                    else:
                        # here, we put the list in dictionary; the key is the
                        # tag name the list elements all share in common, and
                        # the value is the list itself 
                        aDict = {element[0].tag: XmlListConfig(element)}
                    # if the tag has attributes, add those to the dict
                    if element.items():
                        aDict.update(dict(element.items()))
                    self.update({element.tag: aDict})
                # this assumes that if you've got an attribute in a tag,
                # you won't be having any text. This may or may not be a 
                # good idea -- time will tell. It works for the way we are
                # currently doing XML configuration files...
                elif element.items():
                    self.update({element.tag: dict(element.items())})
                # finally, if there are no child tags and no attributes, extract
                # the text
                else:
                    self.update({element.tag: element.text})




    #convert the bugzilla data to an issue.
    files = glob.glob("xml/*")
    bugs = {}
    for f in files:

        tree = ElementTree.parse(f)
        xmldict = XmlDictConfig(tree.getroot())

        # create a list of long_desc since the xml2dict func does not work correctly here.
        xmldict['bug']['long_desc'] = []
        for x in tree.getroot().getiterator():
            if x.tag == 'long_desc':
                xmldict['bug']['long_desc'].append(XmlDictConfig(x))


        bugs[xmldict['bug']['bug_id']] = xmldict['bug']

    return bugs




def extractInfo(bugs):
    info = dict(bug_status = set([]), 
                version = set([]), 
                component= set([]), 
                product= set([]), 
                op_sys= set([]), 
                rep_platform= set([]), 
                priority= set([]), 
                bug_severity= set([]), 
                target_milestone= set([])
                )
    for bug_id, b in bugs.items():
        for k in info.keys():
            if k in b:
                info[k].add(b[k])

    return info

def convertBug(bug):
    """ converts a bugzilla bug into a bitbucket issue.
    """
    i = dict(title="just a test issue", 
             content="some content to test", 
             component="pygameissues", 
             milestone="bitbucketmigration", 
             version="1.9.2", 
             responsible="illume", 
             status="new", 
             kind="bug")





bugs = create_bugzilla_dicts()
#pprint.pprint( bugs['3'] )

info = extractInfo(bugs)
pprint.pprint(info)