class ConnectionTest(unittest.TestCase):
    def setUp(self):
        #self.con = Connection('http://teamsys.intellij.net', 'resttest', 'resttest')
        self.con = Connection("http://localhost:8081", "root", "root")

    def test_getProject(self):
        p = self.con.getProject('SB')
        self.assertEqual(p.id, 'SB')
        self.assertEqual(p.name, 'Sandbox')

    def test_getSubsystems(self):
        subsystems = self.con.getSubsystems('SB')
        default = [s for s in subsystems if s.isDefault][0]
        self.assertTrue(default is not None)

    def test_getIssue(self):
        i = self.con.getIssue('SB-1')
        self.assertEqual(i.id, 'SB-1')
        self.assertEqual(i.numberInProject, '1')
        self.assertEqual(i.projectShortName, 'SB')

    def test_createIssue(self):
        i = self.con.createIssue('SB', 'resttest', 'Test issue',
                                 'Test description', '2', 'Bug', 'First',
                                 'Open', '', '', '')
        self.assertEqual(i.projectShortName, 'SB')
        self.assertEqual(i.priority, '2')
        self.assertEqual(i.type, 'Bug')
        self.assertEqual(i.subsystem, 'First')

    def test_createIssueAttachment(self):
        i = self.con.createIssue('SB', 'resttest', 'For attachmkents test',
                                 'Test description', '2', 'Bug', 'First',
                                 'Open', '', '', '')
        fname = 'connection_test.py'
        content = open(fname)
        self.con.createAttachment(i.id, fname, content)
        self.assertEqual(fname, self.con.getAttachments(i.id)[0].name)

    def test_createAndDeleteSubsystem(self):
        name = 'Test Subsystem [' + str(random.random()) + "]"
        self.con.createSubsystemDetailed('SB', name, False, 'resttest')
        s = self.con.getSubsystem('SB', name)
        self.assertEqual(s.name, name)
        self.assertEqual(s.isDefault, 'false')
        #todo: uncomment when fix deployed to teamsys
        #self.assertEqual(s.defaultAssignee, 'resttest')
        self.con.deleteSubsystem('SB', name)

    def test_importIssues(self):
        issues = self.con.getIssues("A", "", 0, 10)
        for issue in issues:
            if hasattr(issue, "Assignee"):
                issue["assigneeName"] = issue["Assignee"]
                del issue.Assignee
        self.con.importIssues("B", "assignees", issues)
