Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Get stats about your activity. | 6 """Get stats about your activity. |
| 7 | 7 |
| 8 Example: | 8 Example: |
| 9 - my_activity.py for stats for the current week (last week on mondays). | 9 - my_activity.py for stats for the current week (last week on mondays). |
| 10 - my_activity.py -Q for stats for last quarter. | 10 - my_activity.py -Q for stats for last quarter. |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 issues) | 339 issues) |
| 340 issues = sorted(issues, key=lambda i: i['modified'], reverse=True) | 340 issues = sorted(issues, key=lambda i: i['modified'], reverse=True) |
| 341 | 341 |
| 342 return issues | 342 return issues |
| 343 | 343 |
| 344 def process_rietveld_issue(self, instance, issue): | 344 def process_rietveld_issue(self, instance, issue): |
| 345 ret = {} | 345 ret = {} |
| 346 ret['owner'] = issue['owner_email'] | 346 ret['owner'] = issue['owner_email'] |
| 347 ret['author'] = ret['owner'] | 347 ret['author'] = ret['owner'] |
| 348 | 348 |
| 349 ret['reviewers'] = set(username(r) for r in issue['reviewers']) | 349 ret['reviewers'] = set(issue['reviewers']) |
| 350 | 350 |
| 351 shorturl = instance['url'] | 351 shorturl = instance['url'] |
| 352 if 'shorturl' in instance: | 352 if 'shorturl' in instance: |
| 353 shorturl = instance['shorturl'] | 353 shorturl = instance['shorturl'] |
| 354 | 354 |
| 355 ret['review_url'] = 'http://%s/%d' % (shorturl, issue['issue']) | 355 ret['review_url'] = 'http://%s/%d' % (shorturl, issue['issue']) |
| 356 ret['header'] = issue['description'].split('\n')[0] | 356 |
| 357 # Rietveld sometimes has '\r\n' instead of '\n'. | |
| 358 ret['header'] = issue['description'].replace('\r', '').split('\n')[0] | |
| 357 | 359 |
| 358 ret['modified'] = datetime_from_rietveld(issue['modified']) | 360 ret['modified'] = datetime_from_rietveld(issue['modified']) |
| 359 ret['created'] = datetime_from_rietveld(issue['created']) | 361 ret['created'] = datetime_from_rietveld(issue['created']) |
| 360 ret['replies'] = self.process_rietveld_replies(issue['messages']) | 362 ret['replies'] = self.process_rietveld_replies(issue['messages']) |
| 361 | 363 |
| 362 return ret | 364 return ret |
| 363 | 365 |
| 364 @staticmethod | 366 @staticmethod |
| 365 def process_rietveld_replies(replies): | 367 def process_rietveld_replies(replies): |
| 366 ret = [] | 368 ret = [] |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 ret['review_url'] = issue['url'] | 405 ret['review_url'] = issue['url'] |
| 404 ret['header'] = issue['subject'] | 406 ret['header'] = issue['subject'] |
| 405 ret['owner'] = issue['owner']['email'] | 407 ret['owner'] = issue['owner']['email'] |
| 406 ret['author'] = ret['owner'] | 408 ret['author'] = ret['owner'] |
| 407 ret['created'] = datetime.fromtimestamp(issue['createdOn']) | 409 ret['created'] = datetime.fromtimestamp(issue['createdOn']) |
| 408 ret['modified'] = datetime.fromtimestamp(issue['lastUpdated']) | 410 ret['modified'] = datetime.fromtimestamp(issue['lastUpdated']) |
| 409 if 'comments' in issue: | 411 if 'comments' in issue: |
| 410 ret['replies'] = self.process_gerrit_issue_replies(issue['comments']) | 412 ret['replies'] = self.process_gerrit_issue_replies(issue['comments']) |
| 411 else: | 413 else: |
| 412 ret['replies'] = [] | 414 ret['replies'] = [] |
| 415 ret['reviewers'] = set() | |
| 416 for reply in ret['replies']: | |
| 417 if reply['author'] != ret['author']: | |
| 418 ret['reviewers'].add(reply['author']) | |
| 413 return ret | 419 return ret |
| 414 | 420 |
| 415 @staticmethod | 421 @staticmethod |
| 416 def process_gerrit_issue_replies(replies): | 422 def process_gerrit_issue_replies(replies): |
| 417 ret = [] | 423 ret = [] |
| 418 replies = filter(lambda r: 'email' in r['reviewer'], replies) | 424 replies = filter(lambda r: 'email' in r['reviewer'], replies) |
| 419 for reply in replies: | 425 for reply in replies: |
| 420 r = {} | 426 r = {} |
| 421 r['author'] = reply['reviewer']['email'] | 427 r['author'] = reply['reviewer']['email'] |
| 422 r['created'] = datetime.fromtimestamp(reply['timestamp']) | 428 r['created'] = datetime.fromtimestamp(reply['timestamp']) |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 reviewers.append(match.group(1)) | 597 reviewers.append(match.group(1)) |
| 592 if instance['review_re']: | 598 if instance['review_re']: |
| 593 match = re.match(instance['review_re'], line) | 599 match = re.match(instance['review_re'], line) |
| 594 if match: | 600 if match: |
| 595 reviews.append(int(match.group(1))) | 601 reviews.append(int(match.group(1))) |
| 596 if instance['change_re']: | 602 if instance['change_re']: |
| 597 match = re.match(instance['change_re'], line) | 603 match = re.match(instance['change_re'], line) |
| 598 if match: | 604 if match: |
| 599 changes.append(int(match.group(1))) | 605 changes.append(int(match.group(1))) |
| 600 | 606 |
| 601 # TODO(enne): should convert full names to usernames via CommitterList. | 607 committer_list = webkitpy.common.config.committers.CommitterList() |
| 602 ret['reviewers'] = set(reviewers) | 608 ret['reviewers'] = set( |
| 609 (committer_list.contributor_by_name(r).emails[0] for r in reviewers)) | |
| 603 | 610 |
| 604 # Reviews more useful than change link itself, but tricky if multiple | 611 # Reviews more useful than change link itself, but tricky if multiple |
| 605 # Reviews == bugs for WebKit changes | 612 # Reviews == bugs for WebKit changes |
| 606 if len(reviews) == 1: | 613 if len(reviews) == 1: |
| 607 url = 'http://%s/%d' % (instance['review_url'], reviews[0]) | 614 url = 'http://%s/%d' % (instance['review_url'], reviews[0]) |
| 608 if instance['review_prop']: | 615 if instance['review_prop']: |
| 609 ret[instance['review_prop']] = reviews[0] | 616 ret[instance['review_prop']] = reviews[0] |
| 610 else: | 617 else: |
| 611 url = 'http://%s/%d' % (instance['change_url'], changes[0]) | 618 url = 'http://%s/%d' % (instance['change_url'], changes[0]) |
| 612 ret['review_url'] = url | 619 ret['review_url'] = url |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 703 print "Failed to import WebKit committer list, skipping WebKit checks." | 710 print "Failed to import WebKit committer list, skipping WebKit checks." |
| 704 self.webkit_repo = None | 711 self.webkit_repo = None |
| 705 return | 712 return |
| 706 | 713 |
| 707 if not webkit_account(self.user): | 714 if not webkit_account(self.user): |
| 708 email = self.user + "@chromium.org" | 715 email = self.user + "@chromium.org" |
| 709 print "No %s in committers.py, skipping WebKit checks." % email | 716 print "No %s in committers.py, skipping WebKit checks." % email |
| 710 self.webkit_repo = None | 717 self.webkit_repo = None |
| 711 | 718 |
| 712 def print_change(self, change): | 719 def print_change(self, change): |
| 720 optional_values = { | |
| 721 'reviewers': ', '.join(change['reviewers']) | |
| 722 } | |
| 713 self.print_generic(self.options.output_format, | 723 self.print_generic(self.options.output_format, |
| 714 self.options.output_format_changes, | 724 self.options.output_format_changes, |
| 715 change['header'], | 725 change['header'], |
| 716 change['review_url'], | 726 change['review_url'], |
| 717 change['author']) | 727 change['author'], |
| 728 optional_values) | |
| 718 | 729 |
| 719 def print_issue(self, issue): | 730 def print_issue(self, issue): |
| 720 optional_values = { | 731 optional_values = { |
| 721 'owner': issue['owner'], | 732 'owner': issue['owner'], |
| 722 } | 733 } |
| 723 self.print_generic(self.options.output_format, | 734 self.print_generic(self.options.output_format, |
| 724 self.options.output_format_issues, | 735 self.options.output_format_issues, |
| 725 issue['header'], | 736 issue['header'], |
| 726 issue['url'], | 737 issue['url'], |
| 727 issue['author'], | 738 issue['author'], |
| 728 optional_values) | 739 optional_values) |
| 729 | 740 |
| 730 def print_review(self, review): | 741 def print_review(self, review): |
|
enne (OOO)
2013/03/11 19:14:16
What about passing reviewers as an optional value
| |
| 731 self.print_generic(self.options.output_format, | 742 self.print_generic(self.options.output_format, |
| 732 self.options.output_format_reviews, | 743 self.options.output_format_reviews, |
| 733 review['header'], | 744 review['header'], |
| 734 review['review_url'], | 745 review['review_url'], |
| 735 review['author']) | 746 review['author']) |
| 736 | 747 |
| 737 @staticmethod | 748 @staticmethod |
| 738 def print_generic(default_fmt, specific_fmt, | 749 def print_generic(default_fmt, specific_fmt, |
| 739 title, url, author, | 750 title, url, author, |
| 740 optional_values=None): | 751 optional_values=None): |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1003 print '\n\n\n' | 1014 print '\n\n\n' |
| 1004 | 1015 |
| 1005 my_activity.print_changes() | 1016 my_activity.print_changes() |
| 1006 my_activity.print_reviews() | 1017 my_activity.print_reviews() |
| 1007 my_activity.print_issues() | 1018 my_activity.print_issues() |
| 1008 return 0 | 1019 return 0 |
| 1009 | 1020 |
| 1010 | 1021 |
| 1011 if __name__ == '__main__': | 1022 if __name__ == '__main__': |
| 1012 sys.exit(main()) | 1023 sys.exit(main()) |
| OLD | NEW |