#!/usr/bin/python # vim: set fileencoding=utf-8 : """ * Copyright (c) 2007 by Paweł Niewiadomski (Atlassian Pty Ltd) * Copyright (c) 2009 by Tobias Richter (Diamond Light Source Ltd) * Copyright (c) 2010 by Timm Drevensek (Fraunhofer IGD) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the names of the contributors nor their * organisations may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPY RIGHT HOLDERS ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPY RIGHT HOLDERS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ import sys import re import time import commands import urllib from trac.env import open_environment from trac.ticket.model import * from trac.ticket.query import Query from trac.web.href import Href components=[] milestones=[] users=[] class DummyHref: def ticket(self, id): return id class DummyRef: def __init__(self): self.href=DummyHref() usermap = { # here you have to specify your own code to map between Trac user and Jira user (maybe it can be transfered intact or using LDAP, AD, etc.) # .... 'trac_user' : 'jira_user' } def mapUser(user, default=""): if user == "": return default if (user == None): return default if not user in users: users.append(user) if user.find("@") > 0: user = user[0:user.find("@")] if usermap.has_key(user): user = usermap[user] return user def escape(str): str = str.replace("&", "&").replace('"', '"').replace("<", "<").replace(">", ">").replace("$", "$").replace("*", "*") str = str.replace("{","[").replace("}", "]").replace("+", "+").replace("", " ").replace(" ", "\n").replace("", " ") return str.encode('iso8859-1', 'xmlcharrefreplace') def escape_version(str): str = escape(str) str = str.replace(",", ":") return str.encode('iso8859-1', 'xmlcharrefreplace') def mapIssueType(type): type = type.capitalize(); if type == "Enhancement": return "Improvement" elif type == "Defect": return "Bug" elif type == "Task": return "Task" sys.stderr.write("Fallback to Bug for "+type+"\n") return "Bug" def mapPriority(p): #if p == "major" or p == "minor" or p == "normal" or p == "trivial" or p == "critical": #return p.capitalize(); p = p.capitalize(); if p == "Blocker": return "Blocker" if p == "Critical": return "Critical" if p == "Major": return "Major" if p == "Minor": return "Minor" if p == "Trivial": return "Trivial" sys.stderr.write("Fallback to Major priority for "+p+"\n") return "Major" def mapResolution(r): if r == "wontfix": return "Won't Fix" elif r == "duplicate": return "Duplicate" elif r == "invalid": return "Incomplete" elif r == "worksforme": return "Cannot Reproduce" return "Fixed" summaries = {} def processTicket(env,id,owner,projkey): global summaries ticket = Ticket(env, id) # CreateIssue print ' ' # Transaction state = "open" # ??? # if ticket["status"] == "closed": # state = "closed" # print ' ' # TRAC: ch[t, author, field, oldvalue, newvalue, permanent] for ch in ticket.get_changelog(): # Comment if ch[2] == "comment" and ch[4] != "" and (len(ch[4])-1) > ch[4].count("\n"): print ' ' # Workflow # TODO: TransitionWorkflow don't have a created="'+ch[0].strftime("%Y-%m-%d %H:%M:%S.0")+'" field! # BUG: http://jira.atlassian.com/browse/JRA-9366 ? elif ch[2] == "resolution": if state == "closed": print ' ' print ' ' state = "closed" # Attachement elif ch[2] == "attachment": print ' ' print '' def createComponent(name, desc, user, projkey): if name in components: return if name != "": print ' ' components.append(name) def createMilestone(obj, projkey): if obj.name in milestones: return if obj.name != "": print ' ' milestones.append(obj.name) def main(): global summaries sys.stderr.write("Running "+sys.argv[0]+"..\n") env = open_environment(sys.argv[1]) env.projkey=sys.argv[2] owner = sys.argv[3] ref = DummyRef() tickets=[] for t in Query(env).execute(ref): tickets.append(int(t["id"])) tickets.sort() print '' print '' # print '' print ' ' print ' ' print ' ' print ' ' print ' ' # Components print '' print ' ' for c in Component(env).select(env): createComponent(c.name,c.description,c.owner, env.projkey) for t in tickets: ticket = Ticket(env, t) createComponent(ticket["component"],"",owner, env.projkey) # Milestones/Versions print '' print ' ' for m in Milestone(env).select(env): createMilestone(m, env.projkey) # Issues print '' print ' ' for t in tickets: processTicket(env, t, owner, env.projkey) print '' if __name__ == "__main__": main() sys.stderr.write("Found Users:\n") for user in users: sys.stderr.write("" +user+ "\n")