class ConnectionTest(unittest.TestCase):

    def setUp(self):
        #self.con = Connection('http://teamsys.intellij.net', 'resttest', 'resttest')
        self.con = Connection("http://localhost:8081", "root", "root")
    def test_getProject(self):
        p = self.con.getProject('SB')
        self.assertEqual(p.id, 'SB')
        self.assertEqual(p.name, 'Sandbox')

    def test_getSubsystems(self):
        subsystems = self.con.getSubsystems('SB')
        default = [s for s in subsystems if s.isDefault][0]
        self.assertTrue(default is not None)        

    def test_getIssue(self):
        i = self.con.getIssue('SB-1')
        self.assertEqual(i.id, 'SB-1')
        self.assertEqual(i.numberInProject, '1')
        self.assertEqual(i.projectShortName, 'SB')

    def test_createIssue(self):
        i = self.con.createIssue('SB', 'resttest', 'Test issue', 'Test description', '2', 'Bug', 'First', 'Open', '', '', '')
        self.assertEqual(i.projectShortName, 'SB')
        self.assertEqual(i.priority, '2')
        self.assertEqual(i.type, 'Bug')
        self.assertEqual(i.subsystem, 'First')

    def test_createIssueAttachment(self):
        i = self.con.createIssue('SB', 'resttest', 'For attachmkents test', 'Test description', '2', 'Bug', 'First', 'Open', '', '', '')
        fname = 'connection_test.py'
        content = open(fname)
        self.con.createAttachment(i.id, fname, content)
        self.assertEqual(fname, self.con.getAttachments(i.id)[0].name)

    def test_createAndDeleteSubsystem(self):
        name = 'Test Subsystem [' + str(random.random()) + "]"
        self.con.createSubsystemDetailed('SB', name, False, 'resttest')
        s = self.con.getSubsystem('SB', name)
        self.assertEqual(s.name, name)
        self.assertEqual(s.isDefault, 'false')
        #todo: uncomment when fix deployed to teamsys
        #self.assertEqual(s.defaultAssignee, 'resttest')
        self.con.deleteSubsystem('SB', name)

    def test_importIssues(self):
        issues = self.con.getIssues("A", "", 0, 10)
        for issue in issues:
            if hasattr(issue, "Assignee"):
                issue["assigneeName"] = issue["Assignee"]
                del issue.Assignee
        self.con.importIssues("B", "assignees", issues)
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 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 trac2youtrack(target_url, target_login, target_password, project_ID, project_name, env_path):
    # creating connection to trac to import issues to
    client = Client(env_path)
    # creating connection to youtrack to import issues in
    target = Connection(target_url, target_login, target_password)

    #create project
    print "Creating project[%s]" % project_name
    try :
        target.getProject(project_ID)
    except youtrack.YouTrackException:
        target.createProjectDetailed(project_ID, project_name, client.get_project_description(), target_login)

    #importing users
    trac_users = client.get_users()
    print "Importing users"
    yt_users = list([])
    # converting trac users to yt users
    registered_users = set([])
    for user in trac_users :
        print "Processing user [ %s ]" % user.name
        registered_users.add(user.name)
        yt_users.append(to_youtrack_user(user))
        # adding users to yt project
    target.importUsers(yt_users)
    print "Importing users finished"

    print "Creating project custom fields"

    create_yt_custom_field(target, project_ID, "Priority", client.get_issue_priorities())

    create_yt_custom_field(target, project_ID, "Type", client.get_issue_types())

    trac_resolution_to_yt_state = lambda track_field, yt_bundle : to_youtrack_state(track_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Resolution", client.get_issue_resolutions(), trac_resolution_to_yt_state)

    trac_versions = client.get_versions()
    trac_version_to_yt_version = lambda trac_field, yt_bundle : to_youtrack_version(trac_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Version", trac_versions, trac_version_to_yt_version)
    #create_yt_bundle_custom_field(target, project_ID, "Affected versions", trac_versions, trac_version_to_yt_version)

    trac_components = client.get_components()
    for cmp in trac_components :
        if cmp.owner not in registered_users :
            cmp.owner, registered_users = process_non_authorised_user(target, registered_users, cmp.owner)
    trac_component_to_yt_subsystem = lambda trac_field, yt_bundle : to_youtrack_subsystem(trac_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Component", trac_components, trac_component_to_yt_subsystem)

    create_yt_custom_field(target, project_ID, "Severity", client.get_severities())

    trac_custom_fields = client.get_custom_fields_declared()
    check_box_fields = dict([])
    for elem in trac_custom_fields:
        print "Processing custom field [ %s ]" % elem.name
        type_name = None
        if elem.type == "checkbox":
            if len(elem.label) > 0:
                opt = elem.label
            else:
                opt = elem.name
            options = list([opt])
            check_box_fields[elem.name] = opt
        else:
            options = elem.options

        values = None
        if len(options):
            values = options

        field_name = elem.name
        if field_name in tracLib.FIELD_NAMES.keys() :
            field_name = tracLib.FIELD_NAMES[field_name]

        field_type = tracLib.CUSTOM_FIELD_TYPES[elem.type]
        if field_name in tracLib.FIELD_TYPES.keys():
            field_type = tracLib.FIELD_TYPES[field_name]

        process_custom_field(target, project_ID, field_type, field_name, trac_values_to_youtrack_values(field_name, values))
        print "Creating project custom fields finished"

    print "Importing issues"
    trac_issues = client.get_issues()
    yt_issues = list([])
    counter = 0
    max = 100
    for issue in trac_issues:
        print "Processing issue [ %s ]" % (str(issue.id))
        counter += 1
        if not (issue.reporter in registered_users):
            yt_user, registered_users = process_non_authorised_user(target, registered_users, issue.reporter)
            if yt_user is None :
                issue.reporter = "guest"
            else:
                issue.reporter = yt_user
        if not (issue.owner in registered_users):
            yt_user, registered_users = process_non_authorised_user(target, registered_users, issue.owner)
            if yt_user is None :
                issue.owner = ""
            else:
                issue.owner = yt_user
        legal_cc = set([])
        for cc in issue.cc:
            if cc in registered_users:
                legal_cc.add(cc)
        issue.cc = legal_cc

        yt_issues.append(to_youtrack_issue(issue, check_box_fields))
        if counter == max:
            counter = 0
            print target.importIssues(project_ID, project_name + ' Assignees', yt_issues)
            yt_issues = list([])
    print target.importIssues(project_ID, project_name + ' Assignees', yt_issues)
    print 'Importing issues finished'
    #importing tags
    print "Importing keywords"
    for issue in trac_issues:
        print "Importing tags from issue [ %s ]" % (str(issue.id))
        tags = issue.keywords
        for t in tags:
            target.executeCommand(str(project_ID) + "-" + str(issue.id), "tag " + t.encode('utf-8'))
    print "Importing keywords finished"

    print "Importing attachments"
    for issue in trac_issues:
        print "Processing issue [ %s ]" % (str(issue.id))
        issue_attach = issue.attachment
        for attach in issue_attach:
            print "Processing attachment [ %s ]" % attach.filename.encode('utf-8')
            if not (attach.author_name in registered_users):
                yt_user, registered_users = process_non_authorised_user(target, registered_users, attach.author_name)
                if yt_user is None :
                    attach.author_name = "guest"
                else:
                    attach.author_name = yt_user
            content = open(urllib.quote(attach.filename.encode('utf-8')))
            target.createAttachment(str(project_ID) + "-" + str(issue.id), attach.name, content, attach.author_name,
                                    created=attach.time)
    print "Importing attachments finished"

    print "Importing workitems"
    tt_enabled = False
    for issue in trac_issues:
        if issue.workitems:
            if not tt_enabled:
                tt_settings = target.getProjectTimeTrackingSettings(str(project_ID))
                if not tt_settings.Enabled:
                    print "Enabling TimeTracking for the prject"
                    target.setProjectTimeTrackingSettings(str(project_ID), enabled=True)
                tt_enabled = True
            print "Processing issue [ %s ]" % (str(issue.id))
            workitems = [to_youtrack_workitem(w) for w in issue.workitems]
            target.importWorkItems(str(project_ID) + "-" + str(issue.id), workitems)
    print "Importing workitems finished"
def trac2youtrack(target_url, target_login, target_password, project_ID, project_name, env_path):
    # creating connection to trac to import issues to
    client = Client(env_path)
    # creating connection to util to import issues in
    target = Connection(target_url, target_login, target_password)

    # create project
    print("Creating project[%s]" % project_name)
    try:
        target.getProject(project_ID)
    except youtrack.YouTrackException:
        target.createProjectDetailed(project_ID, project_name, client.get_project_description(), target_login)

    # importing users
    trac_users = client.get_users()
    print("Importing users")
    yt_users = list([])

    # converting trac users to yt users
    registered_users = set([])
    for user in trac_users :
        print("Processing user [ %s ]" % user.name)
        registered_users.add(user.name)
        yt_users.append(to_youtrack_user(user))
        # adding users to yt project
    target.importUsers(yt_users)
    print("Importing users finished")

    print("Creating project custom fields")

    create_yt_custom_field(target, project_ID, "Priority", client.get_issue_priorities())

    create_yt_custom_field(target, project_ID, "Type", client.get_issue_types())

    trac_resolution_to_yt_state = lambda track_field, yt_bundle : to_youtrack_state(track_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Resolution", client.get_issue_resolutions(), trac_resolution_to_yt_state)

    trac_version_to_yt_version = lambda trac_field, yt_bundle : to_youtrack_version(trac_field, yt_bundle)

    trac_versions = client.get_versions()
    create_yt_bundle_custom_field(target, project_ID, "Affected versions", trac_versions, trac_version_to_yt_version)

    trac_milestones = client.get_milestones()
    create_yt_bundle_custom_field(target, project_ID, "Fix versions", trac_milestones, trac_version_to_yt_version)

    trac_components = client.get_components()
    for cmp in trac_components :
        if cmp.owner not in registered_users :
            cmp.owner, registered_users = process_non_authorised_user(target, registered_users, cmp.owner)
    trac_component_to_yt_subsystem = lambda trac_field, yt_bundle : to_youtrack_subsystem(trac_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Component", trac_components, trac_component_to_yt_subsystem)

    create_yt_custom_field(target, project_ID, "Severity", client.get_severities())

    trac_custom_fields = client.get_custom_fields_declared()
    check_box_fields = dict([])
    for elem in trac_custom_fields:
        print("Processing custom field [ %s ]" % elem.name)
        if elem.type == "checkbox":
            if len(elem.label) > 0:
                opt = elem.label
            else:
                opt = elem.name
            options = list([opt])
            check_box_fields[elem.name] = opt
        else:
            options = elem.options

        values = None
        if len(options):
            values = options

        field_name = elem.name
        if field_name in youtrackutils.tracLib.FIELD_NAMES.keys() :
            field_name = youtrackutils.tracLib.FIELD_NAMES[field_name]

        field_type = youtrackutils.tracLib.CUSTOM_FIELD_TYPES[elem.type]
        if field_name in youtrackutils.tracLib.FIELD_TYPES.keys():
            field_type = youtrackutils.tracLib.FIELD_TYPES[field_name]

        process_custom_field(target, project_ID, field_type, field_name, trac_values_to_youtrack_values(field_name, values))
        print("Creating project custom fields finished")

    print("Importing issues")
    trac_issues = client.get_issues()
    yt_issues = list([])
    counter = 0
    max = 100
    for issue in trac_issues:
        print("Processing issue [ %s ]" % (str(issue.id)))
        counter += 1
        if not (issue.reporter in registered_users):
            yt_user, registered_users = process_non_authorised_user(target, registered_users, issue.reporter)
            if yt_user is None :
                issue.reporter = "guest"
            else:
                issue.reporter = yt_user
        if not (issue.owner in registered_users):
            yt_user, registered_users = process_non_authorised_user(target, registered_users, issue.owner)
            if yt_user is None :
                issue.owner = ""
            else:
                issue.owner = yt_user
        legal_cc = set([])
        for cc in issue.cc:
            if cc in registered_users:
                legal_cc.add(cc)
        issue.cc = legal_cc

        yt_issues.append(to_youtrack_issue(project_ID, issue, check_box_fields))
        if counter == max:
            counter = 0
            print(target.importIssues(project_ID, project_name + ' Assignees', yt_issues))
            yt_issues = list([])
    print(target.importIssues(project_ID, project_name + ' Assignees', yt_issues))
    print('Importing issues finished')

    # importing tags
    print("Importing keywords")
    for issue in trac_issues:
        print("Importing tags from issue [ %s ]" % (str(issue.id)))
        tags = issue.keywords
        for t in tags:
            target.executeCommand(str(project_ID) + "-" + str(issue.id), "tag " + t.encode('utf-8'))
    print("Importing keywords finished")

    print("Importing attachments")
    for issue in trac_issues:
        print("Processing issue [ %s ]" % (str(issue.id)))
        issue_attach = issue.attachment
        for attach in issue_attach:
            print("Processing attachment [ %s ]" % attach.filename.encode('utf-8'))
            if not (attach.author_name in registered_users):
                yt_user, registered_users = process_non_authorised_user(target, registered_users, attach.author_name)
                if yt_user is None:
                    attach.author_name = "guest"
                else:
                    attach.author_name = yt_user
            content = open(urllib.quote(attach.filename.encode('utf-8')))
            target.createAttachment(str(project_ID) + "-" + str(issue.id), attach.name, content, attach.author_name,
                                    created=attach.time)
    print("Importing attachments finished")

    print("Importing workitems")
    tt_enabled = False
    for issue in trac_issues:
        if issue.workitems:
            if not tt_enabled:
                tt_settings = target.getProjectTimeTrackingSettings(str(project_ID))
                if not tt_settings.Enabled:
                    print("Enabling TimeTracking for the project")
                    target.setProjectTimeTrackingSettings(str(project_ID), enabled=True)
                tt_enabled = True
            print("Processing issue [ %s ]" % (str(issue.id)))
            workitems = [to_youtrack_workitem(w) for w in issue.workitems]
            target.importWorkItems(str(project_ID) + "-" + str(issue.id), workitems)
    print("Importing workitems finished")
def redmine2youtrack(target_url, target_login, target_password, project_ID, project_name, url, api_key, from_project_ID):
    # creating connection to redmine to import issues to
    client = Client(url=url, api_key=api_key)
    # creating connection to youtrack to import issues in
    target = Connection(target_url, target_login, target_password)

    #create project
    print "Creating project[%s]" % project_name
    try :
        target.getProject(project_ID)
    except youtrack.YouTrackException:
        target.createProjectDetailed(project_ID, project_name, client.get_project_description(), target_login)

    #importing users
    redmine_users = client.get_users()
    print "Importing users"
    yt_users = list([])
    # converting redmine users to yt users
    registered_users = set([])
    for user in redmine_users :
        print "Processing user [ %s ]" % user.login
        registered_users.add(user.id)
        yt_users.append(to_youtrack_user(user))
        # adding users to yt project
    target.importUsers(yt_users)
    print "Importing users finished"

    print "Creating project custom fields"

    create_yt_custom_field(target, project_ID, "Priority", client.get_issue_priorities())
    create_yt_custom_field(target, project_ID, "Type", client.get_issue_types())

    redmine_resolution_to_yt_state = lambda track_field, yt_bundle : to_youtrack_state(track_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Resolution", client.get_issue_resolutions(), redmine_resolution_to_yt_state)

    redmine_versions = client.get_versions(project_id=from_project_ID)
    redmine_version_to_yt_version = lambda redmine_field, yt_bundle : to_youtrack_version(redmine_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Version", redmine_versions, redmine_version_to_yt_version)
    #create_yt_bundle_custom_field(target, project_ID, "Affected versions", redmine_versions, redmine_version_to_yt_version)

    redmine_components = client.get_components(project_id=from_project_ID)

    redmine_component_to_yt_subsystem = lambda redmine_field, yt_bundle : to_youtrack_subsystem(redmine_field, yt_bundle)
    create_yt_bundle_custom_field(target, project_ID, "Component", redmine_components, redmine_component_to_yt_subsystem)

    redmine_custom_fields = client.get_custom_fields_declared()
    check_box_fields = dict([])
    for elem in redmine_custom_fields:
        print "Processing custom field [ %s ]" % elem.name
        type_name = None
        if elem.type == "checkbox":
            if len(elem.label) > 0:
                opt = elem.label
            else:
                opt = elem.name
            options = list([opt])
            check_box_fields[elem.name] = opt
        else:
            options = elem.options

        values = None
        if len(options):
            values = options

        field_name = elem.name
        if field_name in redmine.FIELD_NAMES.keys() :
            field_name = redmine.FIELD_NAMES[field_name]

        field_type = redmine.CUSTOM_FIELD_TYPES[elem.type]
        if field_name in redmine.FIELD_TYPES.keys():
            field_type = redmine.FIELD_TYPES[field_name]

        process_custom_field(target, project_ID, field_type, field_name, redmine_values_to_youtrack_values(field_name, values))
        print "Creating project custom fields finished"

    print "Importing issues"
    redmine_issues = client.get_all_issues(options={'project_id': from_project_ID})
    yt_issues = list([])
    counter = 0
    max = 100
    for issue in redmine_issues:
        print "Processing issue [ %s ]" % (str(issue.id))
        counter += 1
        if not issue.author is None and not (issue.author.id in registered_users):
            issue.author = None
        if hasattr(issue, 'assigned_to') and not issue.assigned_to is None and not (issue.assigned_to.id in registered_users):
            issue.assigned_to = None
        #legal_cc = set([])
        #for cc in issue.cc:
        #    if cc in registered_users:
        #        legal_cc.add(cc)
        #issue.cc = legal_cc

        yt_issues.append(to_youtrack_issue(issue, check_box_fields))
        if counter == max:
            counter = 0
            print target.importIssues(project_ID, project_name + ' Assignees', yt_issues)
            yt_issues = list([])
    print target.importIssues(project_ID, project_name + ' Assignees', yt_issues)
    print 'Importing issues finished'
    #importing tags
    #print "Importing keywords"
    #for issue in redmine_issues:
    #    print "Importing tags from issue [ %s ]" % (str(issue.id))
    #    tags = issue.keywords
    #    for t in tags:
    #        target.executeCommand(str(project_ID) + "-" + str(issue.id), "tag " + t.encode('utf-8'))
    #print "Importing keywords finished"

    print "Importing attachments"
    for issue in redmine_issues:
        print "Processing issue [ %s ]" % (str(issue.id))
        issue_attach = issue.attachment
        for attach in issue_attach:
            print "Processing attachment [ %s ]" % attach.filename.encode('utf-8')
            if not (attach.author_name.id in registered_users):
                attach.author_name = "guest"
            content = open(urllib.quote(attach.filename.encode('utf-8')))
            target.createAttachment(str(project_ID) + "-" + str(issue.id), attach.filename, content, attach.author_name,
                                    created=attach.time)
    print "Importing attachments finished"
def mantis2youtrack(
    target_url,
    target_login,
    target_pass,
    mantis_db_name,
    mantis_db_host,
    mantis_db_port,
    mantis_db_login,
    mantis_db_pass,
    mantis_project_names,
):
    print "target_url             : " + target_url
    print "target_login           : "******"target_pass            : "******"mantis_db_name         : " + mantis_db_name
    print "mantis_db_host         : " + mantis_db_host
    print "mantis_db_port         : " + mantis_db_port
    print "mantis_db_login        : "******"mantis_db_pass         : "******"mantis_project_names   : " + repr(mantis_project_names)

    # connacting to yt
    target = Connection(target_url, target_login, target_pass)
    # connacting to mantis
    client = MantisClient(
        mantis_db_host, int(mantis_db_port), mantis_db_login, mantis_db_pass, mantis_db_name, mantis.CHARSET
    )
    if not len(mantis_project_names):
        print "You should declarer at least one project to import"
        sys.exit()

    value_sets = dict([])

    print "Importing users"
    yt_users = []
    value_sets["user"] = set([])
    for user in client.get_mantis_users():
        print "Processing user [ %s ]" % user.user_name
        value_sets["user"].add(user.user_name)
        yt_users.append(to_yt_user(user))
    target.importUsers(yt_users)
    print "Importing users finished"

    print "Creating custom fields definitions"
    value_sets.update(create_custom_fields(target, u"priority", mantis.PRIORITY_VALUES.values()))
    value_sets.update(create_custom_fields(target, u"severity", mantis.SEVERITY_VALUES.values()))
    value_sets.update(create_custom_fields(target, u"category", ["No subsystem"], "1"))
    value_sets.update(create_custom_fields(target, u"version", [], "1"))
    value_sets.update(create_custom_fields(target, u"fixed_in_version", [], "1"))
    value_sets.update(create_custom_fields(target, u"build", [], "1"))
    value_sets.update(create_custom_fields(target, u"platform"))
    value_sets.update(create_custom_fields(target, u"os"))
    value_sets.update(create_custom_fields(target, u"os_build"))
    value_sets.update(create_custom_fields(target, u"due_date"))
    value_sets.update(create_custom_fields(target, u"Reproducibility", mantis.REPRODUCIBILITY_VALUES.values()))

    # create custom field for target version
    field = None
    try:
        field = target.getCustomField("Fix versions")
    except YouTrackException:
        pass
    if field is not None:
        if hasattr(field, "defaultBundle"):
            bundle = field.defaultBundle
            for name in get_yt_cf_name_from_mantis_cf_name("target_version"):
                try:
                    target.createCustomFieldDetailed(
                        name,
                        mantis.FIELD_TYPES[name],
                        False,
                        True,
                        True,
                        {"defaultBundle": bundle, "attachBundlePolicy": "1"},
                    )
                except YouTrackException:
                    pass

    value_sets.update(
        create_auto_attached_bundle_custom_fields(
            target,
            u"status",
            mantis.STATUS_VALUES.values(),
            lambda status, bundle, value_mapping: to_yt_state(status, bundle, value_mapping),
        )
    )

    value_sets.update(
        create_auto_attached_bundle_custom_fields(
            target,
            u"resolution",
            mantis.RESOLUTION_VALUES.values(),
            lambda resolution, bundle, value_mapping: to_yt_state(resolution, bundle, value_mapping),
        )
    )

    if mantis.CREATE_CF_FOR_SUBPROJECT:
        value_sets.update(create_custom_fields(target, u"subproject", [], "1"))

    handler_field_name = u"handler"
    value_sets.update(create_custom_fields(target, handler_field_name, [], "1"))
    for name in get_yt_cf_name_from_mantis_cf_name(handler_field_name):
        value_sets[name] = value_sets["user"]

    # adding some custom fields that are predefined in mantis
    project_ids = []
    for name in mantis_project_names:
        project_ids.append(client.get_project_id_by_name(name))

    custom_fields = client.get_mantis_custom_fields(project_ids)

    for cf_def in custom_fields:
        print "Processing custom field [ %s ]" % cf_def.name.encode("utf-8")
        value_sets.update(process_mantis_custom_field(target, cf_def))

    print "Creating custom fields definitions finished"

    for name in mantis_project_names:
        project_id = int(client.get_project_id_by_name(name))
        print "Creating project [ %s ] with name [ %s ]" % (project_id, name)
        try:
            target.getProject(str(project_id))
        except YouTrackException:
            target.createProjectDetailed(
                str(project_id), name, client.get_project_description(project_id), target_login
            )

        print "Importing components to project [ %s ]" % project_id
        value_sets.update(
            add_values_to_fields(
                target,
                project_id,
                u"category",
                client.get_mantis_categories(project_id),
                lambda component, yt_bundle, value_mapping: to_yt_subsystem(component, yt_bundle, value_mapping),
            )
        )
        print "Importing components to project [ %s ] finished" % project_id

        print "Importing versions to project [ %s ]" % project_id
        mantis_versions = client.get_mantis_versions(project_id)
        value_sets.update(
            add_values_to_fields(
                target,
                project_id,
                u"version",
                mantis_versions,
                lambda version, yt_bundle, value_mapping: to_yt_version(version, yt_bundle, value_mapping),
            )
        )

        value_sets.update(
            add_values_to_fields(
                target,
                project_id,
                u"fixed_in_version",
                mantis_versions,
                lambda version, yt_bundle, value_mapping: to_yt_version(version, yt_bundle, value_mapping),
            )
        )

        for name in get_yt_cf_name_from_mantis_cf_name("target_version"):
            value_sets[name] = value_sets["Fix versions"]

        print "Importing versions to project [ %s ] finished" % project_id

        print "Attaching custom fields to project [ %s ]" % project_id
        cf_ids = client.get_custom_fields_attached_to_project(project_id)

        ignore = []
        for cf in custom_fields:
            if cf.field_id in cf_ids:
                attach_field_to_project(target, project_id, cf.name)
            else:
                ignore.append(cf.name)

        if mantis.CREATE_CF_FOR_SUBPROJECT:
            value_sets.update(
                add_values_to_fields(
                    target,
                    project_id,
                    u"subproject",
                    client.get_mantis_subprojects(project_id),
                    lambda sp_name, yt_bundle, value_mapping: yt_bundle.createElement(sp_name)
                    if sp_name not in value_mapping
                    else yt_bundle.createElement(value_sets[sp_name]),
                )
            )
        print "Attaching custom fields to project [ %s ] finished" % project_id

        print "Importing issues to project [ %s ]" % project_id
        mantis_issues = client.get_mantis_issues(project_id)
        yt_issues = []
        max_count = 100
        for issue in mantis_issues:
            # print "Processing issue [ %s ]" % str(issue.id)
            yt_issues.append(to_yt_issue(issue, value_sets, ignore))
            if len(yt_issues) >= max_count:
                print target.importIssues(str(project_id), name + "Assignees", yt_issues)
                yt_issues = []
        target.importIssues(str(project_id), str(project_id) + "Assignees", yt_issues)
        print "Importing issues to project [ %s ] finished" % project_id

        print "Importing issue attachments to project [ %s ]" % project_id
        mantis_attachments = client.get_mantis_attachments(project_id)
        for attachment in mantis_attachments:
            print "Processing issue attachment [ %s ]" % str(attachment.id)
            content = StringIO(attachment.content)
            authorLogin = client.get_user_name_by_id(attachment.user_id)
            target.createAttachment(
                "%s-%s" % (project_id, attachment.bug_id),
                attachment.filename,
                content,
                authorLogin,
                attachment.file_type,
                None,
                str(attachment.date_added * 1000),
            )
        print "Importing issue attachments to project [ %s ] finished" % project_id

        print "Importing tags to issues from project [ %s ]" % project_id
        for issue in mantis_issues:
            print "Processing tags for issue [ %s ]" % str(issue.id)
            for tag in issue.tags:
                print "Processing tag [ %s ]" % tag.encode("utf8")
                target.executeCommand(str(project_id) + "-" + str(issue.id), "tag " + tag.encode("utf8"))
        print "Importing tags to issues from project [ %s ] finished" % project_id

    print "Importing issue links"
    mantis_issue_links = client.get_issue_links()
    yt_issue_links = []
    for link in mantis_issue_links:
        print "Processing issue link for source issue [ %s ]" % str(link.source)
        yt_issue_links.append(to_yt_link(link))
    print target.importLinks(yt_issue_links)
    print "Importing issue links finished"
Exemplo n.º 9
0
    def post(self, request, format=None):
        serializer = self.get_serializer_class()

        log.debug(type(request.DATA))
        if isinstance(request.DATA, QueryDict):
            data = request.DATA.dict()
            new_extra = OrderedDict()
            to_del = []
            for key, value in data.iteritems():
                if key.startswith('extra') and not key.endswith('extra'):
                    log.debug(key)
                    new_key = key.split('[')[1][:-1]
                    new_extra[new_key] = value
                    to_del.append(key)

            for element in to_del:
                del (data[element])

            user = request.user

            if not 'user' in new_extra:
                new_extra['user'] = u"%s (%s) - %s" % (user.username, user.get_full_name(), user.email)
            if not 'user-agent' in new_extra:
                new_extra['user-agent'] = request.META.get('HTTP_USER_AGENT', None)
            if not 'referer' in new_extra:
                new_extra['referer'] = request.META.get('HTTP_REFERER', None)
            if not 'ip' in new_extra:
                new_extra['ip'] = ip.get_ip(request)
            if not 'tenant' in new_extra:
                new_extra['tenant'] = request.META.get('HTTP_HOST', None)

            data['extra'] = new_extra
        elif isinstance(request.DATA, dict):
            data = request.DATA

            try:
                extra = data['extra']
            except KeyError:
                extra = {}

            new_extra = OrderedDict(extra)
            user = request.user

            if not 'user' in new_extra:
                new_extra['user'] = u"%s (%s) - %s" % (user.username, user.get_full_name(), user.email)
            if not 'user-agent' in new_extra:
                new_extra['user-agent'] = request.META.get('HTTP_USER_AGENT', None)
            if not 'referer' in new_extra:
                new_extra['referer'] = request.META.get('HTTP_REFERER', None)
            if not 'ip' in new_extra:
                new_extra['ip'] = ip.get_ip(request)
            if not 'tenant' in new_extra:
                new_extra['tenant'] = request.META.get('HTTP_HOST', None)

            data['extra'] = new_extra
        else:
            data = request.DATA

        log.debug(data)
        try:
            if len(settings.REDMINE_ADDRESS):
                serializer = serializer(data=data)

                if serializer.is_valid():
                    obj = serializer.save()
                    try:
                        ret = request_redmine('issues', data=obj.to_json(), method='POST')
                    except urllib2.HTTPError as ex:
                        log.debug("HTTPError")
                        return Response(data={'code': ex.code, 'message': ex.reason},
                                        status=status.HTTP_400_BAD_REQUEST)
                    except urllib2.URLError as ex:
                        log.debug("URLError")
                        return Response(data={'reason': ex.reason[1]},
                                        status=status.HTTP_400_BAD_REQUEST)
                    log.debug(ret)
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    log.debug("Serializer is invalid")
            else:
                log.debug("No redmine address")
        except AttributeError:
            log.debug("Redmine address not set.")

        try:
            if len(settings.YOUTRACK_ADDRESS):
                log.debug("YouTrack address is set")

                conn = YTConnection(settings.YOUTRACK_ADDRESS, settings.YOUTRACK_USER, settings.YOUTRACK_PASSWORD)
                serializer = YouTrackIssueSerializer(data=data)

                if serializer.is_valid():
                    obj = serializer.save()

                    if obj.extra:
                        context = {
                            'description': obj.description,
                            'extra': obj.extra,
                        }

                        template = get_template(obj.template_name)
                        context = Context(context)
                        description = template.render(context)
                    else:
                        description = obj.description

                    ret = conn.createIssue(obj.project_id, assignee=None, summary=obj.subject,
                                           description=description,
                                           priority=obj.priority, type=obj.type, subsystem=obj.subsystem)

                    log.debug(ret)

                    if obj.screenshot:
                        parsed_url = urlparse(ret[0]['location'])
                        issue_path = parsed_url.path
                        issue_id = issue_path.split("/")[-1]
                        # strip beggining data:image/png;base64,
                        data_str = obj.screenshot[22:]
                        data = a2b_base64(data_str)
                        with tempfile.TemporaryFile() as tmp_file:
                            tmp_file.write(data_str)
                            ret2 = conn.createAttachment(issue_id, 'screenshot.png', tmp_file)
                            ret_data = ret2.read()
                            log.debug(ret_data)

                    ret_dict = obj.to_dict()
                    try:
                        del(ret_dict['project_id'])
                    except KeyError:
                        pass

                    return Response(ret_dict, status=status.HTTP_201_CREATED)

        except AttributeError:
            log.debug("YouTrack address not set.")


        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)