Exemplo n.º 1
0
def main(argv):
   project_name = ''
   project_id = ''
   project_desc = ''
   project_usr = '******'
   project_pwd = 'Sarasa12'
   svn_cli = pysvn.Client()
   svn_working_path = '/tmp'
   youtrack_url = 'http://localhost:80'
   try:
      opts, args = getopt.getopt(argv,"hp:i:d:",["project_name=","project_id=", "project_desc="])
   except getopt.GetoptError:
      print 'test.py -p <project_name> -i <project_id> -d <project_desc>'
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         print 'test.py -p <project_name> -i <project_id> -d <project_desc>'
         sys.exit()
      elif opt in ("-p", "--project_name"):
         project_name = arg
      elif opt in ("-i", "--project_id"):
         project_id = arg
      elif opt in ("-d", "--project_desc"):
         project_desc = arg

   #yt = Connection('http://v-rot-mne-nogi.myjetbrains.com/youtrack', 'root', 'root') 
   #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888))
   yt = Connection(youtrack_url, project_usr, project_pwd)

   #def createProjectDetailed(self, projectId, name, description, projectLeadLogin, startingNumber=1)
   print yt.createProjectDetailed(project_id, project_name, project_desc, project_usr, 1)
def jira2youtrack(source_url, source_login, source_password, target_url, target_login, target_password, project_id):
    print("source_url      : " + source_url)
    print("source_login    : "******"source_password : "******"target_url      : " + target_url)
    print("target_login    : "******"target_password : "******"project_id      : " + project_id)

    source = JiraClient(source_url, source_login, source_password)
    target = Connection(target_url, target_login, target_password)
#
#    target.createProjectDetailed(project_id, project_id, "", target_login)
#
#    for i in range(0, 5500):
#        try:
#            jira_issues = source.get_issues(project_id, i * 10, (i + 1) * 10)
#            target.importIssues(project_id, project_id + " assignees",
#                [create_yt_issue_from_jira_issue(target, issue, project_id) for issue in
#                 jira_issues])
#            for issue in jira_issues:
#                process_labels(target, issue)
#                process_attachments(source, target, issue)
#        except BaseException, e:
#            print(str(e))

    for i in range(0, 5500):
        jira_issues = source.get_issues(project_id, i * 50, (i + 1) * 50)
        links = []
        for issue in jira_issues:
            process_links(target, issue, links)
        print(target.importLinks(links))
def jira2youtrack(source_url, source_login, source_password,
                  target_url, target_login, target_password,
                  projects, flags, field_mappings, value_mappings):
    print 'source_url   : ' + source_url
    print 'source_login : '******'target_url   : ' + target_url
    print 'target_login : '******'', target_login)
        except YouTrackException:
            pass

        while True:
            _end = start + chunk_size - 1
            if end and _end > end:
                _end = end
            if start > _end:
                break
            print 'Processing issues: %s [%d .. %d]' % (project_id, start, _end)
            try:
                jira_issues = source.get_issues(project_id, start, _end)
                start += chunk_size
                if not (jira_issues or end):
                    break
                # Filter out moved issues
                jira_issues = [issue for issue in jira_issues
                               if issue['key'].startswith('%s-' % project_id)]
                if flags & FI_ISSUES:
                    issues2import = []
                    for issue in jira_issues:
                        issues2import.append(
                            to_yt_issue(target, issue, project_id,
                                        field_mappings, value_mappings))
                    if not issues2import:
                        continue
                    target.importIssues(
                        project_id, '%s assignees' % project_id, issues2import)
            except YouTrackException, e:
                print e
                continue
            for issue in jira_issues:
                if flags & FI_LINKS:
                    process_links(target, issue, issue_links)
                if flags & FI_LABELS:
                    process_labels(target, issue)
                if flags & FI_ATTACHMENTS:
                    process_attachments(source, target, issue,
                                        flags & FI_REPLACE_ATTACHMENTS > 0)
                if flags & FI_WORK_LOG:
                    process_worklog(source, target, issue)
def agilezen2youtrack(source_url, source_token, target_url, target_login, target_password, project_names_to_import):
    source = Client(source_url, source_token)
    target = Connection(target_url, target_login, target_password)
    last_page = False
    current_page = 1
    try:
        target.createCustomFieldDetailed("State", "state[1]", False, True, True, {"attachBundlePolicy": "2"})
    except YouTrackException, e:
        print str(e)
Exemplo n.º 5
0
 def submit(self):
     try:
         connection = Connection(settings.YOUTRACK_URL, settings.YOUTRACK_LOGIN, settings.YOUTRACK_PASSWORD)
         response, content = connection.createIssue(self.project, assignee=None,
                                                    summary=u'Issue from feedback form',
                                                    description=self.cleaned_data['description'])
         print response
         issue_id = response['location'].split('/')[-1]
         connection.executeCommand(issue_id, 'Customer email ' + self.cleaned_data['email'])
         return True
     except YouTrackException:
         return False
def add_tags(tag_file,target_url, target_login, target_password):
    """
    Add tags from the tag file (run after known creation)
    :param tag_file:
    :return:
    """
    target = Connection(target_url, target_login, target_password)
    with open(tag_file) as tag_o_file:
        reader = csv.reader(tag_o_file)
        for row in reader:
            issue = row[0]
            for t in row[1:]:
                print "executing tag for %s" %(issue)
                target.executeCommand(issue, "tag %s" % (t))
 def process_commits(secret=None):
     if context_secret and secret != context_secret:
         abort(403)
     yt = Connection(yt_url, yt_login, yt_password)
     try:
         cmd_pattern = re.compile(
             r'#((?:%s)-\d+)(?:\s+(.+))?' % '|'.join(yt.getProjects().keys()),
             re.IGNORECASE | re.MULTILINE)
     except YouTrackException:
         app.logger.warning('Cannot get projects from YT')
         cmd_pattern = re.compile(r'#([A-z]+-\d+)(?:\s+(.+))?', re.MULTILINE)
     payload = json.loads(request.form.get('payload'))
     commits_url_template = get_commits_url_template(payload)
     for commit in payload['commits']:
         message = commit['message'].encode('utf-8')
         issue_refs = cmd_pattern.findall(message)
         if not issue_refs:
             continue
         commit_node = commit['node']
         commit_url = commits_url_template % commit['raw_node']
         timestamp = commit['utctimestamp']
         author = commit['author'].encode('utf-8')
         match = re.search(r'<(.+?)>', commit['raw_author'])
         if not match:
             app.logger.error("Cannot get author's email address.")
             abort(400)
         users = yt.getUsers(params={'q': match.group(1)})
         if not users:
             app.logger.error('Cannot find user with email ' + match.group(1))
             abort(400)
         if len(users) != 1:
             app.logger.error('Not unique email address ' + match.group(1))
             abort(400)
         comment = "Commit [%s %s] made by '''%s''' on ''%s''\n{quote}%s{quote}" \
                   % (commit_url, commit_node, author, timestamp, message)
         cmd_exec_result = True
         for issue_id, command in issue_refs:
             if command is None:
                 command = ''
             try:
                 app.logger.info("Adding commit %s to issue %s (command: %s)" %
                                 (commit_node, issue_id, command))
                 yt.executeCommand(issue_id, command, comment, run_as=users[0].login)
             except YouTrackException as e:
                 cmd_exec_result = False
                 app.logger.error('Failed to add commit %s to issue %s: %s' %
                                  (commit_node, issue_id, e.message))
         if not cmd_exec_result:
             abort(500)
     return 'success'
Exemplo n.º 8
0
 def submit(self):
     try:
         connection = Connection(settings.YOUTRACK_URL, settings.YOUTRACK_LOGIN, settings.YOUTRACK_PASSWORD)
         response, content = connection.createIssue(self.project, assignee=None,
                                                    summary=self.get_summary().encode('utf-8'),
                                                    description=self.cleaned_data['description'].encode('utf-8'))
         issue_id = response['location'].split('/')[-1]
         commands = ''
         if self.subsystem is not None:
             commands += ' Subsystem %s' % self.subsystem
         commands += ' Customer email ' + self.cleaned_data['email']
         connection.executeCommand(issue_id, commands)
         return True
     except YouTrackException:
         return False
def main():
    target_url, target_login, target_password, issue_source = sys.argv[1:5]
    target = Connection(target_url, target_login, target_password)
    if os.path.exists(issue_source): #"treat as a file of issues to delete"
        issues = open(issue_source).readlines()
    else:
        issues = []
        issues.append(issue_source)
    for issue in issues:
        if str(issue).strip() == "": continue
        print "deleting %s" % (issue,)
        try:
            result = target._req("DELETE", "/issue/%s" % (str(issue).strip(),))
            print result
        except Exception  as e:
            print e
def youtrack2youtrack(source_url, source_login, source_password, target_url, target_login, target_password,
                      project_ids, query = ''):
    if not len(project_ids):
        print "You should sign at least one project to import"
        return

    source = Connection(source_url, source_login, source_password)
    target = Connection(target_url, target_login,
        target_password) #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)

    print "Import issue link types"
    for ilt in source.getIssueLinkTypes():
        try:
            print target.createIssueLinkType(ilt)
        except youtrack.YouTrackException, e:
            print e.message
