def getComments(self, id): response, content = self._req('GET', '/issue/' + id + '/comment') xml = minidom.parseString(content) return [ youtrack.Comment(e, self) for e in xml.documentElement.childNodes if e.nodeType == Node.ELEMENT_NODE ]
def to_youtrack_comment(project_ID, trac_comment): """ This method converts trac comment to youtrack comment Args: trac_comment: Trac comment to convert Returns: YT comment, which has same author as initial comment. If initial comment author was anonymous, comment is added from behalf of guest user. YT comment gets same creation date as trac comment. """ comment = youtrack.Comment() if trac_comment.author == "anonymous": comment.author = "guest" else: comment.author = trac_comment.author comment.text = trac_comment.content # translate Trac wiki ticket link format to YouTrack id format comment.text = re.sub(r'\#(\d+)', project_ID+'-'+r'\1', comment.text) # translate trac preformatted blocks, {{{ and }}} # opening tag done as two lines for python 2.7 that doesn't really support optional capture group comment.text = re.sub(r'{{{\s*#!(\w+)', r'```\1', comment.text) comment.text = re.sub(r'{{{', r'```', comment.text) comment.text = re.sub(r'}}}', r'```', comment.text) comment.created = str(trac_comment.time) return comment
def _add_journals(self, issue, journals): if not journals: return for rec in journals: if rec.notes is not None and rec.notes != '': comment = youtrack.Comment() comment.text = rec.notes comment.author = self._create_user(rec.user).login comment.created = str(to_unixtime(rec.created_on)) issue['comments'].append(comment)
def _add_journals(self, issue, journals): if not journals: return for rec in journals: if hasattr(rec, 'notes') and rec.notes is not None and rec.notes != '': comment = youtrack.Comment() if self._params.get('use_markdown'): comment.markdown = "true" comment.text = rec.notes comment.author = self._create_user(rec.user).login comment.created = str(to_unixtime(rec.created_on)) issue['comments'].append(comment)
def build_comment(self, comment): yt_comment = youtrack.Comment() yt_comment.text = comment['body'] comment_author_name = "guest" if 'author' in comment: comment_author = comment['author'] create_user(self.target, comment_author) comment_author_name = comment_author['name'] yt_comment.author = comment_author_name.replace(' ', '_') yt_comment.created = to_unix_date(comment['created']) yt_comment.updated = to_unix_date(comment['updated']) return yt_comment
def to_youtrack_comment(trac_comment): """ This method converts trac comment to youtrack comment Args: trac_comment: Trac comment to convert Returns: YT comment, which has same author as initial comment. If initial comment author was anonymous, comment is added from behalf of guest user. YT comment gets same creation date as trac comment. """ comment = youtrack.Comment() if trac_comment.author == "anonymous": comment.author = "guest" else: comment.author = trac_comment.author comment.text = trac_comment.content comment.created = str(trac_comment.time) return comment
def migrate_tasks_to_issues(a_conn, yt_conn, a_work, yt_proj, yt_login): """ Asana Tasks can be in multiple Projects, yet YouTrack Issues can be in only one Subsystem. Thus, we will use the 1st Project in the Asana list to use as the YouTrack Subsystem """ # We must filter tasks by project, tag, or assignee + workspace, so we'll use the last option and migrate tasks # one user at a time numberInProject = 0 for a_id, a_user in _a_users.iteritems(): a_tasks = [ i for i in a_conn.tasks.find_all(params={ 'workspace': a_work['id'], 'assignee': a_id }) ] if len(a_tasks) == 0: continue msg = "Fetching details for {} Asana Tasks assigned to {} in Workspace {}" print msg.format(len(a_tasks), a_user['email'], a_work['name']) a_tasks = get_task_details(a_conn, a_tasks) # print "Asana task details: {}".format(a_tasks) # Add to map merge_into_map(a_tasks, 'name', _task_map) global _a_tasks for i in a_tasks: _a_tasks[i['id']] = i.copy() print "Fetching existing YouTrack tasks" # Checking existing issues in YouTrack yt_filter = "Assignee: {}".format( _user_map[a_user['email']]['yt'].login) yt_issues = [ i for i in yt_conn.getIssues(yt_proj.id, yt_filter, 0, 1000) ] # yt_issues = [yt_conn.getIssue(i.id) for i in yt_conn.getIssues(yt_proj.id, yt_filter, 0, 1000)] merge_into_map(yt_issues, 'summary', _task_map) merge_into_map(yt_issues, 'AsanaID', _asana_id_map) global _yt_issues for i in yt_issues: _yt_issues[i.numberInProject] = i numberInProject = max(numberInProject, int(i.numberInProject)) numberInProject += 1 # print "Task details: {}".format(yt_issues) # Now add Issues from all Tasks new_issues = [] print 'Fetching Asana stories for each task...' for a in a_tasks: # Skip adding tasks where task name matches issue summary if 'yt' in _task_map[a['name']] or str(a['id']) in _asana_id_map: print "Skipping task import : {}".format( a['name'].encode('utf-8')) continue # Look at Asana Story to find out who the YouTrack Issue reporterName should be a_stories = get_task_stories(a_conn, a) a_stories = get_story_details(a_conn, a_stories) # Save for later _a_tasks[a['id']]['stories'] = a_stories # Establish our comments and who created this Task comments = [] reporter_name = None for s in a_stories: if s['type'] == 'comment': comment = yt.Comment() comment.author = a_id_to_yt_login(s['created_by']['id']) # _user_map[_a_users[s['created_by']['id']]['email']]['yt'].login comment.text = s['text'] comment.created = a_to_yt_time(s['created_at']) comments.append(comment) elif s['type'] == 'system' and reporter_name is None and s[ 'text'][:9] in ['assigned ', 'added to ', 'added sub']: # TODO if subtask, link to other YT Issue reporter_name = a_id_to_yt_login(s['created_by']['id']) # Build a list for bulk importing later """[{'numberInProject':'1', 'summary':'some problem', 'description':'some description', 'priority':'1', 'fixedVersion':['1.0', '2.0'], 'comment':[{'author':'yamaxim', 'text':'comment text', 'created':'1267030230127'}]}, {'numberInProject':'2', 'summary':'some problem', 'description':'some description', 'priority':'1'}]""" if reporter_name is None: if a.get('asignee', None) is not None: reporter_name = a_id_to_yt_login(a['assignee']['id']) else: reporter_name = yt_login new_issue = yt.Issue() new_issue.comments = comments new_issue.reporterName = reporter_name new_issue['AsanaID'] = str(a['id']) new_issue.numberInProject = str(numberInProject) new_issue.summary = a.get('name', '') new_issue.description = a.get('notes', '') new_issue.state = 'Fixed' if a.get('completed', False) is True else 'Submitted' new_issue.assignee = a_id_to_yt_login(a['assignee']['id']) if a['due_on'] is not None: new_issue['Due Date'] = a_to_yt_date(a['due_on']) # new_issue = dict(numberInProject=str(a['id']), summary=a.get('name', ''), description=a.get('notes', ''), # state='Fixed' if a.get('completed', False) is True else 'Submitted') if 'created_at' in a: # created = datetime.strptime(a['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ') # created = "{}{}".format(created.strftime('%s'), created.strftime('%f'))[:-3] new_issue.created = a_to_yt_time(a['created_at']) if 'modified_at' in a: # updated = datetime.strptime(a['modified_at'], '%Y-%m-%dT%H:%M:%S.%fZ') # updated = "{}{}".format(updated.strftime('%s'), updated.strftime('%f'))[:-3] # new_issue.updated = updated new_issue.updated = a_to_yt_time(a['modified_at']) if a.get('completed_at', None) is not None: # resolved = datetime.strptime(a['completed_at'], '%Y-%m-%dT%H:%M:%S.%fZ') # resolved = "{}{}".format(resolved.strftime('%s'), resolved.strftime('%f'))[:-3] # new_issue.resolved = resolved new_issue.resolved = a_to_yt_time(a['completed_at']) if 'projects' in a and len(a['projects']) > 0: new_issue['subsystem'] = a['projects'][0]['name'] new_issues.append(new_issue) numberInProject += 1 print 'Creating new YouTrack Issues for {} (Asana IDs: {})'.format( a_user['email'], [n.AsanaID for n in new_issues]) print yt_conn.importIssues(yt_proj.id, None, new_issues, test=False)