Created
September 1, 2011 20:06
-
-
Save erussell/1187119 to your computer and use it in GitHub Desktop.
Import Trac tickets into GitHub issues, using v3 of the GitHub API. Based on https://github.com/adamcik/github-trac-ticket-import
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import base64 | |
import csv | |
import json | |
import urllib | |
import urllib2 | |
import string | |
# Dictionary mapping Trac usernames to GitHub usernames | |
USERS = { | |
'erussell' : 'erussell', | |
} | |
# Username of your GitHub account | |
USERNAME = '' | |
# Password of your GitHub account | |
PASSWORD = '' | |
# Organization that owns repository (or empty string if no organization) | |
ORGNAME = '' | |
# Repository name | |
REPOSITORY = '' | |
# Path to Trac issues (CSV version of report 1) | |
TRAC_TICKETS = '' | |
if (ORGNAME == ''): | |
ORGNAME = USERNAME | |
github_url = 'https://api.github.com/repos/%s/%s/' % (ORGNAME, REPOSITORY) | |
authorization = 'Basic %s' % base64.b64encode("%s:%s" % (USERNAME, PASSWORD)) | |
csv_data = open(TRAC_TICKETS) | |
reader = csv.DictReader(csv_data) | |
tickets = [] | |
url = github_url + 'issues?per_page=100' | |
response = urllib2.urlopen(url) | |
content = response.read() | |
issues = json.loads(content) | |
url = github_url + 'milestones' | |
response = urllib2.urlopen(url) | |
content = response.read() | |
milestones = dict([ (milestone['title'], milestone) for milestone in json.loads(content) ]) | |
create_milestones = set() | |
url = github_url + 'labels' | |
response = urllib2.urlopen(url) | |
content = response.read() | |
labels = [ label['name'] for label in json.loads(content) ] | |
create_labels = set() | |
for row in reader: | |
for key, value in row.items(): | |
row[key] = row[key].decode('utf-8') | |
if filter(lambda i: i['title'] == row['summary'], issues): | |
continue | |
if 'milestone' in row and not row['milestone'] in milestones: | |
create_milestones.add(row['milestone']) | |
if not row['type'] in labels: | |
create_labels.add(row['type']) | |
if not row['component'] in labels: | |
create_labels.add(row['component']) | |
tickets.append({ | |
'title': row['summary'], | |
'description': row['_description'], | |
'owner' : row['owner'], | |
'tags': [row['type'], row['component']], | |
'milestone' : row['milestone'] if 'milestone' in row else None, | |
}) | |
url = github_url + 'milestones' | |
for milestone in create_milestones: | |
data = json.dumps({'title' : milestone}) | |
request = urllib2.Request(url, data, {'Content-Type': 'application/json'}) | |
request.add_header('Authorization', authorization) | |
response = urllib2.urlopen(request) | |
content = response.read() | |
try: | |
milestones[milestone] = json.loads(content) | |
except KeyError: | |
raise Exception(content) | |
response.close() | |
url = github_url + 'labels' | |
for label in create_labels: | |
data = json.dumps({'name' : label}) | |
request = urllib2.Request(url, data, {'Content-Type': 'application/json'}) | |
request.add_header('Authorization', authorization) | |
response = urllib2.urlopen(request) | |
content = response.read() | |
response.close() | |
url = github_url + 'issues' | |
for ticket in tickets: | |
owner = ticket['owner'] | |
body = ticket['description'] | |
body = string.replace(body, '[[BR]]', '\n\n') | |
body = string.replace(body, "'''", '**') | |
body = string.replace(body, "''", '*') | |
data = json.dumps({ | |
'title' : ticket['title'], | |
'body' : body, | |
'assignee' : USERS[owner] if owner in USERS else None, | |
'milestone' : milestones[ticket['milestone']]['number'], | |
'labels' : ticket['tags']}) | |
request = urllib2.Request(url, data, {'Content-Type': 'application/json'}) | |
request.add_header('Authorization', authorization) | |
response = urllib2.urlopen(request) | |
content = response.read() | |
try: | |
issue = json.loads(content) | |
except KeyError: | |
raise Exception(content) | |
response.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very useful (potentially) piece of code. I tried running it against by repo, but the authorisation is failing (see below). I wonder if the basic authorization with token would work ?