def jira2youtrack(source_url, source_login, source_password, target_url, target_login, target_password, project_id,
                  issues_count, skip_count):
    print("source_url      : " + source_url)
    print("source_login    : "******"target_url      : " + target_url)
    print("target_login    : "******"project_id      : " + project_id)
    print("issues_count    : ", issues_count)
    print("skip_count      : ", skip_count)

    first_chunk = skip_count / 10
    last_chunk = issues_count / 10
    if issues_count % 10:
        last_chunk += 1

    source = JiraClient(source_url, source_login, source_password)
    target = Connection(target_url, target_login, target_password)

    try:
        target.createProjectDetailed(project_id, project_id, "", target_login)
    except YouTrackException:
        pass

    for i in range(first_chunk, last_chunk):
        start = i * 10 + 1
        end = (i + 1) * 10 + 1
        if start <= skip_count: start = skip_count + 1
        if end > issues_count + 1: end = issues_count + 1
        try:
            jira_issues = source.get_issues(project_id, start, end)
            target.importIssues(project_id, project_id + " assignees",
                [create_yt_issue_from_jira_issue(target, issue, project_id) for issue in
                 jira_issues])
            for issue in jira_issues:
                try:
                    process_labels(target, issue)
                except YouTrackException, e:
                    print e
                try:
                    process_attachments(source, target, issue)
                except YouTrackException, e:
                    print e
                try:
                    process_worklog(source, target, issue)
                except YouTrackException, e:
                    print e
def googlecode2youtrack(project_name, source_login, source_password, target_url, target_login, target_password,
                        project_id):
    target = Connection(target_url, target_login, target_password)

    try:
        target.getProject(project_id)
    except YouTrackException:
        target.createProjectDetailed(project_id, project_name, "", target_login)

    for field_name, field_type in googleCode.FIELD_TYPES.items():
        create_and_attach_custom_field(target, project_id, field_name, field_type)

    start = 1
    max = 30

    while True:
        source = gdata.projecthosting.client.ProjectHostingClient()
        source.client_login(source_login, source_password, source="youtrack", service="code")
        print "Get issues from " + str(start) + " to " + str(start + max)
        query = gdata.projecthosting.client.Query(start_index=start, max_results=max)
        issues = source.get_issues(project_name, query=query).entry
        start += max

        if len(issues) <= 0:
            break

        target.importIssues(project_id, project_name + " assignees",
            [to_yt_issue(target, project_id, issue, source.get_comments(project_name, issue_id(issue)).entry) for issue
             in issues])
        for issue in issues:
            import_tags(target, project_id, issue)
            import_attachments(target, project_id, project_name, issue, target_login)
def zendesk2youtrack(source_url, source_login, source_password, target_url,
                     target_login, target_password, project_id):
    target = Connection(target_url, target_login, target_password)
    source = ZendeskClient(source_url, source_login, source_password)

    importer = ZendeskYouTrackImporter(
        source, target,
        ZendeskYouTrackImportConfig(youtrackutils.zendesk.NAMES, {}, {}))
    importer.do_import({project_id: project_id})
Exemplo n.º 14
0
def push_event_hook():
    push_event = request.json
    app.logger.debug(push_event)
    user_name = push_event['user_name']
    repo_name = push_event['repository']['name']
    repo_url = push_event['repository']['url']
    repo_homepage = push_event['repository']['homepage']
    refspec = push_event['ref']
    app.logger.debug('Received push event by %s in branch %s on repository %s',
                     user_name, refspec, repo_url)

    for commit in push_event['commits']:
        app.logger.debug('Processing commit %s by %s (%s) in %s', commit['id'],
                         commit['author']['name'], commit['author']['email'],
                         commit['url'])
        commit_time = dateutil.parser.parse(commit['timestamp'])
        issues = re.findall(app.config['REGEX'], commit['message'],
                            re.MULTILINE)
        if not issues:
            app.logger.debug(
                '''Didn't find any referenced issues in commit %s''',
                commit['id'])
        else:
            app.logger.debug('Found %d referenced issues in commit %s',
                             len(issues), commit['id'])
            yt = Connection(app.config['YOUTRACK_URL'],
                            app.config['YOUTRACK_USERNAME'],
                            app.config['YOUTRACK_PASSWORD'])

            user_login = get_user_login(yt, commit['author']['email'])
            if user_login is None:
                app.logger.warn(
                    "Couldn't find user with email address %s. Using default user.",
                    commit['author']['email'])
                default_user = yt.getUser(app.config['DEFAULT_USER'])
                user_login = default_user['login']

            for issue_id in issues:
                app.logger.debug('Processing reference to issue %s', issue_id)
                try:
                    yt.getIssue(issue_id)
                    comment_string = 'Commit [%(url)s %(id)s] on branch %(refspec)s in [%(repo_homepage)s %(repo_name)s] made by %(author)s on %(date)s\n{quote}%(message)s{quote}' % {
                        'url': commit['url'],
                        'id': commit['id'],
                        'author': commit['author']['name'],
                        'date': str(commit_time),
                        'message': commit['message'],
                        'repo_homepage': repo_homepage,
                        'repo_name': repo_name,
                        'refspec': refspec
                    }
                    app.logger.debug(comment_string)
                    yt.executeCommand(issueId=issue_id,
                                      command='comment',
                                      comment=comment_string.encode('utf-8'),
                                      run_as=user_login.encode('utf-8'))
                except YouTrackException:
                    app.logger.warn("Couldn't find issue %s", issue_id)
    return Response('Push event processed. Thanks!', mimetype='text/plain')
Exemplo n.º 15
0
    def __init__(self, server, username, password):
        self.logger = LoggerFactory.getLogger("com.xebialabs.yourtrack.Server")
        if server is None:
            sys.exit("No server provided.")
        if username is not None:
            youtrackUsername = username
        else:
            youtrackUsername = server['username']
        if password is not None:
            youtrackPassword = password
        else:
            youtrackPassword = server['password']

        if server['token'] is not None:
            # authentication request with permanent token
            self.youtrack = YouTrack(server['url'], token=server['token'])
        else:
            # authentication with username and password
            self.youtrack = YouTrack(server['url'], login=youtrackUsername, password=youtrackPassword)
Exemplo n.º 16
0
def host_elegido(bot, update, user_data):
    bot.sendChatAction(chat_id=update.callback_query.from_user.id,
                       action=ChatAction.TYPING)

    usuario = usuarios.getCollection().find_one(
        {'chat_id': update.callback_query.from_user.id})
    logger.info('Elegir host Opción {}'.format(update.callback_query.data))

    host = next(x for x in usuario['hosts']
                if x['host'] == update.callback_query.data)
    user_data['host'] = host

    try:
        connection = Connection(user_data['host']['host'],
                                user_data['host']['username'],
                                user_data['host']['pass'])
        connections[usuario['chat_id']] = connection
        proyectos = connection.getProjects()

    except YouTrackException as e:
        logger.error(e)
        del user_data['host']['pass']
        usuarios.getCollection().update(
            {'chat_id': update.callback_query.from_user.id},
            {'$pull': {
                'hosts': user_data['host']
            }})

        return CONFIRMAR

    keyboard = []
    for proyecto in proyectos.keys():
        keyboard.append(
            InlineKeyboardButton(proyectos[proyecto], callback_data=proyecto))

    # Acomodo el teclado
    keyboard = [keyboard[i:i + 3] for i in range(0, len(keyboard), 3)]
    reply_markup = InlineKeyboardMarkup(keyboard,
                                        resize_keyboard=True,
                                        one_time_keyboard=True)
    update.callback_query.edit_message_text(text="Bien! Elegí un proyecto",
                                            reply_markup=reply_markup)
    return PROYECTO
Exemplo n.º 17
0
def issue_elegido(bot, update, user_data):
    bot.sendChatAction(chat_id=update.callback_query.from_user.id,
                       action=ChatAction.TYPING)

    user_data['issue'] = update.callback_query.data
    logger.info('Elegir Issue {} Opción {}'.format(user_data['proyecto'],
                                                   user_data['issue']))

    connection = Connection(user_data['host']['host'],
                            user_data['host']['username'],
                            user_data['host']['pass'])
    try:
        the_types = connection.getProjectTimeTrackingWorkTypes(
            user_data['proyecto'])
    except YouTrackException as e:
        logger.error('Error de Youtrack {}'.format(e))
        reply_markup = InlineKeyboardMarkup([[
            InlineKeyboardButton("Elegir otro proyecto",
                                 callback_data=user_data['host']['host'])
        ]],
                                            resize_keyboard=True,
                                            one_time_keyboard=True)
        del user_data['proyecto']
        update.callback_query.edit_message_text(
            text="El proyecto no admite registro de horas, hablá con tu PM",
            reply_markup=reply_markup)
        return HOST

    user_data['types'] = the_types['types']
    keyboard = []
    for one_type in the_types['types']:
        keyboard.append([
            InlineKeyboardButton(one_type['name'],
                                 callback_data=one_type['id'])
        ])

    reply_markup = InlineKeyboardMarkup(keyboard,
                                        resize_keyboard=True,
                                        one_time_keyboard=True)

    update.callback_query.edit_message_text(text="Elegí el tipo",
                                            reply_markup=reply_markup)
    return RECIBIR
