| 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 'name': 'google-breakpad', | 104 'name': 'google-breakpad', |
| 105 }, | 105 }, |
| 106 { | 106 { |
| 107 'name': 'gyp', | 107 'name': 'gyp', |
| 108 } | 108 } |
| 109 ] | 109 ] |
| 110 | 110 |
| 111 | 111 |
| 112 # Uses ClientLogin to authenticate the user for Google Code issue trackers. | 112 # Uses ClientLogin to authenticate the user for Google Code issue trackers. |
| 113 def get_auth_token(email): | 113 def get_auth_token(email): |
| 114 error = Exception() | 114 # KeyringCreds will use the system keyring on the first try, and prompt for |
| 115 # a password on the next ones. |
| 116 creds = upload.KeyringCreds('code.google.com', 'code.google.com', email) |
| 115 for _ in xrange(3): | 117 for _ in xrange(3): |
| 116 email, password = ( | 118 email, password = creds.GetUserCredentials() |
| 117 upload.KeyringCreds('code.google.com', 'google.com', email) | |
| 118 .GetUserCredentials()) | |
| 119 url = 'https://www.google.com/accounts/ClientLogin' | 119 url = 'https://www.google.com/accounts/ClientLogin' |
| 120 data = urllib.urlencode({ | 120 data = urllib.urlencode({ |
| 121 'Email': email, | 121 'Email': email, |
| 122 'Passwd': password, | 122 'Passwd': password, |
| 123 'service': 'code', | 123 'service': 'code', |
| 124 'source': 'chrome-my-activity', | 124 'source': 'chrome-my-activity', |
| 125 'accountType': 'GOOGLE', | 125 'accountType': 'GOOGLE', |
| 126 }) | 126 }) |
| 127 req = urllib2.Request(url, data=data, headers={'Accept': 'text/plain'}) | 127 req = urllib2.Request(url, data=data, headers={'Accept': 'text/plain'}) |
| 128 try: | 128 try: |
| 129 response = urllib2.urlopen(req) | 129 response = urllib2.urlopen(req) |
| 130 response_body = response.read() | 130 response_body = response.read() |
| 131 response_dict = dict(x.split('=') | 131 response_dict = dict(x.split('=') |
| 132 for x in response_body.split('\n') if x) | 132 for x in response_body.split('\n') if x) |
| 133 return response_dict['Auth'] | 133 return response_dict['Auth'] |
| 134 except urllib2.HTTPError, e: | 134 except urllib2.HTTPError, e: |
| 135 error = e | 135 print e |
| 136 | 136 |
| 137 raise error | 137 print 'Unable to authenticate to code.google.com.' |
| 138 print 'Some issues may be missing.' |
| 139 return None |
| 138 | 140 |
| 139 | 141 |
| 140 def username(email): | 142 def username(email): |
| 141 """Keeps the username of an email address.""" | 143 """Keeps the username of an email address.""" |
| 142 return email and email.split('@', 1)[0] | 144 return email and email.split('@', 1)[0] |
| 143 | 145 |
| 144 | 146 |
| 145 def datetime_to_midnight(date): | 147 def datetime_to_midnight(date): |
| 146 return date - timedelta(hours=date.hour, minutes=date.minute, | 148 return date - timedelta(hours=date.hour, minutes=date.minute, |
| 147 seconds=date.second, microseconds=date.microsecond) | 149 seconds=date.second, microseconds=date.microsecond) |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 | 373 |
| 372 gcode_data = urllib.urlencode({ | 374 gcode_data = urllib.urlencode({ |
| 373 'alt': 'json', | 375 'alt': 'json', |
| 374 'max-results': '100000', | 376 'max-results': '100000', |
| 375 'q': '%s' % self.user, | 377 'q': '%s' % self.user, |
| 376 'published-max': self.modified_before.strftime(time_format), | 378 'published-max': self.modified_before.strftime(time_format), |
| 377 'updated-min': self.modified_after.strftime(time_format), | 379 'updated-min': self.modified_after.strftime(time_format), |
| 378 }) | 380 }) |
| 379 | 381 |
| 380 opener = urllib2.build_opener() | 382 opener = urllib2.build_opener() |
| 381 opener.addheaders = [('Authorization', 'GoogleLogin auth=%s' % | 383 if self.google_code_auth_token: |
| 382 self.google_code_auth_token)] | 384 opener.addheaders = [('Authorization', 'GoogleLogin auth=%s' % |
| 383 gcode_get = opener.open(gcode_url + '?' + gcode_data) | 385 self.google_code_auth_token)] |
| 384 gcode_json = json.load(gcode_get) | 386 gcode_json = None |
| 385 gcode_get.close() | 387 try: |
| 388 gcode_get = opener.open(gcode_url + '?' + gcode_data) |
| 389 gcode_json = json.load(gcode_get) |
| 390 gcode_get.close() |
| 391 except urllib2.HTTPError, _: |
| 392 print 'Unable to access ' + instance['name'] + ' issue tracker.' |
| 386 | 393 |
| 387 if 'entry' not in gcode_json['feed']: | 394 if not gcode_json or 'entry' not in gcode_json['feed']: |
| 388 return [] | 395 return [] |
| 389 | 396 |
| 390 issues = gcode_json['feed']['entry'] | 397 issues = gcode_json['feed']['entry'] |
| 391 issues = map(partial(self.process_google_code_issue, instance), issues) | 398 issues = map(partial(self.process_google_code_issue, instance), issues) |
| 392 issues = filter(self.filter_issue, issues) | 399 issues = filter(self.filter_issue, issues) |
| 393 issues = sorted(issues, key=lambda i: i['modified'], reverse=True) | 400 issues = sorted(issues, key=lambda i: i['modified'], reverse=True) |
| 394 return issues | 401 return issues |
| 395 | 402 |
| 396 def process_google_code_issue(self, project, issue): | 403 def process_google_code_issue(self, project, issue): |
| 397 ret = {} | 404 ret = {} |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 print '\n\n\n' | 667 print '\n\n\n' |
| 661 | 668 |
| 662 my_activity.print_changes() | 669 my_activity.print_changes() |
| 663 my_activity.print_reviews() | 670 my_activity.print_reviews() |
| 664 my_activity.print_issues() | 671 my_activity.print_issues() |
| 665 return 0 | 672 return 0 |
| 666 | 673 |
| 667 | 674 |
| 668 if __name__ == '__main__': | 675 if __name__ == '__main__': |
| 669 sys.exit(main()) | 676 sys.exit(main()) |
| OLD | NEW |