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 |