Exemplo n.º 18
0
class Fish:
    def __init__(self):
        self.conn = YT(YT_PATH, LOGIN, PASSWORD)

    def get_issue_data(self, project_id, request_filter, divider):
        issues = self.conn.get_issues(project_id, request_filter, AFTER, MAX)
        total_reward = 0
        for issue in issues:
            total_reward += int(issue.get('Estimation', 0))

        finished_issues = self.conn.get_issues(
            project_id, request_filter + FILTER_FINISHED, AFTER, MAX)
        total_cost = 0
        for issue in finished_issues:
            total_cost += int(issue.get(
                'Spent time', 0)) if int(issue.get('Spent time', 0)) < int(
                    issue.get('Estimation', 0)) else int(
                        issue.get('Estimation', 0))

        return list(map(lambda x: x // divider, [total_reward, total_cost]))
Exemplo n.º 19
0
def main(args):
    """ Add / Update / Remove items from the specified bundle

    """

    enum_dest = EnumValueDest
    cnx = Connection(args.youtrack, args.yusername, args.ypassword)
    enum_bundle = cnx.getEnumBundle(args.bundle)
    list_items = {}
    for i in enum_bundle.values:
        list_items[v.element_name] = v.description
    enum_src = EnumValueSrc(args)
    for name, desc_data in enum_src.get_src_values():
        desc = build_desc(args.desc, desc_data)
        if name in list_items.keys():
            if not (desc == list_items[name]):
                pass
            pass
        else:

            print("%s: %s" % (name, str(desc_data)))
def import_attachments_only(source_url, source_login, source_password,
                            target_url, target_login, target_password,
                            project_ids):
    if not project_ids:
        print 'No projects to import. Exit...'
        return
    start = 0
    max = 20
    source = Connection(source_url, source_login, source_password)
    target = Connection(target_url, target_login, target_password)
    user_importer = UserImporter(source, target, caching_users=True)
    for projectId in project_ids:
        while True:
            try:
                print 'Get issues from %d to %d' % (start, start + max)
                issues = source.getIssues(projectId, '', start, max)
                if len(issues) <= 0:
                    break
                for issue in issues:
                    print 'Process attachments for issue %s' % issue.id
                    attachments = issue.getAttachments()
                    users = set([])
                    for a in attachments:
                        author = a.getAuthor()
                        if author is not None:
                            users.add(author)
                    user_importer.importUsersRecursively(users)
                    for a in attachments:
                        print 'Transfer attachment of %s: %s' % (issue.id, a.name.encode('utf-8'))
                        try:
                            target.createAttachmentFromAttachment(issue.id, a)
                        except BaseException, e:
                            print 'Cannot import attachment [ %s ]' % a.name.encode('utf-8')
                            print repr(e)
            except Exception, e:
                print 'Cannot process issues from %d to %d' % (start, start + max)
                traceback.print_exc()
                raise e
            start += max
Exemplo n.º 21
0
def jira2youtrack(source_url, source_login, source_password,
                  target_url, target_login, target_password,
                  projects, flags, field_mappings, value_mappings):
    print 'source_url   : ' + source_url
    print 'source_login : '******'target_url   : ' + target_url
    print 'target_login : '******'', target_login)
        except YouTrackException:
            pass

        while True:
            _end = start + chunk_size - 1
            if end and _end > end:
                _end = end
            if start > _end:
                break
            print 'Processing issues: %s [%d .. %d]' % (project_id, start, _end)
            try:
                jira_issues = source.get_issues(project_id, start, _end)
                start += chunk_size
                if not (jira_issues or end):
                    break
                # Filter out moved issues
                jira_issues = [issue for issue in jira_issues
                               if issue['key'].startswith('%s-' % project_id)]
                if flags & FI_ISSUES:
                    issues2import = []
                    for issue in jira_issues:
                        issues2import.append(
                            to_yt_issue(target, issue, project_id,
                                        field_mappings, value_mappings))
                    if not issues2import:
                        continue
                    target.importIssues(
                        project_id, '%s assignees' % project_id, issues2import)
            except YouTrackException, e:
                print e
                continue
            for issue in jira_issues:
                if flags & FI_LINKS:
                    process_links(target, issue, issue_links)
                if flags & FI_LABELS:
                    process_labels(target, issue)
                if flags & FI_ATTACHMENTS:
                    process_attachments(source, target, issue,
                                        flags & FI_REPLACE_ATTACHMENTS > 0)
                if flags & FI_WORK_LOG:
                    process_worklog(source, target, issue)
 def process_commits(secret=None):
     if context_secret and secret != context_secret:
         abort(403)
     yt = Connection(yt_url, yt_login, yt_password)
     try:
         cmd_pattern = re.compile(
             r'#((?:%s)-\d+)(?:\s+(.+))?' %
             '|'.join(yt.getProjects().keys()),
             re.IGNORECASE | re.MULTILINE)
     except YouTrackException:
         app.logger.warning('Cannot get projects from YT')
         cmd_pattern = re.compile(r'#([A-z]+-\d+)(?:\s+(.+))?',
                                  re.MULTILINE)
     payload = json.loads(request.form.get('payload'))
     commits_url_template = get_commits_url_template(payload)
     for commit in payload['commits']:
         message = commit['message'].encode('utf-8')
         issue_refs = cmd_pattern.findall(message)
         if not issue_refs:
             continue
         commit_node = commit['node']
         commit_url = commits_url_template % commit['raw_node']
         timestamp = commit['utctimestamp']
         author = commit['author'].encode('utf-8')
         match = re.search(r'<(.+?)>', commit['raw_author'])
         if not match:
             app.logger.error("Cannot get author's email address.")
             abort(400)
         users = yt.getUsers(params={'q': match.group(1)})
         if not users:
             app.logger.error('Cannot find user with email ' +
                              match.group(1))
             abort(400)
         if len(users) != 1:
             app.logger.error('Not unique email address ' + match.group(1))
             abort(400)
         comment = "Commit [%s %s] made by '''%s''' on ''%s''\n{quote}%s{quote}" \
                   % (commit_url, commit_node, author, timestamp, message)
         cmd_exec_result = True
         for issue_id, command in issue_refs:
             if command is None:
                 command = ''
             try:
                 app.logger.info(
                     "Adding commit %s to issue %s (command: %s)" %
                     (commit_node, issue_id, command))
                 yt.executeCommand(issue_id,
                                   command,
                                   comment,
                                   run_as=users[0].login)
             except YouTrackException as e:
                 cmd_exec_result = False
                 app.logger.error(
                     'Failed to add commit %s to issue %s: %s' %
                     (commit_node, issue_id, e.message))
         if not cmd_exec_result:
             abort(500)
     return 'success'
Exemplo n.º 23
0
def csv2youtrack(source_file, target_url, target_login, target_password, comments_file=None, attachments_file=None):
    target = Connection(target_url, target_login, target_password)
    source = Client(source_file)
    source_comments = None
    if comments_file:
        source_comments = Client(comments_file)

    source_attachments = None
    if attachments_file:
        source_attachments = Client(attachments_file)

    config = CsvYouTrackImportConfig(csvClient.FIELD_NAMES, csvClient.FIELD_TYPES)
    importer = CsvYouTrackImporter(source, target, config, source_comments, source_attachments)
    importer.import_csv()
Exemplo n.º 24
0
def issue_actualizar_estado(bot, update, user_data):
    bot.sendChatAction(chat_id=update.callback_query.from_user.id,
                       action=ChatAction.TYPING)
    if update.callback_query.data == 'issue_estado_cerrar':
        estado = 'Fixed'
    else:
        estado = 'In Progress'

    logger.info('Actualizar estado issue {} {}'.format(user_data['issue'],
                                                       estado))
    try:
        connection = Connection(user_data['host']['host'],
                                user_data['host']['username'],
                                user_data['host']['pass'])
        command = 'State ' + estado
        connection.executeCommand(user_data['issue'], command)

        update.callback_query.edit_message_text("Gracias amego!")

    except Exception as e:
        logger.error(e)
        update.callback_query.edit_message_text("No eh!")
    return ConversationHandler.END
Exemplo n.º 25
0
def receive_hook():
    payload = request.json
    user_name = payload['user_name']
    repo_url = payload['repository']['url']
    app.logger.debug('Received payload for a push by %s on repository %s', user_name, repo_url)

    for commit in payload['commits']:
        app.logger.debug('Processing commit %s by %s (%s) in %s', commit['id'], commit['author']['name'], commit['author']['email'], commit['url'])
        commit_time = dateutil.parser.parse(commit['timestamp'])
        refs = re.findall(app.config['REGEX'], commit['message'], re.MULTILINE)
        if not refs:
            app.logger.info('''Didn't find any referenced issues in commit %s''', commit['id'])
        else:
            app.logger.info('Found %d referenced issues in commit %s', len(refs), commit['id'])

            yt = Connection(app.config['YOUTRACK_URL'], app.config['YOUTRACK_USERNAME'], app.config['YOUTRACK_PASSWORD'])

            user = app.config['DEFAULT_USER']
            users = yt.getUsers({ 'q': commit['author']['email'] })
            if not users:
                app.logger.warn('''Couldn't find user with email address %s. Using default user.''', commit['author']['email'])
            elif len(users) > 1:
                app.logger.warn('''Found more than one user with email address %s. Using default user.''', commit['author']['email'])
            else:
                user = users[0]['login']

            for ref in refs:
                app.logger.info('Processing reference to issue %s', ref)
                try:
                    issue = yt.getIssue(ref)
                    comment_string = 'Commit [%(url)s %(id)s] made by %(author)s on %(date)s\n{quote}%(message)s{quote}' % {'url': commit['url'], 'id': commit['id'], 'author': commit['author']['name'], 'date': str(commit_time), 'message': commit['message']}
                    app.logger.debug(comment_string)
                    yt.executeCommand(issueId=ref, command='comment', comment=comment_string, run_as=user)
                except YouTrackException:
                    app.logger.warn('''Couldn't find issue %s''', ref)
    return Response('Payload processed. Thanks!', mimetype='text/plain')
Exemplo n.º 26
0
def push_event_hook(room=None):
    push_event = request.json
    app.logger.debug(push_event)
    app.logger.debug("slack_room:%s" % room)

    # process mergerequest
    if 'object_kind' in push_event and push_event['object_kind'] == 'merge_request':
        obj = push_event['object_attributes']
        user = push_event['user']
        slack = Slacker(app.config['SLACK_TOKEN'])
        url = "%s/%s/%s/merge_requests/%d" % (app.config['GITLAB_HOME'], obj['target']['namespace'], obj['target']['name'], obj['iid'])
        print url
        event = "Pull Request(%s): %s - %s\n%s" % (obj['state'], url, obj['title'], obj['description'])
        slack.chat.post_message('#%s' % room, event, username=user['username'], icon_url=user['avatar_url'])
        return Response('Push event processed. Thanks!', mimetype='text/plain')

    user_name = push_event['user_name']
    repo_name = push_event['repository']['name']
    repo_url = push_event['repository']['url']
    repo_homepage = push_event['repository']['homepage']
    refspec = push_event['ref']
    app.logger.debug('Received push event by %s in branch %s on repository %s', user_name, refspec, repo_url)

    for commit in push_event['commits']:
        app.logger.debug('Processing commit %s by %s (%s) in %s', commit['id'], commit['author']['name'], commit['author']['email'], commit['url'])
        commit_time = dateutil.parser.parse(commit['timestamp'])
        issues = re.findall(app.config['REGEX'], commit['message'], re.MULTILINE)
        if not issues:
            app.logger.debug('''Didn't find any referenced issues in commit %s''', commit['id'])
        else:
            app.logger.debug('Found %d referenced issues in commit %s', len(issues), commit['id'])
            yt = Connection(app.config['YOUTRACK_URL'], app.config['YOUTRACK_USERNAME'], app.config['YOUTRACK_PASSWORD'])

            user_login = get_user_login(yt, commit['author']['email'])
            if user_login is None:
                app.logger.warn("Couldn't find user with email address %s. Using default user.", commit['author']['email'])
                default_user = yt.getUser(app.config['DEFAULT_USER'])
                user_login = default_user['login']

            for issue_id in issues:
                app.logger.debug('Processing reference to issue %s', issue_id)
                try:
                    yt.getIssue(issue_id)
                    comment_string = 'Commit [%(url)s %(id)s] on branch %(refspec)s in [%(repo_homepage)s %(repo_name)s] made by %(author)s on %(date)s\n{quote}%(message)s{quote}' % {'url': commit['url'], 'id': commit['id'], 'author': commit['author']['name'], 'date': str(commit_time), 'message': commit['message'], 'repo_homepage': repo_homepage, 'repo_name': repo_name, 'refspec': refspec}
                    app.logger.debug(comment_string)
                    yt.executeCommand(issueId=issue_id, command='comment', comment=comment_string.encode('utf-8'),
                                      run_as=user_login.encode('utf-8'))
                except YouTrackException:
                    app.logger.warn("Couldn't find issue %s", issue_id)
    return Response('Push event processed. Thanks!', mimetype='text/plain')
def doMove(source_url, source_login, source_password, target_url, target_login, target_password, source_issue_id, target_project_id) :
    print "source_url       : " + source_url
    print "source_login     : "******"source_password  : "******"target_url       : " + target_url
    print "target_login     : "******"target_password  : "******"source_id        : " + source_issue_id
    print "target_project   : " + target_project_id

    # connecting
    try :
        target = Connection(target_url, target_login, target_password)
        print "Connected to target url [%s]" % target_url
    except Exception, ex:
        print "Failed to connect to target url [%s] with login/password [%s/%s]" % (target_url, target_login, target_password)
        raise ex
def googlecode2youtrack(project_name, source_login, source_password,
                        target_url, target_login, target_password, project_id):
    target = Connection(target_url, target_login, target_password)

    try:
        target.getProject(project_id)
    except YouTrackException:
        target.createProjectDetailed(project_id, project_name, "",
                                     target_login)

    for field_name, field_type in googleCode.FIELD_TYPES.items():
        create_and_attach_custom_field(target, project_id, field_name,
                                       field_type)

    start = 1
    max = 30

    while True:
        source = gdata.projecthosting.client.ProjectHostingClient()
        source.client_login(source_login,
                            source_password,
                            source="youtrack",
                            service="code")
        print "Get issues from " + str(start) + " to " + str(start + max)
        query = gdata.projecthosting.client.Query(start_index=start,
                                                  max_results=max)
        issues = source.get_issues(project_name, query=query).entry
        start += max

        if len(issues) <= 0:
            break

        target.importIssues(project_id, project_name + " assignees", [
            to_yt_issue(
                target, project_id, issue,
                source.get_comments(project_name, issue_id(issue)).entry)
            for issue in issues
        ])
        for issue in issues:
            import_tags(target, project_id, issue)
            import_attachments(target, project_id, project_name, issue,
                               target_login)
def csv2youtrack(source_file, target_url, target_login, target_password):
    target = Connection(target_url, target_login, target_password)
    source = Client(source_file)

    import_custom_fields(source.get_header(), target)

    max = 100
    while True:
        issues = source.get_issue_list(max)
        if not len(issues):
            break
        projects = get_projects(issues)
        for p in projects:
            try:
                target.getProject(p)
            except YouTrackException:
                target.createProjectDetailed(p, p, "", target_login)

            target.importIssues(p, p + " Assignees", [to_yt_issue(issue, target)
                                                      for issue in issues if (get_project(issue) == p)])
Exemplo n.º 30
0
def jira2youtrack(source_url, source_login, source_password, target_url, target_login, target_password, project_id,
                  issues_count, skip_count):
    print("source_url      : " + source_url)
    print("source_login    : "******"target_url      : " + target_url)
    print("target_login    : "******"project_id      : " + project_id)
    print("issues_count    : ", issues_count)
    print("skip_count      : ", skip_count)

    first_chunk = skip_count / 10
    last_chunk = issues_count / 10
    if issues_count % 10:
        last_chunk += 1

    source = JiraClient(source_url, source_login, source_password)
    target = Connection(target_url, target_login, target_password)

    try:
        target.createProjectDetailed(project_id, project_id, "", target_login)
    except YouTrackException:
        pass

    for i in range(first_chunk, last_chunk):
        start = i * 10 + 1
        end = (i + 1) * 10 + 1
        if start <= skip_count: start = skip_count + 1
        if end > issues_count + 1: end = issues_count + 1
        try:
            jira_issues = source.get_issues(project_id, start, end)
            target.importIssues(project_id, project_id + " assignees",
                [create_yt_issue_from_jira_issue(target, issue, project_id) for issue in
                 jira_issues])
            for issue in jira_issues:
                try:
                    process_labels(target, issue)
                except YouTrackException, e:
                    print e
                try:
                    process_attachments(source, target, issue)
                except YouTrackException, e:
                    print e
                try:
                    process_worklog(source, target, issue)
                except YouTrackException, e:
                    print e
Exemplo n.º 31
0
def youtrack2youtrack(source_url,
                      source_login,
                      source_password,
                      target_url,
                      target_login,
                      target_password,
                      project_ids,
                      query=''):
    if not len(project_ids):
        print "You should sign at least one project to import"
        return

    source = Connection(source_url, source_login, source_password)
    target = Connection(
        target_url, target_login, target_password
    )  #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)

    print "Import issue link types"
    for ilt in source.getIssueLinkTypes():
        try:
            print target.createIssueLinkType(ilt)
        except youtrack.YouTrackException, e:
            print e.message
Exemplo n.º 32
0
class YtClient(object):

    def __init__(self, server, username, password):
        self.logger = LoggerFactory.getLogger("com.xebialabs.yourtrack.Server")
        if server is None:
            sys.exit("No server provided.")
        if username is not None:
            youtrackUsername = username
        else:
            youtrackUsername = server['username']
        if password is not None:
            youtrackPassword = password
        else:
            youtrackPassword = server['password']

        if server['token'] is not None:
            # authentication request with permanent token
            self.youtrack = YouTrack(server['url'], token=server['token'])
        else:
            # authentication with username and password
            self.youtrack = YouTrack(server['url'], login=youtrackUsername, password=youtrackPassword)

    def getIssue(self, issueId):
        return self.youtrack.getIssue(issueId)

    def getAllIssues(self, query, withFields):
        self.logger.debug("getAllIssues")
        self.logger.debug("Query = %s" % query)
        self.logger.debug("Fields = %s" % withFields)
        return self.youtrack.getAllIssues(filter=query, withFields=withFields)

    def updateIssuesByQuery(self, query, fieldsToUpdate, comment):
        command = ""
        for key in fieldsToUpdate:
            command += key + " " + fieldsToUpdate[key]
        foundIssues = self.youtrack.getAllIssues(filter=query, withFields=[])
        for issue in foundIssues:
            self.youtrack.executeCommand(issue['id'], command, comment)

    def getIssuesByQuery(self, query, fieldList=[]):
        self.logger.debug("getIssuesByQuery")
        return self.youtrack.getAllIssues(filter=query, withFields=[])
Exemplo n.º 33
0
def push_event_hook():
    push_event = request.json
    app.logger.debug(push_event)
    user_name = push_event['user_name']
    repo_name = push_event['repository']['name']
    repo_url = push_event['repository']['url']
    repo_homepage = push_event['repository']['homepage']
    refspec = push_event['ref']
    app.logger.debug('Received push event by %s in branch %s on repository %s', user_name, refspec, repo_url)

    for commit in push_event['commits']:
        app.logger.debug('Processing commit %s by %s (%s) in %s', commit['id'], commit['author']['name'], commit['author']['email'], commit['url'])
        commit_time = dateutil.parser.parse(commit['timestamp'])
        issues = re.findall(app.config['REGEX'], commit['message'], re.MULTILINE)
        if not issues:
            app.logger.debug('''Didn't find any referenced issues in commit %s''', commit['id'])
        else:
            app.logger.debug('Found %d referenced issues in commit %s', len(issues), commit['id'])
            yt = Connection(app.config['YOUTRACK_URL'], app.config['YOUTRACK_USERNAME'], app.config['YOUTRACK_PASSWORD'])

            default_user = yt.getUser(app.config['DEFAULT_USER'])
            user_login = default_user['login']

            users = yt.getUsers({ 'q': commit['author']['email'] })
            if not users:
                app.logger.warn('''Couldn't find user with email address %s. Using default user.''', commit['author']['email'])
            elif len(users) > 1:
                app.logger.warn('''Found more than one user with email address %s. Using default user.''', commit['author']['email'])
            else:
                user_login = users[0]['login']

            for issue_id in issues:
                app.logger.debug('Processing reference to issue %s', issue_id)
                try:
                    issue = yt.getIssue(issue_id)
                    comment_string = 'Commit [%(url)s %(id)s] on branch %(refspec)s in [%(repo_homepage)s %(repo_name)s] made by %(author)s on %(date)s\n{quote}%(message)s{quote}' % {'url': commit['url'], 'id': commit['id'], 'author': commit['author']['name'], 'date': str(commit_time), 'message': commit['message'], 'repo_homepage': repo_homepage, 'repo_name': repo_name, 'refspec': refspec}
                    app.logger.debug(comment_string)
                    yt.executeCommand(issueId=issue_id, command='comment', comment=comment_string.encode('utf-8'),
                                      run_as=user_login.encode('utf-8'))
                except YouTrackException:
                    app.logger.warn('''Couldn't find issue %s''', ref)
    return Response('Push event processed. Thanks!', mimetype='text/plain')
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'
Exemplo n.º 35
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()
            user = request.user

        elif isinstance(request.DATA, dict):
            data = request.DATA
            user = request.user

        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()
                    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)
                    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)
