def bugzilla2youtrack(target_url, target_login, target_pass, bz_db, bz_host, bz_port, bz_login, bz_pass, bz_product_names, issues_filter): # connecting to bz client = Client(bz_host, int(bz_port), bz_login, bz_pass, db_name=bz_db) if not len(bz_product_names): answer = raw_input("All projects will be imported. Are you sure? [y/n]") if answer.capitalize() != "Y": sys.exit() bz_product_names = client.get_product_names() print("bz_product_names : " + repr(bz_product_names)) # connecting to yt target = Connection(target_url, target_login, target_pass) print("Creating issue link types") link_types = client.get_issue_link_types() for link in link_types: print("Processing link type [ %s ]" % link.name) try: target.createIssueLinkType(to_yt_issue_link_type(link)) except YouTrackException: print("Can't create link type [ %s ] (maybe because it already exists)" % link.name) print("Creating issue link types finished") print("Creating custom fields") custom_fields = client.get_custom_fields() for cf in custom_fields: create_yt_custom_field(cf, target) print("Creating custom fields finished") for key in youtrackutils.bugzilla.FIELD_TYPES: if key not in youtrack.EXISTING_FIELDS: create_custom_field(target, youtrackutils.bugzilla.FIELD_TYPES[key], key, True, bundle_policy="1") bz_product_ids = [] for name in bz_product_names: product_id = str(client.get_product_id_by_name(name)) bz_product_ids.append(product_id) print("Creating project [ %s ] with name [ %s ]" % (product_id, name)) try: target.getProject(str(product_id)) except YouTrackException: target.createProjectDetailed(str(product_id), name, client.get_project_description(product_id), target_login) print("Importing components for project [ %s ]" % product_id) process_components(client.get_components(product_id), product_id, target) print("Importing components finished for project [ %s ]" % product_id) print("Importing versions for project [ %s ]" % product_id) process_versions(client.get_versions(product_id), product_id, target) print("Importing versions finished for project [ %s ] finished" % product_id) print("Importing issues to project [ %s ]" % product_id) max_count = 100 count = 0 from_id = 0 bz_issues_count = client.get_issues_count(product_id) while count < bz_issues_count: batch = client.get_issues(product_id, from_id, from_id + max_count) batch = [bz_issue for bz_issue in batch if (issues_filter(bz_issue))] count += len(batch) from_id += max_count target.importIssues(product_id, product_id + " assignees", [to_yt_issue(bz_issue, product_id, target) for bz_issue in batch]) # todo convert to good tags import for issue in batch: tags = issue["keywords"] | issue["flags"] for t in tags: print("Processing tag [ %s ]" % t.encode('utf8')) target.executeCommand(str(product_id) + "-" + str(issue[get_number_in_project_field_name()]), "tag " + t.encode('utf8')) for issue in batch: for attach in issue["attachments"]: print("Processing attachment [ %s ]" % (attach.name.encode('utf8'))) content = StringIO(attach.content) target.createAttachment(str(product_id) + "-" + str(issue[get_number_in_project_field_name()]), attach.name, content, attach.reporter.login , created=str(int(attach.created) * 1000)) print("Importing issues to project [ %s ] finished" % product_id) # todo add pagination to links print("Importing issue links") cf_links = client.get_issue_links() duplicate_links = client.get_duplicate_links() if len(duplicate_links): try: target.createIssueLinkTypeDetailed("Duplicate", "duplicates", "is duplicated by", True) except YouTrackException: print("Can't create link type [ Duplicate ] (maybe because it already exists)") depend_links = client.get_dependencies_link() if len(depend_links): try: target.createIssueLinkTypeDetailed("Depend", "depends on", "is required for", True) except YouTrackException: print("Can't create link type [ Depend ] (maybe because it already exists)") links = cf_links | duplicate_links | depend_links links_to_import = list([]) for link in links: print("Processing link %s for issue%s" % (link.name, link.source)) if (str(link.target_product_id) in bz_product_ids) and (str(link.source_product_id) in bz_product_ids): links_to_import.append(to_yt_issue_link(link)) print(target.importLinks(links_to_import)) print("Importing issue links finished")
def fb2youtrack(params): # Connection to FogBugz source = FBClient(params['fb_url'], params['fb_login'], params['fb_password']) # Connecting to YouTrack token = params.get('token') if not token and 'token_file' in params: try: with open(params['token_file'], 'r') as f: token = f.read().strip() except (OSError, IOError) as e: print("Cannot load token from file: " + str(e)) sys.exit(1) if token: target = Connection(params['yt_url'], token=token) elif 'yt_login' in params: target = Connection(params['yt_url'], params.get('yt_login'), params.get('yt_password')) else: print("You have to provide token or login/password to import data") sys.exit(1) if not params.get('project_lead_login'): project_lead = params.get('yt_login') if not project_lead: for login in ('root', 'admin', 'administrator', 'guest'): try: project_lead = target.getUser(login).login break except youtrack.YouTrackException: continue params['project_lead_login'] = project_lead max_issue_id = params['fb_max_issue_id'] project_names = youtrackutils.fbugz.PROJECTS_TO_IMPORT accessible_projects = source.list_project_names() for p_name in project_names: if not (p_name in accessible_projects.keys()): print('Unknown project names. Exiting...') sys.exit() # for p_name in accessible_projects : # if (p_name.encode('utf-8') in project_names_str) : # project_names_str.remove(p_name.encode('utf-8')) # project_names.append(p_name) # # if (len(project_names_str) != 0) : # print 'Unknown project names!' print('Creating custom fields') # # for field_name in ['Category', 'Priority', 'Status']: # field_name = get_yt_name_from_fb__field_name(field_name) # create_custom_field(target, fbugz.CF_TYPES[field_name], field_name, False) fb_category_bundle_name = u'FB Categories' fb_priorities_bundle_name = u'FB Priorities' fb_statuses_bundle_name = u'FB Statuses' common_fields = { u'category' : fb_category_bundle_name, u'priority' : fb_priorities_bundle_name, u'status' : fb_statuses_bundle_name } field_name = u'category' create_bundle_with_values( target, youtrackutils.fbugz.CF_TYPES[get_yt_field_name(field_name)], common_fields[field_name], source.list_categories(), lambda bundle, value: bundle.createElement(to_yt_field_value(field_name, value))) field_name = u'priority' create_bundle_with_values(target, youtrackutils.fbugz.CF_TYPES[get_yt_field_name(field_name)], common_fields[field_name], [elem[0] + '-' + elem[1] for elem in source.list_priorities()], lambda bundle, value : bundle.createElement(to_yt_field_value(field_name, value))) field_name = u'status' statuses = [(to_yt_field_value(field_name, value), resolved) for (value, resolved) in source.list_statuses()] create_bundle_with_values(target, youtrackutils.fbugz.CF_TYPES[get_yt_field_name(field_name)], common_fields[field_name], statuses, lambda bundle, value : to_yt_status(bundle, value)) simple_fields = [u'original_title', u'version', u'computer', u'due', u'estimate'] for name in simple_fields: name = get_yt_field_name(name) create_custom_field(target, youtrackutils.fbugz.CF_TYPES[name], name, False) print('Importing users') for name in ['Normal', 'Deleted', 'Community', 'Virtual'] : group = Group() group.name = name try : target.createGroup(group) print('Group with name [ %s ] successfully created' % name) except: print("Can't create group with name [ %s ] (maybe because it already exists)" % name) users_to_import = [] max = 100 for user in source.get_users() : yt_user = _to_yt_user(user) print('Importing user [ %s ]' % yt_user.login) users_to_import.append(yt_user) if len(users_to_import) >= max: _do_import_users(target, users_to_import) users_to_import = [] _do_import_users(target, users_to_import) print('Importing users finished') # to handle linked issues try : target.createIssueLinkTypeDetailed('parent-child', 'child of', 'parent of', True) except YouTrackException: print("Can't create issue link type [ parent-child ] (maybe because it already exists)") links_to_import = [] for project_name in project_names: value_sets = dict([]) project_id = accessible_projects[project_name] print('Importing project [ %s ]' % project_name) target.createProjectDetailed(project_id, project_name.encode('utf-8'), '', params['project_lead_login']) print('Creating custom fields in project [ %s ]' % project_name) for cf_name in common_fields: bundle_name = common_fields[cf_name] cf_name = get_yt_field_name(cf_name) target.deleteProjectCustomField(project_id, cf_name) target.createProjectCustomFieldDetailed(project_id, cf_name, 'No ' + cf_name.lower(), {'bundle' : bundle_name}) for cf_name in simple_fields: cf_name = get_yt_field_name(cf_name) try: target.createProjectCustomFieldDetailed(project_id, cf_name, 'No ' + cf_name.lower()) except YouTrackException: print("Can't create custom field with name [%s]" % cf_name) cf_name = get_yt_field_name('fix_for') milestones = source.get_milestones(project_id) value_sets["fix_for"] = [] for milestone in milestones: value_sets["fix_for"].append(milestone.name) milestone.name = to_yt_field_value('fix_for', milestone.name) add_values_to_field(target, cf_name, project_id, milestones, lambda bundle, value: _to_yt_version(bundle, value)) cf_name = get_yt_field_name('area') areas = source.get_areas(project_id) value_sets["area"] = [] for area in areas: value_sets["area"].append(area.name) area.name = to_yt_field_value('area', area.name) add_values_to_field(target, cf_name, project_id, areas, lambda bundle, value: _to_yt_subsystem(bundle, value)) print('Importing issues for project [ %s ]' % project_name) start = 0 issues_to_import = [] # create dictionary with child : parent pairs while start <= max_issue_id: fb_issues = source.get_issues(project_name, start, 30) for issue in fb_issues : add_values_to_field(target, get_yt_field_name('area'), project_id, [issue.field_values['area']], lambda bundle, value: bundle.createElement(value)) issues_to_import.append(_to_yt_issue(issue, value_sets)) target.importIssues(project_id, project_name.encode('utf-8') + " assignees", issues_to_import) for issue in fb_issues : full_issue_id = '%s-%s' % (project_id, issue.ix_bug) for attach in issue.attachments : target.createAttachmentFromAttachment(full_issue_id, attach) for tag in issue.tags : target.executeCommand(full_issue_id, 'tag ' + tag) if issue.bug_parent is not None: parent_issue_id = '%s-%s' % (source.get_issue_project_id(issue.bug_parent), issue.bug_parent) link = Link() link.typeName = 'parent-child' link.source = full_issue_id link.target = parent_issue_id links_to_import.append(link) issues_to_import = [] start += 30 print('Importing issues for project [ %s ] finished' % project_name) print('Importing issue links') print(target.importLinks(links_to_import)) print('Importing issue links finished')
def bugzilla2youtrack(target_url, target_login, target_pass, bz_db, bz_host, bz_port, bz_login, bz_pass, bz_product_names, issues_filter): # connecting to bz client = Client(bz_host, int(bz_port), bz_login, bz_pass, db_name=bz_db) if not len(bz_product_names): answer = raw_input("All projects will be imported. Are you sure? [y/n]") if answer.capitalize() != "Y": sys.exit() bz_product_names = client.get_product_names() print "bz_product_names : " + repr(bz_product_names) # connecting to yt target = Connection(target_url, target_login, target_pass) print "Creating issue link types" link_types = client.get_issue_link_types() for link in link_types: print "Processing link type [ %s ]" % link.name try: target.createIssueLinkType(to_yt_issue_link_type(link)) except YouTrackException: print "Can't create link type [ %s ] (maybe because it already exists)" % link.name print "Creating issue link types finished" print "Creating custom fields" custom_fields = client.get_custom_fields() for cf in custom_fields: create_yt_custom_field(cf, target) print "Creating custom fields finished" for key in bugzilla.FIELD_TYPES: if key not in youtrack.EXISTING_FIELDS: create_custom_field(target, bugzilla.FIELD_TYPES[key], key, True, bundle_policy="1") bz_product_ids = [] for name in bz_product_names: product_id = str(client.get_product_id_by_name(name)) bz_product_ids.append(product_id) print "Creating project [ %s ] with name [ %s ]" % (product_id, name) try: target.getProject(str(product_id)) except YouTrackException: target.createProjectDetailed(str(product_id), name, client.get_project_description(product_id), target_login) print "Importing components for project [ %s ]" % product_id process_components(client.get_components(product_id), product_id, target) print "Importing components finished for project [ %s ]" % product_id print "Importing versions for project [ %s ]" % product_id process_versions(client.get_versions(product_id), product_id, target) print "Importing versions finished for project [ %s ] finished" % product_id print "Importing issues to project [ %s ]" % product_id max_count = 100 count = 0 from_id = 0 bz_issues_count = client.get_issues_count(product_id) while count < bz_issues_count: batch = client.get_issues(product_id, from_id, from_id + max_count) batch = [bz_issue for bz_issue in batch if (issues_filter(bz_issue))] count += len(batch) from_id += max_count target.importIssues(product_id, product_id + " assignees", [to_yt_issue(bz_issue, product_id, target) for bz_issue in batch]) # todo convert to good tags import for issue in batch: tags = issue["keywords"] | issue["flags"] for t in tags: print "Processing tag [ %s ]" % t.encode('utf8') target.executeCommand(str(product_id) + "-" + str(issue[get_number_in_project_field_name()]), "tag " + t.encode('utf8')) for issue in batch: for attach in issue["attachments"]: print "Processing attachment [ %s ]" % (attach.name.encode('utf8')) content = StringIO(attach.content) target.createAttachment(str(product_id) + "-" + str(issue[get_number_in_project_field_name()]), attach.name, content, attach.reporter , created=str(int(attach.created) * 1000)) print "Importing issues to project [ %s ] finished" % product_id # todo add pagination to links print "Importing issue links" cf_links = client.get_issue_links() duplicate_links = client.get_duplicate_links() if len(duplicate_links): try: target.createIssueLinkTypeDetailed("Duplicate", "duplicates", "is duplicated by", True) except YouTrackException: print "Can't create link type [ Duplicate ] (maybe because it already exists)" depend_links = client.get_dependencies_link() if len(depend_links): try: target.createIssueLinkTypeDetailed("Depend", "depends on", "is required for", True) except YouTrackException: print "Can't create link type [ Depend ] (maybe because it already exists)" links = cf_links | duplicate_links | depend_links links_to_import = list([]) for link in links: print "Processing link %s for issue%s" % (link.name, link.source) if (str(link.target_product_id) in bz_product_ids) and (str(link.source_product_id) in bz_product_ids): links_to_import.append(to_yt_issue_link(link)) print target.importLinks(links_to_import) print "Importing issue links finished"
def fb2youtrack(target_url, target_login, target_password, source_url, source_login, source_password, project_names, max_issue_id): #encoding = 'utf-8' source = FBClient(source_url, source_login, source_password) target = Connection(target_url, target_login, target_password) accessible_projects = source.list_project_names() for p_name in project_names: if not (p_name in accessible_projects.keys()): print 'Unknown project names. Exiting...' sys.exit() # for p_name in accessible_projects : # if (p_name.encode('utf-8') in project_names_str) : # project_names_str.remove(p_name.encode('utf-8')) # project_names.append(p_name) # # if (len(project_names_str) != 0) : # print 'Unknown project names!' print('Creating custom fields') # # for field_name in ['Category', 'Priority', 'Status']: # field_name = get_yt_name_from_fb__field_name(field_name) # create_custom_field(target, fbugz.CF_TYPES[field_name], field_name, False) fb_category_bundle_name = u'FB Categories' fb_priorities_bundle_name = u'FB Priorities' fb_statuses_bundle_name = u'FB Statuses' common_fields = { u'category': fb_category_bundle_name, u'priority': fb_priorities_bundle_name, u'status': fb_statuses_bundle_name } field_name = u'category' create_bundle_with_values( target, fbugz.CF_TYPES[get_yt_name_from_fb_field_name(field_name)], common_fields[field_name], source.list_categories(), lambda bundle, value: bundle.createElement( to_yt_field_value(field_name, value))) field_name = u'priority' create_bundle_with_values( target, fbugz.CF_TYPES[get_yt_name_from_fb_field_name(field_name)], common_fields[field_name], [elem[0] + '-' + elem[1] for elem in source.list_priorities()], lambda bundle, value: bundle.createElement( to_yt_field_value(field_name, value))) field_name = u'status' statuses = [(to_yt_field_value(field_name, value), resolved) for (value, resolved) in source.list_statuses()] create_bundle_with_values( target, fbugz.CF_TYPES[get_yt_name_from_fb_field_name(field_name)], common_fields[field_name], statuses, lambda bundle, value: to_yt_status(bundle, value)) simple_fields = [ u'original_title', u'version', u'computer', u'due', u'estimate' ] for name in simple_fields: name = get_yt_name_from_fb_field_name(name) create_custom_field(target, fbugz.CF_TYPES[name], name, False) print 'Importing users' for name in ['Normal', 'Deleted', 'Community', 'Virtual']: group = Group() group.name = name try: target.createGroup(group) print 'Group with name [ %s ] successfully created' % name except: print "Can't create group with name [ %s ] (maybe because it already exists)" % name users_to_import = [] max = 100 for user in source.get_users(): yt_user = _to_yt_user(user) print 'Importing user [ %s ]' % yt_user.login users_to_import.append(yt_user) if len(users_to_import) >= max: _do_import_users(target, users_to_import) users_to_import = [] _do_import_users(target, users_to_import) print 'Importing users finished' # to handle linked issues try: target.createIssueLinkTypeDetailed('parent-child', 'child of', 'parent of', True) except YouTrackException: print "Can't create issue link type [ parent-child ] (maybe because it already exists)" links_to_import = [] for project_name in project_names: value_sets = dict([]) project_id = accessible_projects[project_name] print 'Importing project [ %s ]' % project_name target.createProjectDetailed(project_id, project_name.encode('utf-8'), 'no description', 'root') print 'Creating custom fields in project [ %s ]' % project_name for cf_name in common_fields: bundle_name = common_fields[cf_name] cf_name = get_yt_name_from_fb_field_name(cf_name) target.deleteProjectCustomField(project_id, cf_name) target.createProjectCustomFieldDetailed(project_id, cf_name, 'No ' + cf_name.lower(), {'bundle': bundle_name}) for cf_name in simple_fields: cf_name = get_yt_name_from_fb_field_name(cf_name) try: target.createProjectCustomFieldDetailed( project_id, cf_name, 'No ' + cf_name.lower()) except YouTrackException: print "Can't create custom field with name [%s]" % cf_name cf_name = get_yt_name_from_fb_field_name('fix_for') milestones = source.get_milestones(project_id) value_sets["fix_for"] = [] for milestone in milestones: value_sets["fix_for"].append(milestone.name) milestone.name = to_yt_field_value('fix_for', milestone.name) add_values_to_field( target, cf_name, project_id, milestones, lambda bundle, value: _to_yt_version(bundle, value)) cf_name = get_yt_name_from_fb_field_name('area') areas = source.get_areas(project_id) value_sets["area"] = [] for area in areas: value_sets["area"].append(area.name) area.name = to_yt_field_value('area', area.name) add_values_to_field( target, cf_name, project_id, areas, lambda bundle, value: _to_yt_subsystem(bundle, value)) print 'Importing issues for project [ %s ]' % project_name start = 0 issues_to_import = [] # create dictionary with child : parent pairs while start <= max_issue_id: fb_issues = source.get_issues(project_name, start, 30) for issue in fb_issues: add_values_to_field( target, get_yt_name_from_fb_field_name('area'), project_id, [issue.field_values['area']], lambda bundle, value: bundle.createElement(value)) issues_to_import.append(_to_yt_issue(issue, value_sets)) target.importIssues(project_id, project_name.encode('utf-8') + " assignees", issues_to_import) for issue in fb_issues: full_issue_id = '%s-%s' % (project_id, issue.ix_bug) for attach in issue.attachments: target.createAttachmentFromAttachment( full_issue_id, attach) for tag in issue.tags: target.executeCommand(full_issue_id, 'tag ' + tag) if issue.bug_parent is not None: parent_issue_id = '%s-%s' % (source.get_issue_project_id( issue.bug_parent), issue.bug_parent) link = Link() link.typeName = 'parent-child' link.source = full_issue_id link.target = parent_issue_id links_to_import.append(link) issues_to_import = [] start += 30 print 'Importing issues for project [ %s ] finished' % project_name print 'Importing issue links' print target.importLinks(links_to_import) print 'Importing issue links finished'
def bugzilla2youtrack(params): # Connecting to Bugzilla client = Client(host=params['bz_host'], port=int(params['bz_port']), login=params['bz_login'], password=params['bz_password'], db_name=params['bz_db']) bz_product_names = params.get('bz_product_names') if not bz_product_names: answer = raw_input( "All projects will be imported. Are you sure? [Y/n] ") if answer.strip().lower() not in ("y", "yes", ""): sys.exit() bz_product_names = client.get_product_names() print("bz_product_names: " + repr(bz_product_names)) # Connecting to YouTrack token = params.get('token') if not token and 'token_file' in params: try: with open(params['token_file'], 'r') as f: token = f.read().strip() except (OSError, IOError) as e: print("Cannot load token from file: " + str(e)) sys.exit(1) if token: target = Connection(params['yt_url'], token=token) elif 'yt_login' in params: target = Connection(params['yt_url'], params.get('yt_login'), params.get('yt_password')) else: print("You have to provide token or login/password to import data") sys.exit(1) print("Creating issue link types") link_types = client.get_issue_link_types() for link in link_types: print("Processing link type [ %s ]" % link.name) try: target.createIssueLinkType(to_yt_issue_link_type(link)) except YouTrackException: print( "Can't create link type [ %s ] (maybe because it already exists)" % link.name) print("Creating issue link types finished") print("Creating custom fields") custom_fields = client.get_custom_fields() for cf in custom_fields: create_yt_custom_field(cf, target) print("Creating custom fields finished") for key in youtrackutils.bugzilla.FIELD_TYPES: if key not in youtrack.EXISTING_FIELDS: create_custom_field(target, youtrackutils.bugzilla.FIELD_TYPES[key], key, True, bundle_policy="1") bz_product_ids = [] for name in bz_product_names: product_id = str(client.get_product_id_by_name(name)) bz_product_ids.append(product_id) print("Creating project [ %s ] with name [ %s ]" % (product_id, name)) try: target.getProject(product_id) except YouTrackException: target.createProjectDetailed( product_id, name, client.get_project_description(product_id), 'root') print("Importing components for project [ %s ]" % product_id) process_components(client.get_components(product_id), product_id, target) print("Importing components finished for project [ %s ]" % product_id) print("Importing versions for project [ %s ]" % product_id) process_versions(client.get_versions(product_id), product_id, target) print("Importing versions finished for project [ %s ] finished" % product_id) print("Importing issues to project [ %s ]" % product_id) max_count = 100 count = 0 from_id = 0 bz_issues_count = client.get_issues_count(product_id) while count < bz_issues_count: batch = client.get_issues(product_id, from_id, from_id + max_count) batch = [bz_issue for bz_issue in batch] count += len(batch) from_id += max_count target.importIssues(product_id, product_id + " assignees", [ to_yt_issue(bz_issue, product_id, target) for bz_issue in batch ]) # todo convert to good tags import for issue in batch: tags = issue["keywords"] | issue["flags"] for t in tags: print("Processing tag [ %s ]" % t.encode('utf8')) target.executeCommand( str(product_id) + "-" + str(issue[get_number_in_project_field_name()]), "tag " + t.encode('utf8')) for issue in batch: issue_id = str(product_id) + '-' + \ str(issue[get_number_in_project_field_name()]) for attach in issue["attachments"]: print("Processing attachment [ %s ] for issue %s" % (utf8encode(attach.name), issue_id)) content = StringIO(attach.content) try: target.importAttachment( issue_id, attach.name, content, attach.reporter.login, None, None, str(int(attach.created) * 1000)) except urllib2.HTTPError as e: print("WARN: Cant import attachment [ %s ]" % utf8encode(attach.name)) print(e.code) print(e.read()) print("Please check Max Upload File Size in YouTrack") continue print("Importing issues to project [ %s ] finished" % product_id) # todo add pagination to links print("Importing issue links") cf_links = client.get_issue_links() duplicate_links = client.get_duplicate_links() if len(duplicate_links): try: target.createIssueLinkTypeDetailed("Duplicate", "duplicates", "is duplicated by", True) except YouTrackException: print( "Can't create link type [ Duplicate ] (maybe because it already exists)" ) depend_links = client.get_dependencies_link() if len(depend_links): try: target.createIssueLinkTypeDetailed("Depend", "depends on", "is required for", True) except YouTrackException: print( "Can't create link type [ Depend ] (maybe because it already exists)" ) links = cf_links | duplicate_links | depend_links links_to_import = list([]) for link in links: print("Processing link %s for issue%s" % (link.name, link.source)) if (str(link.target_product_id) in bz_product_ids) and (str( link.source_product_id) in bz_product_ids): links_to_import.append(to_yt_issue_link(link)) print(target.importLinks(links_to_import)) print("Importing issue links finished")
def fb2youtrack(target_url, target_login, target_password, source_url, source_login, source_password, project_names, max_issue_id) : #encoding = 'utf-8' source = FBClient(source_url, source_login, source_password) target = Connection(target_url, target_login, target_password) accessible_projects = source.list_project_names() for p_name in project_names : if not(p_name in accessible_projects.keys()) : print 'Unknown project names. Exiting...' sys.exit() # for p_name in accessible_projects : # if (p_name.encode('utf-8') in project_names_str) : # project_names_str.remove(p_name.encode('utf-8')) # project_names.append(p_name) # # if (len(project_names_str) != 0) : # print 'Unknown project names!' print('Creating custom fields') # # for field_name in ['Category', 'Priority', 'Status']: # field_name = get_yt_name_from_fb__field_name(field_name) # create_custom_field(target, fbugz.CF_TYPES[field_name], field_name, False) fb_category_bundle_name = u'FB Categories' fb_priorities_bundle_name = u'FB Priorities' fb_statuses_bundle_name = u'FB Statuses' common_fields = { u'category' : fb_category_bundle_name, u'priority' : fb_priorities_bundle_name, u'status' : fb_statuses_bundle_name } field_name = u'category' create_bundle_with_values(target,fbugz.CF_TYPES[get_yt_name_from_fb_field_name(field_name)], common_fields[field_name], source.list_categories(), lambda bundle, value : bundle.createElement(to_yt_field_value(field_name, value))) field_name = u'priority' create_bundle_with_values(target, fbugz.CF_TYPES[get_yt_name_from_fb_field_name(field_name)], common_fields[field_name], [elem[0] + '-' + elem[1] for elem in source.list_priorities()], lambda bundle, value : bundle.createElement(to_yt_field_value(field_name, value))) field_name = u'status' statuses = [(to_yt_field_value(field_name, value), resolved) for (value, resolved) in source.list_statuses()] create_bundle_with_values(target, fbugz.CF_TYPES[get_yt_name_from_fb_field_name(field_name)], common_fields[field_name], statuses, lambda bundle, value : to_yt_status(bundle, value)) simple_fields = [u'original_title', u'version', u'computer', u'due', u'estimate'] for name in simple_fields: name = get_yt_name_from_fb_field_name(name) create_custom_field(target, fbugz.CF_TYPES[name], name, False) print 'Importing users' for name in ['Normal', 'Deleted', 'Community', 'Virtual'] : group = Group() group.name = name try : target.createGroup(group) print 'Group with name [ %s ] successfully created' % name except: print "Can't create group with name [ %s ] (maybe because it already exists)" % name users_to_import = [] max = 100 for user in source.get_users() : yt_user = _to_yt_user(user) print 'Importing user [ %s ]' % yt_user.login users_to_import.append(yt_user) if len(users_to_import) >= max: _do_import_users(target, users_to_import) users_to_import = [] _do_import_users(target, users_to_import) print 'Importing users finished' # to handle linked issues try : target.createIssueLinkTypeDetailed('parent-child', 'child of', 'parent of', True) except YouTrackException: print "Can't create issue link type [ parent-child ] (maybe because it already exists)" links_to_import = [] for project_name in project_names : value_sets = dict([]) project_id = accessible_projects[project_name] print 'Importing project [ %s ]' % project_name target.createProjectDetailed(project_id, project_name.encode('utf-8'), 'no description', 'root') print 'Creating custom fields in project [ %s ]' % project_name for cf_name in common_fields: bundle_name = common_fields[cf_name] cf_name = get_yt_name_from_fb_field_name(cf_name) target.deleteProjectCustomField(project_id, cf_name) target.createProjectCustomFieldDetailed(project_id, cf_name, 'No ' + cf_name.lower(), {'bundle' : bundle_name}) for cf_name in simple_fields: cf_name = get_yt_name_from_fb_field_name(cf_name) try: target.createProjectCustomFieldDetailed(project_id, cf_name, 'No ' + cf_name.lower()) except YouTrackException: print "Can't create custom field with name [%s]" % cf_name cf_name = get_yt_name_from_fb_field_name('fix_for') milestones = source.get_milestones(project_id) value_sets["fix_for"] = [] for milestone in milestones: value_sets["fix_for"].append(milestone.name) milestone.name = to_yt_field_value('fix_for', milestone.name) add_values_to_field(target, cf_name, project_id, milestones, lambda bundle, value: _to_yt_version(bundle, value)) cf_name = get_yt_name_from_fb_field_name('area') areas = source.get_areas(project_id) value_sets["area"] = [] for area in areas: value_sets["area"].append(area.name) area.name = to_yt_field_value('area', area.name) add_values_to_field(target, cf_name, project_id, areas, lambda bundle, value: _to_yt_subsystem(bundle, value)) print 'Importing issues for project [ %s ]' % project_name start = 0 issues_to_import = [] # create dictionary with child : parent pairs while start <= max_issue_id: fb_issues = source.get_issues(project_name, start, 30) for issue in fb_issues : add_values_to_field(target, get_yt_name_from_fb_field_name('area'), project_id, [issue.field_values['area']], lambda bundle, value: bundle.createElement(value)) issues_to_import.append(_to_yt_issue(issue, value_sets)) target.importIssues(project_id, project_name.encode('utf-8') + " assignees", issues_to_import) for issue in fb_issues : full_issue_id = '%s-%s' % (project_id, issue.ix_bug) for attach in issue.attachments : target.createAttachmentFromAttachment(full_issue_id, attach) for tag in issue.tags : target.executeCommand(full_issue_id, 'tag ' + tag) if issue.bug_parent is not None: parent_issue_id = '%s-%s' % (source.get_issue_project_id(issue.bug_parent), issue.bug_parent) link = Link() link.typeName = 'parent-child' link.source = full_issue_id link.target = parent_issue_id links_to_import.append(link) issues_to_import = [] start += 30 print 'Importing issues for project [ %s ] finished' % project_name print 'Importing issue links' print target.importLinks(links_to_import) print 'Importing issue links finished'