def parse_changes (self, review): changesList = [] patchSets = review['patchSets'] for activity in patchSets: if "approvals" not in activity.keys(): continue patchSetNumber = activity['number'] for entry in activity['approvals']: # print "changed_by:" + entry['author'] if "username" in entry["by"].keys(): by = People(entry['by']['username']) elif "email" in entry["by"].keys(): by = People(entry['by']['email']) elif "name" in entry["by"].keys(): by = People(entry['by']['name']) else: by = People(unicode('')) if "name" in entry["by"].keys(): by.set_name(entry["by"]["name"]) if "email" in entry["by"].keys(): by.set_email(entry["by"]["email"]) # print "changed_on:" + entry['updated'] field = entry['type'] new_value = entry['value'] old_value = patchSetNumber update = self._convert_to_datetime(entry["grantedOn"]) change = Change(field, old_value, new_value, by, update) changesList.append(change) return changesList
def parse_changes(self): soup = BeautifulSoup(self.html) self.remove_comments(soup) remove_tags = ['a', 'span', 'i'] changes = [] tables = soup.findAll('table') # We look for the first table with 5 cols table = None for table in tables: if len(table.tr.findAll('th')) == 5: try: for i in table.findAll(remove_tags): i.replaceWith(i.text) except: printerr("error removing HTML tags") break if table is None: return changes rows = list(table.findAll('tr')) for row in rows[1:]: cols = list(row.findAll('td')) if len(cols) == 5: person_email = cols[0].contents[0].strip() person_email = unicode(person_email.replace('@', '@')) date = self._to_datetime_with_secs(cols[1].contents[0].strip()) # when the field contains an Attachment, the list has more #than a field. For example: # # [u'\n', u'Attachment #12723', u'\n Flag\n '] # if len(cols[2].contents) > 1: aux_c = unicode(" ".join(cols[2].contents)) field = unicode(aux_c.replace("\n", "").strip()) else: field = unicode(cols[2].contents[0].replace("\n", "").strip()) removed = unicode(cols[3].contents[0].strip()) added = unicode(cols[4].contents[0].strip()) else: # same as above with the Attachment example if len(cols[0].contents) > 1: aux_c = unicode(" ".join(cols[0].contents)) field = aux_c.replace("\n", "").strip() else: field = cols[0].contents[0].strip() removed = cols[1].contents[0].strip() added = cols[2].contents[0].strip() field, removed, added = self.sanityze_change(field, removed, added) by = People(person_email) by.set_email(person_email) change = Change(field, removed, added, by, date) changes.append(change) return changes
def parse_changes(self): soup = BeautifulSoup(self.html) self.remove_comments(soup) remove_tags = ['a', 'span','i'] changes = [] tables = soup.findAll('table') # We look for the first table with 5 cols table = None for table in tables: if len(table.tr.findAll('th')) == 5: try: for i in table.findAll(remove_tags): i.replaceWith(i.text) except: printerr("error removing HTML tags") break if table is None: return changes rows = list(table.findAll('tr')) for row in rows[1:]: cols = list(row.findAll('td')) if len(cols) == 5: person_email = cols[0].contents[0].strip() person_email = unicode(person_email.replace('@', '@')) date = self._to_datetime_with_secs(cols[1].contents[0].strip()) # when the field contains an Attachment, the list has more #than a field. For example: # # [u'\n', u'Attachment #12723', u'\n Flag\n '] # if len(cols[2].contents) > 1: aux_c = unicode(" ".join(cols[2].contents)) field = unicode(aux_c.replace("\n","").strip()) else: field = unicode(cols[2].contents[0].replace("\n","").strip()) removed = unicode(cols[3].contents[0].strip()) added = unicode(cols[4].contents[0].strip()) else: # same as above with the Attachment example if len(cols[0].contents) > 1: aux_c = unicode(" ".join(cols[0].contents)) field = aux_c.replace("\n","").strip() else: field = cols[0].contents[0].strip() removed = cols[1].contents[0].strip() added = cols[2].contents[0].strip() field, removed, added = self.sanityze_change(field, removed, added) by = People(person_email) by.set_email(person_email) change = Change(field, removed, added, by, date) changes.append(change) return changes
def _get_person(self, lpperson): """ Returns Bicho People object from Launchpad person object """ p = People(lpperson.name) p.set_name(lpperson.display_name) if lpperson.confirmed_email_addresses: for m in lpperson.confirmed_email_addresses: p.set_email(m.email) break return p
def parse_changes(self): soup = BeautifulSoup(self.html) self.remove_comments(soup) remove_tags = ['a', 'span','i'] try: [i.replaceWith(i.contents[0]) for i in soup.findAll(remove_tags)] except Exception: None changes = [] #FIXME The id of the changes are not stored tables = soup.findAll("div", {"class": "actionContainer"}) table = None for table in tables: change_author = table.find("div", {"class": "action-details"}) if change_author == None or len(change_author)<3: self.changes_lost += 1 printerr("Change author format not supported. Change lost!") continue if isinstance(change_author.contents[2], Tag): change_author_str = change_author.contents[2]['rel'] elif isinstance(change_author.contents[2], NavigableString): change_author_str = change_author.contents[2] else: printerr("Change author format not supported") printdbg(change_author) continue author = People(change_author_str.strip()) author.set_email(BugsHandler.getUserEmail(change_author_str.strip())) if isinstance(change_author.contents[4], Tag): date_str = change_author.contents[4].find('time')['datetime'] elif isinstance(change_author.contents[4], NavigableString): date_str = change_author.contents[4] else: printerr("Change date format not supported") continue date = parse(date_str).replace(tzinfo=None) rows = list(table.findAll('tr')) for row in rows: cols = list(row.findAll('td')) if len(cols) == 3: field = unicode(cols[0].contents[0].strip()) old = unicode(cols[1].contents[0].strip()) new = unicode(cols[2].contents[0].strip()) change = Change(field, old, new, author, date) changes.append(change) return changes
def parse_review(self, review): if "username" in review["owner"].keys(): people = People(review['owner']['username']) elif "email" in review["owner"].keys(): people = People(review['owner']['email']) elif "name" in review["owner"].keys(): people = People(review['owner']['name']) else: people = People(unicode('')) if "name" in review["owner"].keys(): people.set_name(review["owner"]["name"]) if "email" in review["owner"].keys(): people.set_email(review["owner"]["email"]) description = "" issue = GerritIssue(review["number"], "review", review["subject"], description, people, self._convert_to_datetime(review["createdOn"]) ) # people = People(review["assigned_to_id"]) # people.set_name(review["assigned_to"]) # issue.assigned_to = people issue.status = review["status"] # No information from Gerrit for this fields issue.assigned_to = None issue.resolution = None issue.priority = None issue.branch = review["branch"] issue.url = review["url"] issue.change_id = review["id"] if "topic" in review.keys(): issue.related_artifacts = review["topic"] else: issue.related_artifacts = None issue.project = review["project"] issue.mod_date = self._convert_to_datetime(review["lastUpdated"]) issue.open = review["open"] return issue
def parse_comments(self, review): if "comments" not in review.keys(): return [] commentsList = [] comments = review['comments'] for comment in comments: if ("username" not in comment['reviewer'].keys()): comment['reviewer']["username"] = comment['reviewer']["name"] by = People(comment['reviewer']["username"]) if ("name" in comment['reviewer'].keys()): by.set_name(comment['reviewer']["name"]) if ("email" in comment['reviewer'].keys()): by.set_email(comment['reviewer']["email"]) com = Comment(comment["message"], by, self._convert_to_datetime(comment["timestamp"])) commentsList.append(com) return commentsList
def parse_changes(self): soup = BeautifulSoup(self.html) self.remove_comments(soup) remove_tags = ['a', 'span','i'] [i.replaceWith(i.contents[0]) for i in soup.findAll(remove_tags)] changes = [] tables = soup.findAll('table') # We need the first table with 5 cols in the first line table = None for table in tables: if len(table.tr.findAll('th')) == 5: break if table is None: return changes rows = list(table.findAll('tr')) for row in rows[1:]: cols = list(row.findAll('td')) if len(cols) == 5: person_email = cols[0].contents[0].strip() person_email = unicode(person_email.replace('@', '@')) date = self._to_datetime_with_secs(cols[1].contents[0].strip()) field = unicode(cols[2].contents[0].strip()) removed = unicode(cols[3].contents[0].strip()) added = unicode(cols[4].contents[0].strip()) else: field = cols[0].contents[0].strip() removed = cols[1].contents[0].strip() added = cols[2].contents[0].strip() field, removed, added = self.sanityze_change(field, removed, added) by = People(person_email) by.set_email(person_email) change = Change(field, removed, added, by, date) changes.append(change) return changes
def get_issue(self): issue_id = self.atags["bug_id"] type = self.atags["bug_severity"] summary = self.atags["short_desc"] if len(self.ctags["long_desc"]) > 0: desc = self.ctags["long_desc"][0]["thetext"] else: desc = "" submitted_by = People(self.atags["reporter"]) submitted_by.set_name(self.atags["reporter_name"]) submitted_by.set_email(self.atags["reporter"]) submitted_on = self._convert_to_datetime(self.atags["creation_ts"]) # FIXME: I miss resolution and priority issue = BugzillaIssue(issue_id, type, summary, desc, submitted_by, submitted_on) issue.set_priority(self.atags["priority"]) issue.set_status(self.atags["bug_status"]) assigned_to = People(self.atags["assigned_to"]) assigned_to.set_name(self.atags["assigned_to_name"]) assigned_to.set_email(self.atags["assigned_to"]) issue.set_assigned(assigned_to) # FIXME = I miss the number of comment and the work_time (useful in # bugzillas) # date must be also a datetime for rc in self._get_raw_comments(): if rc["bug_when"]: by = People(rc["who"]) by.set_name(rc["who_name"]) by.set_email(rc["who"]) com = Comment(rc["thetext"], by, self._to_datetime_with_secs(rc["bug_when"])) issue.add_comment(com) else: #FIXME bug_when empty printdbg("ERROR - Comment") # FIXME TBD: Attachment is not supported so far ## at = Attachment #issue.add_attachment() # FIXME TBD: Relations # fields in btags: dependson, blocked # issue.add_relationship() # issue_id, type issue.set_resolution(self.atags["resolution"]) issue.set_alias(self.atags["alias"]) issue.set_delta_ts(self._to_datetime_with_secs(self.atags["delta_ts"])) issue.set_reporter_accessible(self.atags["reporter_accessible"]) issue.set_cclist_accessible(self.atags["cclist_accessible"]) issue.set_classification_id(self.atags["classification_id"]) issue.set_classification(self.atags["classification"]) issue.set_product(self.atags["product"]) issue.set_component(self.atags["component"]) issue.set_version(self.atags["version"]) issue.set_rep_platform(self.atags["rep_platform"]) issue.set_op_sys(self.atags["op_sys"]) if self.atags["dup_id"]: issue.set_dup_id(int(self.atags["dup_id"])) issue.set_bug_file_loc(self.atags["bug_file_loc"]) issue.set_status_whiteboard(self.atags["status_whiteboard"]) issue.set_target_milestone(self.atags["target_milestone"]) issue.set_votes(self.atags["votes"]) issue.set_everconfirmed(self.atags["everconfirmed"]) issue.set_qa_contact(self.atags["qa_contact"]) issue.set_estimated_time(self.atags["estimated_time"]) issue.set_remaining_time(self.atags["remaining_time"]) issue.set_actual_time(self.atags["actual_time"]) if self.atags["deadline"]: issue.set_deadline(self._convert_to_datetime(self.atags["deadline"])) issue.set_keywords(self.btags["keywords"]) # we also store the list of watchers/CC for w in self.btags["cc"]: auxp = People(w) issue.add_watcher(auxp) issue.set_group(self.btags["group"]) issue.set_flag(self.btags["flag"]) return issue
def get_issue(self): issue_id = self.atags["bug_id"] type = self.atags["bug_severity"] summary = self.atags["short_desc"] if len(self.ctags["long_desc"]) > 0: desc = self.ctags["long_desc"][0]["thetext"] else: desc = "" submitted_by = People(self.atags["reporter"]) submitted_by.set_name(self.atags["reporter_name"]) submitted_by.set_email(self.atags["reporter"]) submitted_on = self._convert_to_datetime(self.atags["creation_ts"]) # FIXME: I miss resolution and priority issue = BugzillaIssue(issue_id, type, summary, desc, submitted_by, submitted_on) issue.set_priority(self.atags["priority"]) issue.set_status(self.atags["bug_status"]) assigned_to = People(self.atags["assigned_to"]) assigned_to.set_name(self.atags["assigned_to_name"]) assigned_to.set_email(self.atags["assigned_to"]) issue.set_assigned(assigned_to) # FIXME = I miss the number of comment and the work_time (useful in # bugzillas) # date must be also a datetime for rc in self._get_raw_comments(): if rc["bug_when"]: by = People(rc["who"]) by.set_name(rc["who_name"]) by.set_email(rc["who"]) com = Comment(rc["thetext"], by, self._to_datetime_with_secs(rc["bug_when"])) issue.add_comment(com) else: #FIXME bug_when empty printdbg("ERROR - Comment") # FIXME TBD: Attachment is not supported so far ## at = Attachment #issue.add_attachment() # FIXME TBD: Relations # fields in btags: dependson, blocked # issue.add_relationship() # issue_id, type issue.set_resolution(self.atags["resolution"]) issue.set_alias(self.atags["alias"]) issue.set_delta_ts(self._to_datetime_with_secs(self.atags["delta_ts"])) issue.set_reporter_accessible(self.atags["reporter_accessible"]) issue.set_cclist_accessible(self.atags["cclist_accessible"]) issue.set_classification_id(self.atags["classification_id"]) issue.set_classification(self.atags["classification"]) issue.set_product(self.atags["product"]) issue.set_component(self.atags["component"]) issue.set_version(self.atags["version"]) issue.set_rep_platform(self.atags["rep_platform"]) issue.set_op_sys(self.atags["op_sys"]) if self.atags["dup_id"]: issue.set_dup_id(int(self.atags["dup_id"])) issue.set_bug_file_loc(self.atags["bug_file_loc"]) issue.set_status_whiteboard(self.atags["status_whiteboard"]) issue.set_target_milestone(self.atags["target_milestone"]) issue.set_votes(self.atags["votes"]) issue.set_everconfirmed(self.atags["everconfirmed"]) issue.set_qa_contact(self.atags["qa_contact"]) issue.set_estimated_time(self.atags["estimated_time"]) issue.set_remaining_time(self.atags["remaining_time"]) issue.set_actual_time(self.atags["actual_time"]) if self.atags["deadline"]: issue.set_deadline( self._convert_to_datetime(self.atags["deadline"])) issue.set_keywords(self.btags["keywords"]) # we also store the list of watchers/CC for w in self.btags["cc"]: auxp = People(w) issue.add_watcher(auxp) issue.set_group(self.btags["group"]) issue.set_flag(self.btags["flag"]) return issue
def getIssue(self, bug): #Return the parse data bug into issue object issue_id = bug.key_id issue_type = bug.bug_type summary = bug.summary description = bug.description status = bug.status resolution = bug.resolution assigned_by = People(bug.assignee_username) assigned_by.set_name(bug.assignee) assigned_by.set_email(BugsHandler.getUserEmail(bug.assignee_username)) submitted_by = People(bug.reporter_username) submitted_by.set_name(bug.reporter) submitted_by.set_email(BugsHandler.getUserEmail(bug.reporter_username)) submitted_on = parse(bug.created).replace(tzinfo=None) issue = JiraIssue(issue_id, issue_type, summary, description, submitted_by, submitted_on) issue.set_assigned(assigned_by) issue.setIssue_key(bug.issue_key) issue.setTitle(bug.title) issue.setLink(bug.link) issue.setEnvironment(bug.environment) issue.setSecurity(bug.security) issue.setUpdated(parse(bug.updated).replace(tzinfo=None)) issue.setVersion(bug.version) issue.setComponent(bug.component) issue.setVotes(bug.votes) issue.setProject(bug.project) issue.setProject_id(bug.project_id) issue.setProject_key(bug.project_key) issue.setStatus(status) issue.setResolution(resolution) bug_activity_url = bug.link + '?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel' printdbg("Bug activity: " + bug_activity_url) data_activity = urllib.urlopen(bug_activity_url).read() parser = SoupHtmlParser(data_activity, bug.key_id) changes = parser.parse_changes() for c in changes: issue.add_change(c) for comment in bug.comments: comment_by = People(comment.comment_author) comment_by.set_email(BugsHandler.getUserEmail(comment.comment_author)) comment_on = parse(comment.comment_created).replace(tzinfo=None) com = Comment(comment.comment, comment_by, comment_on) issue.add_comment(com) for attachment in bug.attachments: url = "/secure/attachment/" + attachment.attachment_id + "/" + attachment.attachment_name attachment_by = People(attachment.attachment_author) attachment_by.set_email(BugsHandler.getUserEmail(attachment.attachment_author)) attachment_on = parse(attachment.attachment_created).replace(tzinfo=None) attach = Attachment(url, attachment_by, attachment_on) issue.add_attachment(attach) #FIXME customfield are not stored in db because is the fields has the same in all the bugs return issue
def getIssue(self, bug): #Return the parse data bug into issue object issue_id = bug.key_id issue_type = bug.bug_type summary = bug.summary description = bug.description status = bug.status resolution = bug.resolution assigned_by = People(bug.assignee_username) assigned_by.set_name(bug.assignee) assigned_by.set_email(BugsHandler.getUserEmail(bug.assignee_username)) submitted_by = People(bug.reporter_username) submitted_by.set_name(bug.reporter) submitted_by.set_email(BugsHandler.getUserEmail(bug.reporter_username)) submitted_on = parse(bug.created).replace(tzinfo=None) issue = JiraIssue(issue_id, issue_type, summary, description, submitted_by, submitted_on) issue.set_assigned(assigned_by) issue.setIssue_key(bug.issue_key) issue.setTitle(bug.title) issue.setLink(bug.link) issue.setEnvironment(bug.environment) issue.setSecurity(bug.security) issue.setUpdated(parse(bug.updated).replace(tzinfo=None)) issue.setVersion(bug.version) issue.setComponent(bug.component) issue.setVotes(bug.votes) issue.setProject(bug.project) issue.setProject_id(bug.project_id) issue.setProject_key(bug.project_key) issue.setStatus(status) issue.setResolution(resolution) bug_activity_url = bug.link + '?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel' printdbg("Bug activity: " + bug_activity_url) data_activity = urllib.urlopen(bug_activity_url).read() parser = SoupHtmlParser(data_activity, bug.key_id) changes = parser.parse_changes() for c in changes: issue.add_change(c) for comment in bug.comments: comment_by = People(comment.comment_author) comment_by.set_email( BugsHandler.getUserEmail(comment.comment_author)) comment_on = parse(comment.comment_created).replace(tzinfo=None) com = Comment(comment.comment, comment_by, comment_on) issue.add_comment(com) for attachment in bug.attachments: url = "/secure/attachment/" + attachment.attachment_id + "/" + attachment.attachment_name attachment_by = People(attachment.attachment_author) attachment_by.set_email( BugsHandler.getUserEmail(attachment.attachment_author)) attachment_on = parse( attachment.attachment_created).replace(tzinfo=None) attach = Attachment(url, attachment_by, attachment_on) issue.add_attachment(attach) #FIXME customfield are not stored in db because is the fields has the same in all the bugs return issue