# coding=UTF-8

from youtrack.connection import Connection, httplib2
from xml.etree.ElementTree import fromstring
import random
import urllib
import httplib
import urllib2

import socks

httplib2.debuglevel=4
httplib.debuglevel=4

yt = Connection('http://teamsys.intellij.net', 'resttest', 'resttest')#, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888))
#yt = Connection('http://localhost:8080', 'root', 'root')

#yt = Connection('http://v-rot-mne-nogi.myjetbrains.com/youtrack', 'root', 'root') #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888))

print 'connected'

# create subsystem
#print yt.createSubsystemDetailed('ADM', 'ss' + str(random.random()), False, 'root')

# get issue
#i = yt.getIssue('SB-4950')

#print i

print yt.createIssue('SB', 'resttest', 'test', 'test', '1', 'Bug', 'Unknown', 'Open', '', '', '')
#print i.getAttachments()
Exemplo n.º 37
0
            if not (target_cf.type == source_cf.type):
                print "In your target and source YT instances you have field with name [ %s ]" % cf_name.encode(
                    'utf-8')
                print "They have different types. Source field type [ %s ]. Target field type [ %s ]" %\
                      (source_cf.type, target_cf.type)
                print "exiting..."
                exit()
        else:
            if hasattr(source_cf, "defaultBundle"):
                create_bundle_from_bundle(source, target,
                                          source_cf.defaultBundle,
                                          source_cf.type, user_importer)
            target.createCustomField(source_cf)

    for projectId in project_ids:
        source = Connection(source_url, source_login, source_password)
        target = Connection(
            target_url, target_login, target_password
        )  #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)
        #reset connections to avoid disconnections
        user_importer.resetConnections(source, target)
        link_importer.resetConnections(target)

        # copy project, subsystems, versions
        project = source.getProject(projectId)

        link_importer.addAvailableIssuesFrom(projectId)
        project_custom_fields = source.getProjectCustomFields(projectId)
        # create bundles and additional values
        for pcf_ref in project_custom_fields:
            pcf = source.getProjectCustomField(projectId, pcf_ref.name)
