Revision: 41533
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at February 19, 2011 13:37 by KernelPanic
Initial Code
#!/usr/bin/env ruby # Trac2Unfuddle: The Unfuddle Trac import tool # Copyright © 2007-2009, Unfuddle LLC. All rights reserved. # Author: Joshua W. Frappier # Version: 0.7 # # No portion of this code may be duplicated or reproduced # without the express written consent of Unfuddle LLC. # For more information, contact [email protected]. # # NOTE: For this script to work, the following gems must be installed: # sqlite3-ruby, xml-simple # # NOTE: You MUST change the values in the section below before # running the script. Once changed, you can simply run the script # without any additional parameters: # # ruby project.rb # this importer is based on the Trac2Unfuddle import tool of Joshua W. Frappier # Author Gianni Metitieri, Swisstimex # Version: 1.0 ######################################################################## # CHANGE THE VALUES IN THIS SECTION ######################################################################## # change these to your own settings # be sure that the user is an account administrator UNFUDDLE_SETTINGS = { :subdomain => 'insert subdomain here', :username => 'insert username here', :password => 'insert password here', :ssl => true # ssl true or false } # values for the newly created Unfuddle project # NOTE: this project must not currently exist within the specified account PROJECT_TITLE = "Imported Project Template" PROJECT_SHORT_NAME = "template" PROJECT_DESCRIPTION = "insert project description here!" THEME = "blue" #[blue, green, grey, orange, purple, red, teal] # Define Component component = ['User Story', 'Documentation', 'Test Case', 'Project Management','Environment','GUI','Database', 'Functionality', 'Performance','Middleware', 'Look & Feel'] # Define Milestones milestone = ['Backlog', 'Sprint 1', 'Sprint 2', 'Sprint 3'] # Define Milestone Due on due_on = ['02/28/2010', '11/30/2009', '12/31/2009', '01/31/2010'] # Define Milestone Status status = [0, 0, 0, 0] # Define Severity severity = ['1-Urgent Fix', '2-Must Fix', '3-Should Fix', '4-Could Fix'] # Define Version version = ['Major.Minor.Patch.Build'] # Define Category category = ['General','News', 'Project', 'Team', 'Blog'] # Define Customer Field 1 type1 = 'list' # is a list or text title1 = 'Type' # insert customer title here if type1 == 'list' customer_1 = ['BUG', 'REQ', 'TASK', 'TECH'] else end # Define Customer Field 2 type2 = 'text' # is a list or text title2 = 'Effort' # insert customer title here if type2 == 'list' customer_2 = ['item1', 'item2', 'item3', 'item4'] else end # Define Customer Field 1 type3 = 'text' #is a list or text title3 = 'Value' # insert customer title here if type3 == 'list' customer_3 = ['item1', 'item2', 'item3', 'item4'] else end # Define Notebook title = 'Project Wiki' ######################################################################## # NO NEED TO CHANGE BELOW THIS LINE ######################################################################## require 'rubygems' require 'date' require 'net/https' require 'xmlsimple' # an adequate hash to xml conversion method class Hash def to_xml(options={}) xml = '' xml += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" unless options[:skip_instruct] xml += "<#{options[:root]}>" if options[:root] self.each { |key,val| key_formatted = key.to_s.gsub('_','-') case val when Date: val_formatted = val.strftime("%Y-%m-%d") when DateTime, Time: val_formatted = val.strftime("%Y-%m-%d %H:%M:%S") when Hash: val_formatted = val.to_xml(:skip_instruct => true) else val_formatted = val.to_s.gsub('&', '&').gsub('>', '>').gsub('<', '<') end xml += "<#{key_formatted}>" xml += val_formatted.to_s xml += "</#{key_formatted}>" } xml += "</#{options[:root]}>" if options[:root] xml end end # convenience method to get a date class Time def to_date ::Date.new(year, month, day) end end # get a resource # returns a hash of the resource def api_get_hash(short_url) request = Net::HTTP::Get.new("/api/v1/#{short_url}.xml", {'Accept' => 'application/xml'}) request.basic_auth UNFUDDLE_SETTINGS[:username], UNFUDDLE_SETTINGS[:password] response = @http.request(request) if response.code == "200" XmlSimple.xml_in(response.body, { 'ForceArray' => false }) else {} end end # create a resource via the unfuddle api and return the # new id of the resource on success def api_create(resource_type, short_url, attributes) request = Net::HTTP::Post.new("/api/v1/#{short_url}", {'Accept' => 'application/xml', 'Content-type' => 'application/xml'}) request.basic_auth UNFUDDLE_SETTINGS[:username], UNFUDDLE_SETTINGS[:password] request.body = attributes.to_xml(:root => resource_type) response = @http.request(request) if response.code == "201" response['Location'].split('/').last.to_i else puts "ERROR (#{response.code}):\n" + response.body 0 end end # update a resource via the unfuddle api def api_update(resource_type, short_url, attributes) request = Net::HTTP::Put.new("/api/v1/#{short_url}", {'Accept' => 'application/xml', 'Content-type' => 'application/xml'}) request.basic_auth UNFUDDLE_SETTINGS[:username], UNFUDDLE_SETTINGS[:password] request.body = attributes.to_xml(:root => resource_type) response = @http.request(request) if response.code == "200" true else puts "ERROR (#{response.code}):\n" + response.body false end end # upload a file to the unfuddle api # returns the upload key of the file def api_upload(short_url, path) request = Net::HTTP::Post.new("/api/v1/#{short_url}.xml", {'Accept' => 'application/xml', 'Content-type' => 'application/octet-stream'}) request.basic_auth UNFUDDLE_SETTINGS[:username], UNFUDDLE_SETTINGS[:password] path = path.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) } unless File.exists?(path) request.body = File.read(path) response = @http.request(request) if response.code == "200" XmlSimple.xml_in(response.body, { 'ForceArray' => false })['key'] else nil end end # setup the http object for later use @http = Net::HTTP.new("#{UNFUDDLE_SETTINGS[:subdomain]}.unfuddle.com", UNFUDDLE_SETTINGS[:ssl] ? 443 : 80) @http.use_ssl = true if UNFUDDLE_SETTINGS[:ssl] @http.verify_mode = OpenSSL::SSL::VERIFY_NONE if UNFUDDLE_SETTINGS[:ssl] # create the project print "Creating Project..." project_id = api_create(:project, 'projects', {:title => PROJECT_TITLE, :short_name => PROJECT_SHORT_NAME, :description => PROJECT_DESCRIPTION, :assignee_on_resolve => 'reporter',:close_ticket_simultaneously_default => 0, :enable_time_tracking => 1, :theme => THEME, :ticket_field1_active => 1, :ticket_field1_title => title1, :ticket_field1_disposition => type1, :ticket_field2_active => 1, :ticket_field2_title => title2, :ticket_field2_disposition => type2, :ticket_field3_active => 1, :ticket_field3_title => title3, :ticket_field3_disposition => type3}) print "#{project_id}...done\n" # create the components index = 0 while index < component.length print "Creating Component #{component[index]}..." component_id = api_create(:component, "projects/#{project_id}/components", {:name => component[index]}) print "#{component_id}...done\n" index += 1 end # create milestones index = 0 while index < milestone.length print "Creating Milestone #{milestone[index]}..." milestone_id = api_create(:milestone, "projects/#{project_id}/milestones", {:title => milestone[index], :due_on => Date.parse(due_on[index]).to_s, :completed => status[index]}) print "#{milestone_id}...done\n" index += 1 end # create severities index = 0 while index < severity.length print "Creating Severities #{severity[index]}..." severity_id = api_create(:severity, "projects/#{project_id}/severities", {:name => severity[index]}) print "#{severity_id}...done\n" index += 1 end # create versions index = 0 while index < version.length print "Creating Versions #{version[index]}..." version_id = api_create(:version, "projects/#{project_id}/versions", {:name => version[index]}) print "#{version_id}...done\n" index += 1 end # create customer field 1 if type1 == 'list' index = 0 while index < customer_1.length print "Creating Customer Field 1 #{customer_1[index]}..." customer_1_id = api_create(:custom_field_value, "projects/#{project_id}/custom_field_values", {:value => customer_1[index], :field_number => 1}) print "#{customer_1_id}...done\n" index += 1 end else end # create customer field 2 if type2 == 'list' index = 0 while index < customer_2.length print "Creating Customer Field 2 #{customer_2[index]}..." customer_2_id = api_create(:custom_field_value, "projects/#{project_id}/custom_field_values", {:value => customer_2[index], :field_number => 2}) print "#{customer_2_id}...done\n" index += 1 end else end # create customer field 3 if type3 == 'list' index = 0 while index < customer_3.length print "Creating Customer Field 3 #{customer_3[index]}..." customer_3_id = api_create(:custom_field_value, "projects/#{project_id}/custom_field_values", {:value => customer_3[index], :field_number => 3}) print "#{customer_3_id}...done\n" index += 1 end else end # create category index = 0 while index < category.length print "Creating category #{category[index]}..." category_id = api_create(:category, "projects/#{project_id}/categories", {:name => category[index]}) print "#{category_id}...done\n" index += 1 end # create notebook print "Creating Notebook..." notebook_id = api_create(:notebook, "projects/#{project_id}/notebooks", {:title => title}) print "#{notebook_id}...done\n"
Initial URL
Initial Description
Written by Joshua W. Frappier
Initial Title
Unfuddle Project template
Initial Tags
template
Initial Language
Ruby