trac_convert / convert.py

import os
import base64
import urllib
import urllib2
import urlparse
import json
import getpass
import sqlite3
import cPickle
import time
#from parse_tickets import template, update_template

username = raw_input("Username?").strip()
password = getpass.getpass("Bitbucket password?")
repo = "trac_convert"

# This code snippet is modified from Georg Brandl
def bb_apicall(endpoint, data, use_pass = True):
    uri = 'https://api.bitbucket.org/1.0/%s/' % endpoint
    # since bitbucket doesn't return the required WWW-Authenticate header when
    # making a request without Authorization, we cannot use the standard urllib2
    # auth handlers; we have to add the requisite header from the start
    if data is not None:
        data = urllib.urlencode(data)
    req = urllib2.Request(uri, data)
    if use_pass:
        # at least re-use Mercurial's password query
        upw = '%s:%s' % (username, password)
        req.add_header('Authorization', 'Basic %s' % base64.b64encode(upw).strip())
    return urllib2.urlopen(req).read()

template = \
"""== Imported Ticket ==
 * **Summary:** %(summary)s
 * **Component:** %(component)s
 * **Milestone:** %(milestone)s
 * **Reporter:** %(reporter)s
 * **Owner:** %(owner)s
 * **Resolution: %(resolution)s
 * **Status:** %(status)s
 * **Created:** %(time)s
 * **Description:** %(description)s
"""

update_template = \
"""
=== Update to Ticket ===
 * **Author:** %(author)s
 * **Changetime:** %(time)s
 * **Field:** %(field)s
 * **Oldvalue:** %(oldvalue)s
 * **Newvalue:** %(newvalue)s
"""

unique_res = set()
unique_status = set()
unique_keys = set()
unique_types = set()
unique_milestones = set()
unique_components = set()

resolution_mapping = {
    "worksforme": "invalid",
    "invalid": "invalid",
    "duplicate": "duplicate",
    "wontfix": "wontfix",
    "fixed": "resolved",
    "new": 'new',
    "assigned": "open",
}

milestone_map = {
    "1.5": "1.5",
    "2.0": "2.0",
    "1.6": "1.6",
    "1.7": "1.7",
    "1.0": "1.0",
    "0.2": "0.2",
    "2.1": "2.1",
    None: None,
    '': None,
}


component_map = {
    'deliverator' : 'yt',
    'website': 'yt',
    'visualization': 'visualization',
    'documentation': 'documentation',
    'reason': 'reason',
    'lagos': 'yt',
    'fido': 'yt',
    'examples': 'documentation',
    'halo_finder': 'halo_finder',
    'scripts': 'documentation',
    'extensions': 'analysis_modules',
    'ramses': 'code_frontends',
    'yt': 'yt',
    'raven': 'visualization'
}

tickets = cPickle.load(open("tickets.cpkl","rb"))
for ticid in sorted(tickets):
    ticket = tickets[ticid]
    content = template % ticket + "\n".join(
                [update_template % update for update in ticket["updates"]])
    #print content
    component = component_map[ticket["component"]]
    if ticket["status"] == "closed":
        res = resolution_mapping[ticket["resolution"]]
    else:
        res = resolution_mapping[ticket["status"]]
    milestone = milestone_map[ticket['milestone']]
    print ticid, res, milestone, component, ticket["summary"]
    data = dict(title = ticket["summary"], content = content,
                status=res, milestone = milestone, component=component)
    #bb_apicall("repositories/MatthewTurk/trac_convert/issues", data)
    #if ticid > 120: break
    #break
    #time.sleep(0.25)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.