def import_attachments_only(source_url, source_login, source_password,
                            target_url, target_login, target_password,
                            project_ids, params=None):
    if not project_ids:
        print 'No projects to import. Exit...'
        return
    if params is None:
        params = {}
    start = 0
    max = 20
    source = Connection(source_url, source_login, source_password)
    target = Connection(target_url, target_login, target_password)
    user_importer = UserImporter(source, target, caching_users=params.get('enable_user_caching', True))
    for projectId in project_ids:
        while True:
            try:
                print 'Get issues from %d to %d' % (start, start + max)
                issues = source.getIssues(projectId, '', start, max)
                if len(issues) <= 0:
                    break
                for issue in issues:
                    print 'Process attachments for issue %s' % issue.id
                    existing_attachments = dict()
                    try:
                        for a in target.getAttachments(issue.id):
                            existing_attachments[a.name + '\n' + a.created] = a
                    except youtrack.YouTrackException, e:
                        if e.response.status == 404:
                            print "Skip importing attachments because issue %s doesn't exist" % issue.id
                            continue
                        raise e

                    attachments = []

                    users = set([])
                    for a in issue.getAttachments():
                        if a.name + '\n' + a.created in existing_attachments and not params.get('replace_attachments'):
                            print "Skip attachment '%s' (created: %s) because it's already exists" \
                                  % (a.name.encode('utf-8'), a.created)
                            continue
                        attachments.append(a)
                        author = a.getAuthor()
                        if author is not None:
                            users.add(author)
                    user_importer.importUsersRecursively(users)

                    for a in attachments:
                        print 'Transfer attachment of %s: %s' % (issue.id, a.name.encode('utf-8'))
                        try:
                            target.createAttachmentFromAttachment(issue.id, a)
                        except BaseException, e:
                            print 'Cannot import attachment [ %s ]' % a.name.encode('utf-8')
                            print repr(e)
                            continue
                        if params.get('replace_attachments'):
                            try:
                                old_attachment = existing_attachments.get(a.name + '\n' + a.created)
                                if old_attachment:
                                    print 'Deleting old attachment'
                                    target.deleteAttachment(issue.id, old_attachment.id)
                            except BaseException, e:
                                print "Cannot delete attachment '%s' from issue %s" % (a.name.encode('utf-8'), issue.id)
                                print e
Exemplo n.º 39
0
    sys.path.append(parentdir)

    config = ConfigParser.ConfigParser()
    config.read('config.ini')

    LOGIN = config.get('CREDENTIALS', 'domain') + '\\' + config.get('CREDENTIALS', 'login')
    PASSWRD = base64.b64decode(config.get('CREDENTIALS', 'password'))
    YOUTRACK_URL = config.get('YOUTRACK', 'url')
    REDMINE_URL = config.get('REDMINE', 'url')
    REDMINE_API_KEY = config.get('REDMINE', 'api key')
    REDMINE_PROJECT = config.get('REDMINE', 'project')
    YOUTRACK_PROJECT = config.get('YOUTRACK', 'project')
    SEARCH_QUERY = config.get('YOUTRACK', 'search query').replace('\n', '')

    try:
        youtrack = Connection(YOUTRACK_URL, LOGIN, PASSWRD)
    except YouTrackException as yt_exc:
        print yt_exc
        sys.exit(0)

    redmine = Redmine(REDMINE_URL, key=REDMINE_API_KEY, requests={'verify': False})

    print "Getting YouTrack issues..."
    issues_list = youtrack.getIssues('project: ' + YOUTRACK_PROJECT + ' ' + SEARCH_QUERY, 0, 5000)

    try:
        redmine_users = get_redmine_users()
        redmine_trackers = get_redmine_trackers()
        redmine_statuses = get_redmine_statuses()
        redmine_priorities = get_redmine_priorities()
        redmine_versions = get_redmine_project_versions()
Exemplo n.º 40
0
import random
import urllib
#import httplib
#import urllib2

#import socks
import csv
import re
import time
import datetime

httplib2.debuglevel = 4
#httplib.debuglevel=4
# connection
yt = Connection(
    'https://youtrack.ugent.be', 'root', 'PRCyt,17*'
)  #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'youtrack.ugent.be', 8080))

print('connected')

# get CMB issues
PRCissues = yt.get_all_issues("PRC-", 0, 500)
#datetime.datetime.now()-datetime.datetime.fromtimestamp(int(issue['created'])<datetime.timedelta(minutes=40)
#datetime.datetime.fromtimestamp(int(PRCissues[0]['created'])/1000).strftime('%Y-%m-%d %H:%M:%S.%f')
# issue IDs per project

# open PRC issue IDs
PRCissuesIDs = []
Currentissuesindexes = list()
counter = 0
for issue in PRCissues:
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()

    print "Creating custom fields definitions"
    create_yt_custom_field(target, u"priority")
    create_yt_custom_field(target, u"severity")
    create_yt_custom_field(target, u"category_id")
    create_yt_custom_field(target, u"version", "1")
    create_yt_custom_field(target, u"fixed_in_version", "1")
    create_yt_custom_field(target, u"build", "1")
    create_yt_custom_field(target, u"platform")
    create_yt_custom_field(target, u"os")
    create_yt_custom_field(target, u"os_build")
    create_yt_custom_field(target, u"due_date")
    create_yt_custom_field(target, u"Reproducibility")
    create_yt_custom_field(target, u"target_version", u'1')
    create_yt_custom_field(target, u"status")
    create_yt_custom_field(target, u"resolution")
    create_yt_custom_field(target, u'project_id', u'1')

    # 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')
        process_mantis_custom_field(target, cf_def)

    print "Creating custom fields definitions finished"

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

        print "Importing components to project [ %s ]" % project_id
        add_values_to_fields(target, project_id, u"category_id",
            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)
        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))

        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))

        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)

        for cf in custom_fields:
            if cf.field_id in cf_ids:
                attach_field_to_project(target, project_id, cf.name)

        print "Attaching custom fields to project [ %s ] finished" % project_id

        print "Importing issues to project [ %s ]" % project_id
        max_count = 100
        after = 0
        go_on = True
        while go_on:
            go_on = False
            mantis_issues = client.get_mantis_issues(project_id, after, max_count)
            after += max_count
            if len(mantis_issues):
                go_on = True
                target.importIssues(project_id, name + " Assignees",
                    [to_yt_issue(issue, project_id, target) for issue in mantis_issues])

                # import attachments
                for issue in mantis_issues:
                    issue_attachments = client.get_attachments(issue['id'])
                    issue_id = "%s-%s" % (project_id, issue['id'])
                    import_attachments(issue_attachments, issue_id, target)
                    issue_tags |= set(client.get_issue_tags_by_id(issue['id']))

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

    import_tags(client, target, project_ids, issue_tags)

    print "Importing issue links"
    go_on = True
    after = 0
    max_count = 200
    while go_on:
        go_on = False
        mantis_issue_links = client.get_issue_links(after, max_count)
        yt_issue_links = []
        for link in mantis_issue_links:
            go_on = True
            print "Processing issue link for source issue [ %s ]" % str(link.source)
            yt_issue_links.append(to_yt_link(link))
        after += max_count
        print target.importLinks(yt_issue_links)

    print "Importing issue links finished"
 def setUp(self):
     #self.con = Connection('http://teamsys.intellij.net', 'resttest', 'resttest')
     self.con = Connection("http://localhost:8081", "root", "root")
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 setUp(self):
     self.con = Connection('http://localhost:8081', 'root', 'root')
    print "target_url       : " + target_url
    print "target_login     : "******"target_password  : "******"source_id        : " + source_issue_id
    print "target_project   : " + target_project_id

    # connecting
    try :
        target = Connection(target_url, target_login, target_password)
        print "Connected to target url [%s]" % target_url
    except Exception, ex:
        print "Failed to connect to target url [%s] with login/password [%s/%s]" % (target_url, target_login, target_password)
        raise ex

    try :
        source = Connection(source_url, source_login, source_password)
        print "Connected to source url [%s]" % source_url
    except Exception, ex :
        print "Failed to connect to source url [%s] with login/password [%s/%s]" % (source_url, source_login, source_password)
        raise ex

    try :
        target.getProject(target_project_id)
    except Exception, ex:
        print "Can't connect to target project [%s]" % target_project_id
        raise ex

    #twin issues
    try :
        source_issue = source.getIssue(source_issue_id)
    except Exception, ex :
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()

    print "Creating custom fields definitions"
    create_yt_custom_field(target, u"priority")
    create_yt_custom_field(target, u"severity")
    create_yt_custom_field(target, u"category_id")
    create_yt_custom_field(target, u"version", "1")
    create_yt_custom_field(target, u"fixed_in_version", "1")
    create_yt_custom_field(target, u"build", "1")
    create_yt_custom_field(target, u"platform")
    create_yt_custom_field(target, u"os")
    create_yt_custom_field(target, u"os_build")
    create_yt_custom_field(target, u"due_date")
    create_yt_custom_field(target, u"Reproducibility")
    create_yt_custom_field(target, u"target_version", u'1')
    create_yt_custom_field(target, u"status")
    create_yt_custom_field(target, u"resolution")
    create_yt_custom_field(target, u'project_id', u'1')

    # 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')
        process_mantis_custom_field(target, cf_def)

    print "Creating custom fields definitions finished"

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

        print "Importing components to project [ %s ]" % project_id
        add_values_to_fields(
            target, project_id, u"category_id",
            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)
        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))

        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))

        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)

        for cf in custom_fields:
            if cf.field_id in cf_ids:
                attach_field_to_project(target, project_id, cf.name)

        print "Attaching custom fields to project [ %s ] finished" % project_id

        print "Importing issues to project [ %s ]" % project_id
        max_count = 100
        after = 0
        go_on = True
        while go_on:
            go_on = False
            mantis_issues = client.get_mantis_issues(project_id, after,
                                                     max_count)
            after += max_count
            if len(mantis_issues):
                go_on = True
                target.importIssues(project_id, name + " Assignees", [
                    to_yt_issue(issue, project_id, target)
                    for issue in mantis_issues
                ])

                # import attachments
                for issue in mantis_issues:
                    issue_attachments = client.get_attachments(issue['id'])
                    issue_id = "%s-%s" % (project_id, issue['id'])
                    import_attachments(issue_attachments, issue_id, target)
                    issue_tags |= set(client.get_issue_tags_by_id(issue['id']))

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

    import_tags(client, target, project_ids, issue_tags)

    print "Importing issue links"
    go_on = True
    after = 0
    max_count = 200
    while go_on:
        go_on = False
        mantis_issue_links = client.get_issue_links(after, max_count)
        yt_issue_links = []
        for link in mantis_issue_links:
            go_on = True
            print "Processing issue link for source issue [ %s ]" % str(
                link.source)
            yt_issue_links.append(to_yt_link(link))
        after += max_count
        print target.importLinks(yt_issue_links)

    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 import_attachments_only(source_url, source_login, source_password,
                            target_url, target_login, target_password,
                            project_ids, source_token=None, target_token=None, params=None):
    if not project_ids:
        print('No projects to import. Exit...')
        return
    if params is None:
        params = {}
    start = 0
    max = 20
    source = Connection(source_url, source_login, source_password) if (source_token is None) else Connection(source_url,
                                                                                                             token=source_token)
    target = Connection(target_url, target_login, target_password) if (target_token is None) else Connection(target_url,
                                                                                                             token=target_token)

    user_importer = UserImporter(source, target, caching_users=params.get('enable_user_caching', True))
    for projectId in project_ids:
        while True:
            try:
                print('Get issues from %d to %d' % (start, start + max))
                issues = source.getIssues(projectId, '', start, max)
                if len(issues) <= 0:
                    break
                for issue in issues:
                    print('Process attachments for issue %s' % issue.id)
                    existing_attachments = dict()
                    try:
                        for a in target.getAttachments(issue.id):
                            existing_attachments[a.name + '\n' + a.created] = a
                    except youtrack.YouTrackException as e:
                        if e.response.status == 404:
                            print("Skip importing attachments because issue %s doesn't exist" % issue.id)
                            continue
                        raise e

                    attachments = []

                    users = set([])
                    for a in issue.getAttachments():
                        if a.name + '\n' + a.created in existing_attachments and not params.get('replace_attachments'):
                            print("Skip attachment '%s' (created: %s) because it's already exists" %
                                  (utf8encode(a.name), utf8encode(a.created)))
                            continue
                        attachments.append(a)
                        author = a.getAuthor()
                        if author is not None:
                            users.add(author)
                    user_importer.importUsersRecursively(users)

                    for a in attachments:
                        print('Transfer attachment of %s: %s' % (utf8encode(issue.id), utf8encode(a.name)))
                        try:
                            target.createAttachmentFromAttachment(issue.id, a)
                        except BaseException as e:
                            print('Cannot import attachment [ %s ]' % utf8encode(a.name))
                            print(repr(e))
                            continue
                        if params.get('replace_attachments'):
                            try:
                                old_attachment = existing_attachments.get(a.name + '\n' + a.created)
                                if old_attachment:
                                    print('Deleting old attachment')
                                    target.deleteAttachment(issue.id, old_attachment.id)
                            except BaseException as e:
                                print("Cannot delete attachment '%s' from issue %s" % (
                                utf8encode(a.name), utf8encode(issue.id)))
                                print(e)
            except Exception as e:
                print('Cannot process issues from %d to %d' % (start, start + max))
                traceback.print_exc()
                raise e
            start += max
            target_cf = target.getCustomField(cf_name)
            if not(target_cf.type == source_cf.type):
                print "In your target and source YT instances you have field with name [ %s ]" % cf_name.encode('utf-8')
                print "They have different types. Source field type [ %s ]. Target field type [ %s ]" %\
                      (source_cf.type, target_cf.type)
                print "exiting..."
                exit()
        else:
            if hasattr(source_cf, "defaultBundle"):
                create_bundle_from_bundle(source, target, source_cf.defaultBundle, source_cf.type, user_importer)
            target.createCustomField(source_cf)

    failed_commands = []

    for projectId in project_ids:
        source = Connection(source_url, source_login, source_password)
        target = Connection(target_url, target_login,
            target_password) #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)
        #reset connections to avoid disconnections
        user_importer.resetConnections(source, target)
        link_importer.resetConnections(target)

        # copy project, subsystems, versions
        project = source.getProject(projectId)

        link_importer.addAvailableIssuesFrom(projectId)
        project_custom_fields = source.getProjectCustomFields(projectId)
        # create bundles and additional values
        for pcf_ref in project_custom_fields:
            pcf = source.getProjectCustomField(projectId, pcf_ref.name)
            if hasattr(pcf, "bundle"):
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")
Exemplo n.º 51
0
from youtrack.connection import Connection

youtrack_url = 'http://youtrack.dev.kbinform.ru/'
youtrack_login = '******'
youtrack_password = '******'
youtrack = Connection(youtrack_url, youtrack_login, youtrack_password)

project_list = [
    'ezmp_product',
]

for _ in range(30):
    for p in project_list:
        issues = youtrack.get_issues(p, '', '', '')
        for i in issues:
            youtrack.delete_issue(i._data['id'])
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"
Exemplo n.º 53
0
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'
                    issue[field_name] = get_value_presentation(field_type, value)

    # process custom fields
    for custom_field in jira_issue.customFieldValues:
        field_name = get_yt_field_name(custom_field.customFieldId)
        field_value = custom_field.values
        field_type = get_yt_field_type(field_name)
        if (field_name is not None) and (field_type is not None):
            pass

    return issue



source = JiraSoapClient("jira url", "jira login", "jira pass")
target = Connection('http://localhost:8081', 'root', 'root')

project_ids = {'ACS'        : 100,
               'ASL'        : 100,
               'BLZ'        : 100,
               'CGM'        : 100,
               'DURANGO'    : 100,
               'FCM'        : 100,
               'FLEXDMV'    : 100,
               'FLEXDOCS'   : 100,
               'FLEXENT'    : 100,
               'SDK'        : 100,
               'FLEXPMD'    : 100,
               'FXU'        : 100
}
def youtrack2youtrack(source_url, source_login, source_password, target_url, target_login, target_password,
                      project_ids, query='', source_token=None, target_token=None, params=None):
    if not len(project_ids):
        print("You should sign at least one project to import")
        return
    if params is None:
        params = {}

    source = Connection(source_url, source_login, source_password) if (source_token is None) else Connection(source_url,
                                                                                                             token=source_token)
    target = Connection(target_url, target_login, target_password) if (target_token is None) else Connection(target_url,
                                                                                                             token=target_token)
    # , proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)

    print("Import issue link types")
    for ilt in source.getIssueLinkTypes():
        try:
            print(target.createIssueLinkType(ilt))
        except youtrack.YouTrackException as e:
            print(e.message)

    user_importer = UserImporter(source, target, caching_users=params.get('enable_user_caching', True))
    link_importer = LinkImporter(target)

    # create all projects with minimum info and project lead set
    created_projects = []
    for project_id in project_ids:
        created = create_project_stub(source, target, project_id, user_importer)
        created_projects.append(created)

    # save created project ids to create correct group roles afterwards
    user_importer.addCreatedProjects([project.id for project in created_projects])
    # import project leads with group they are included and roles assigned to these groups
    user_importer.importUsersRecursively([target.getUser(project.lead) for project in created_projects])
    # afterwards in a script any user import imply recursive import

    cf_names_to_import = set([])  # names of cf prototypes that should be imported
    for project_id in project_ids:
        cf_names_to_import.update([pcf.name.capitalize() for pcf in source.getProjectCustomFields(project_id)])

    target_cf_names = [pcf.name.capitalize() for pcf in target.getCustomFields()]

    period_cf_names = []

    for cf_name in cf_names_to_import:
        source_cf = source.getCustomField(cf_name)
        if source_cf.type.lower() == 'period':
            period_cf_names.append(source_cf.name.lower())

        print("Processing custom field '%s'" % utf8encode(cf_name))
        if cf_name in target_cf_names:
            target_cf = target.getCustomField(cf_name)
            if not (target_cf.type == source_cf.type):
                print("In your target and source YT instances you have field with name [ %s ]" % utf8encode(cf_name))
                print("They have different types. Source field type [ %s ]. Target field type [ %s ]" %
                      (source_cf.type, target_cf.type))
                print("exiting...")
                exit()
        else:
            if hasattr(source_cf, "defaultBundle"):
                create_bundle_from_bundle(source, target, source_cf.defaultBundle, source_cf.type, user_importer)
            target.createCustomField(source_cf)

    failed_commands = []

    for projectId in project_ids:
        source = Connection(source_url, source_login, source_password) if (source_token is None) else Connection(
            source_url, token=source_token)
        target = Connection(target_url, target_login, target_password) if (target_token is None) else Connection(
            target_url, token=target_token)
        # , proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)
        # reset connections to avoid disconnections
        user_importer.resetConnections(source, target)
        link_importer.resetConnections(target)

        # copy project, subsystems, versions
        project = source.getProject(projectId)

        link_importer.addAvailableIssuesFrom(projectId)
        project_custom_fields = source.getProjectCustomFields(projectId)
        # create bundles and additional values
        for pcf_ref in project_custom_fields:
            pcf = source.getProjectCustomField(projectId, pcf_ref.name)
            if hasattr(pcf, "bundle"):
                try:
                    create_bundle_from_bundle(source, target, pcf.bundle, source.getCustomField(pcf.name).type,
                                              user_importer)
                except youtrack.YouTrackException as e:
                    if e.response.status != 409:
                        raise e
                    else:
                        print(e)

        target_project_fields = [pcf.name.lower() for pcf in target.getProjectCustomFields(projectId)]
        for field in project_custom_fields:
            if field.name.lower() in target_project_fields:
                if hasattr(field, 'bundle'):
                    if field.bundle != target.getProjectCustomField(projectId, field.name).bundle:
                        target.deleteProjectCustomField(projectId, field.name)
                        create_project_custom_field(target, field, projectId)
            else:
                try:
                    create_project_custom_field(target, field, projectId)
                except youtrack.YouTrackException as e:
                    if e.response.status != 409:
                        raise e
                    else:
                        print(e)

        # copy issues
        start = 0
        max = 20

        sync_workitems = enable_time_tracking(source, target, projectId)
        tt_settings = target.getProjectTimeTrackingSettings(projectId)

        print("Import issues")
        last_created_issue_number = 0

        while True:
            try:
                print("Get issues from " + str(start) + " to " + str(start + max))
                issues = source.getIssues(projectId, query, start, max)

                if len(issues) <= 0:
                    break

                if convert_period_values and period_cf_names:
                    for issue in issues:
                        for pname in period_cf_names:
                            for fname in issue.__dict__:
                                if fname.lower() != pname:
                                    continue
                                issue[fname] = period_to_minutes(issue[fname])

                users = set([])

                for issue in issues:
                    print("Collect users for issue [%s]" % issue.id)

                    users.add(issue.getReporter())
                    if issue.hasAssignee():
                        if isinstance(issue.Assignee, (list, tuple)):
                            users.update(issue.getAssignee())
                        else:
                            users.add(issue.getAssignee())
                    # TODO: http://youtrack.jetbrains.net/issue/JT-6100
                    users.add(issue.getUpdater())
                    if issue.hasVoters():
                        users.update(issue.getVoters())
                    for comment in issue.getComments():
                        users.add(comment.getAuthor())

                    print("Collect links for issue [%s]" % issue.id)
                    link_importer.collectLinks(issue.getLinks(True))
                    # links.extend(issue.getLinks(True))

                    # fix problem with comment.text
                    for comment in issue.getComments():
                        if not hasattr(comment, "text") or (len(comment.text.strip()) == 0):
                            setattr(comment, 'text', 'no text')

                user_importer.importUsersRecursively(users)

                print("Create issues [" + str(len(issues)) + "]")
                if params.get('create_new_issues'):
                    create_issues(target, issues, last_created_issue_number)
                else:
                    print(target.importIssues(projectId, project.name + ' Assignees', issues))
                link_importer.addAvailableIssues(issues)

                for issue in issues:
                    try:
                        target_issue = target.getIssue(issue.id)
                    except youtrack.YouTrackException as e:
                        print("Cannot get target issue")
                        print(e)
                        continue

                    if params.get('sync_tags') and issue.tags:
                        try:
                            for tag in issue.tags:
                                tag = re.sub(r'[,&<>]', '_', tag)
                                try:
                                    target.executeCommand(issue.id, 'tag ' + tag, disable_notifications=True)
                                except youtrack.YouTrackException:
                                    tag = re.sub(r'[\s-]', '_', tag)
                                    target.executeCommand(issue.id, 'tag ' + tag, disable_notifications=True)
                        except youtrack.YouTrackException as e:
                            print("Cannot sync tags for issue " + issue.id)
                            print(e)

                    if params.get('add_new_comments'):
                        target_comments = dict()
                        max_id = 0
                        for c in target_issue.getComments():
                            target_comments[c.created] = c
                            if max_id < c.created:
                                max_id = c.created
                        for c in issue.getComments():
                            if c.created > max_id or c.created not in target_comments:
                                group = None
                                if hasattr(c, 'permittedGroup'):
                                    group = c.permittedGroup
                                try:
                                    target.executeCommand(issue.id, 'comment', c.text, group, c.author,
                                                          disable_notifications=True)
                                except youtrack.YouTrackException as e:
                                    print('Cannot add comment to issue')
                                    print(e)

                    if params.get('sync_custom_fields'):
                        skip_fields = []
                        if tt_settings and tt_settings.Enabled and tt_settings.TimeSpentField:
                            skip_fields.append(tt_settings.TimeSpentField)
                        skip_fields = [name.lower() for name in skip_fields]
                        for pcf in [pcf for pcf in project_custom_fields if pcf.name.lower() not in skip_fields]:
                            target_cf_value = None
                            if pcf.name in target_issue:
                                target_cf_value = target_issue[pcf.name]
                                if isinstance(target_cf_value, (list, tuple)):
                                    target_cf_value = set(target_cf_value)
                                elif target_cf_value == target.getProjectCustomField(projectId, pcf.name).emptyText:
                                    target_cf_value = None
                            source_cf_value = None
                            if pcf.name in issue:
                                source_cf_value = issue[pcf.name]
                                if isinstance(source_cf_value, (list, tuple)):
                                    source_cf_value = set(source_cf_value)
                                elif source_cf_value == source.getProjectCustomField(projectId, pcf.name).emptyText:
                                    source_cf_value = None
                            if source_cf_value == target_cf_value:
                                continue
                            if isinstance(source_cf_value, set) or isinstance(target_cf_value, set):
                                if source_cf_value is None:
                                    source_cf_value = set([])
                                elif not isinstance(source_cf_value, set):
                                    source_cf_value = set([source_cf_value])
                                if target_cf_value is None:
                                    target_cf_value = set([])
                                elif not isinstance(target_cf_value, set):
                                    target_cf_value = set([target_cf_value])
                                for v in target_cf_value:
                                    if v not in source_cf_value:
                                        target.executeCommand(issue.id, 'remove %s %s' % (pcf.name, v),
                                                              disable_notifications=True)
                                for v in source_cf_value:
                                    if v not in target_cf_value:
                                        target.executeCommand(issue.id, 'add %s %s' % (pcf.name, v),
                                                              disable_notifications=True)
                            else:
                                if source_cf_value is None:
                                    source_cf_value = target.getProjectCustomField(projectId, pcf.name).emptyText
                                if pcf.type.lower() == 'date':
                                    m = re.match(r'(\d{10})(?:\d{3})?', str(source_cf_value))
                                    if m:
                                        source_cf_value = datetime.datetime.fromtimestamp(
                                            int(m.group(1))).strftime('%Y-%m-%d')
                                elif pcf.type.lower() == 'period':
                                    source_cf_value = '%sm' % source_cf_value
                                command = '%s %s' % (pcf.name, source_cf_value)
                                try:
                                    target.executeCommand(issue.id, command, disable_notifications=True)
                                except youtrack.YouTrackException as e:
                                    if e.response.status == 412 and e.response.reason.find('Precondition Failed') > -1:
                                        print('WARN: Some workflow blocks following command: %s' % command)
                                        failed_commands.append((issue.id, command))

                    if sync_workitems:
                        workitems = source.getWorkItems(issue.id)
                        if workitems:
                            existing_workitems = dict()
                            target_workitems = target.getWorkItems(issue.id)
                            if target_workitems:
                                for w in target_workitems:
                                    _id = '%s\n%s\n%s' % (w.date, w.authorLogin, w.duration)
                                    if hasattr(w, 'description'):
                                        _id += '\n%s' % w.description
                                    existing_workitems[_id] = w
                            new_workitems = []
                            for w in workitems:
                                _id = '%s\n%s\n%s' % (w.date, w.authorLogin, w.duration)
                                if hasattr(w, 'description'):
                                    _id += '\n%s' % w.description
                                if _id not in existing_workitems:
                                    new_workitems.append(w)
                            if new_workitems:
                                print("Process workitems for issue [ " + issue.id + "]")
                                try:
                                    user_importer.importUsersRecursively(
                                        [source.getUser(w.authorLogin)
                                         for w in new_workitems])
                                    target.importWorkItems(issue.id, new_workitems)
                                except youtrack.YouTrackException as e:
                                    if e.response.status == 404:
                                        print("WARN: Target YouTrack doesn't support workitems importing.")
                                        print("WARN: Workitems won't be imported.")
                                        sync_workitems = False
                                    else:
                                        print("ERROR: Skipping workitems because of error:" + str(e))

                    print("Process attachments for issue [%s]" % issue.id)
                    existing_attachments = dict()
                    try:
                        for a in target.getAttachments(issue.id):
                            existing_attachments[a.name + '\n' + a.created] = a
                    except youtrack.YouTrackException as e:
                        if e.response.status == 404:
                            print("Skip importing attachments because issue %s doesn't exist" % issue.id)
                            continue
                        raise e

                    attachments = []

                    users = set([])
                    for a in issue.getAttachments():
                        if a.name + '\n' + a.created in existing_attachments and not params.get('replace_attachments'):
                            a.name = utf8encode(a.name)
                            try:
                                print("Skip attachment '%s' (created: %s) because it's already exists"
                                      % (utf8encode(a.name), utf8encode(a.created)))
                            except Exception:
                                pass
                            continue
                        attachments.append(a)
                        author = a.getAuthor()
                        if author is not None:
                            users.add(author)
                    user_importer.importUsersRecursively(users)

                    for a in attachments:
                        print("Transfer attachment of " + utf8encode(issue.id) + ": " + utf8encode(a.name))
                        # TODO: add authorLogin to workaround http://youtrack.jetbrains.net/issue/JT-6082
                        # a.authorLogin = target_login
                        try:
                            target.createAttachmentFromAttachment(issue.id, a)
                        except BaseException as e:
                            print("Cant import attachment [ %s ]" % utf8encode(a.name))
                            print(repr(e))
                            continue
                        if params.get('replace_attachments'):
                            try:
                                old_attachment = existing_attachments.get(a.name + '\n' + a.created)
                                if old_attachment:
                                    print('Deleting old attachment')
                                    target.deleteAttachment(issue.id, old_attachment.id)
                            except BaseException as e:
                                print("Cannot delete attachment '%s' from issue %s" % (
                                utf8encode(a.name), utf8encode(issue.id)))
                                print(e)

            except Exception as e:
                print('Cant process issues from ' + str(start) + ' to ' + str(start + max))
                traceback.print_exc()
                raise e

            start += max

    print("Import issue links")
    link_importer.importCollectedLinks()

    print("Trying to execute failed commands once again")
    for issue_id, command in failed_commands:
        try:
            print('Executing command on issue %s: %s' % (issue_id, command))
            target.executeCommand(issue_id, command, disable_notifications=True)
        except youtrack.YouTrackException as e:
            print('Failed to execute command for issue #%s: %s' % (issue_id, command))
            print(e)
        if cf_name in target_cf_names:
            target_cf = target.getCustomField(cf_name)
            if not(target_cf.type == source_cf.type):
                print "In your target and source YT instances you have field with name [ %s ]" % cf_name.encode('utf-8')
                print "They have different types. Source field type [ %s ]. Target field type [ %s ]" %\
                      (source_cf.type, target_cf.type)
                print "exiting..."
                exit()
        else:
            if hasattr(source_cf, "defaultBundle"):
                create_bundle_from_bundle(source, target, source_cf.defaultBundle, source_cf.type, user_importer)
            target.createCustomField(source_cf)

    for projectId in project_ids:
        source = Connection(source_url, source_login, source_password)
        target = Connection(target_url, target_login,
            target_password) #, proxy_info = httplib2.ProxyInfo(socks.PROXY_TYPE_HTTP, 'localhost', 8888)
        #reset connections to avoid disconnections
        user_importer.resetConnections(source, target)
        link_importer.resetConnections(target)

        # copy project, subsystems, versions
        project = source.getProject(projectId)

        link_importer.addAvailableIssuesFrom(projectId)
        project_custom_fields = source.getProjectCustomFields(projectId)
        # create bundles and additional values
        for pcf_ref in project_custom_fields:
            pcf = source.getProjectCustomField(projectId, pcf_ref.name)
            if hasattr(pcf, "bundle"):
Exemplo n.º 57
0
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 setUp(self):
     #self.con = Connection('http://teamsys.intellij.net', 'resttest', 'resttest')
     self.con = Connection("http://localhost:8081", "root", "root")
from youtrack.connection import Connection

target = Connection("some url", "root", "root")
for user in target.getUsers():
    yt_user = target.getUser(user.login)
    try:
        if (str(yt_user.email).find("jetbrains") > 0):
            print yt_user.email
        elif (str(yt_user.email).find("intellij") > 0):
            print yt_user.email
    except:
        print "exception"
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"