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 rietveld stats about the review you done, or forgot to do. | 6 """Get rietveld stats about the review you done, or forgot to do. |
7 | 7 |
8 Example: | 8 Example: |
9 - my_reviews.py -r me@chromium.org -Q for stats for last quarter. | 9 - my_reviews.py -r me@chromium.org -Q for stats for last quarter. |
10 """ | 10 """ |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 return self.total * 1. / self.days | 103 return self.total * 1. / self.days |
104 | 104 |
105 @property | 105 @property |
106 def review_done_per_day(self): | 106 def review_done_per_day(self): |
107 if not self.days: | 107 if not self.days: |
108 return 0 | 108 return 0 |
109 return self.actually_reviewed * 1. / self.days | 109 return self.actually_reviewed * 1. / self.days |
110 | 110 |
111 def finalize(self, first_day, last_day): | 111 def finalize(self, first_day, last_day): |
112 if self.actually_reviewed: | 112 if self.actually_reviewed: |
| 113 assert self.actually_reviewed > 0 |
113 self.percent_lgtm = (self.lgtms * 100. / self.actually_reviewed) | 114 self.percent_lgtm = (self.lgtms * 100. / self.actually_reviewed) |
114 self.percent_drive_by = (self.drive_by * 100. / self.actually_reviewed) | 115 self.percent_drive_by = (self.drive_by * 100. / self.actually_reviewed) |
115 self.percent_not_requested = ( | 116 self.percent_not_requested = ( |
116 self.not_requested * 100. / self.actually_reviewed) | 117 self.not_requested * 100. / self.actually_reviewed) |
| 118 assert bool(first_day) == bool(last_day) |
117 if first_day and last_day: | 119 if first_day and last_day: |
| 120 assert first_day < last_day |
118 self.days = (to_datetime(last_day) - to_datetime(first_day)).days + 1 | 121 self.days = (to_datetime(last_day) - to_datetime(first_day)).days + 1 |
| 122 assert self.days > 0 |
119 | 123 |
120 | 124 |
121 def _process_issue_lgtms(issue, reviewer, stats): | 125 def _process_issue_lgtms(issue, reviewer, stats): |
122 """Calculates LGTMs stats.""" | 126 """Calculates LGTMs stats.""" |
123 stats.actually_reviewed += 1 | 127 stats.actually_reviewed += 1 |
124 reviewer_lgtms = len([ | 128 reviewer_lgtms = len([ |
125 msg for msg in issue['messages'] | 129 msg for msg in issue['messages'] |
126 if msg['approval'] and msg['sender'] == reviewer]) | 130 if msg['approval'] and msg['sender'] == reviewer]) |
127 if reviewer_lgtms > 1: | 131 if reviewer_lgtms > 1: |
128 stats.multiple_lgtms += 1 | 132 stats.multiple_lgtms += 1 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 ', '.join(sorted(issue['reviewers']))) | 214 ', '.join(sorted(issue['reviewers']))) |
211 | 215 |
212 | 216 |
213 def print_reviews(reviewer, created_after, created_before, instance_url): | 217 def print_reviews(reviewer, created_after, created_before, instance_url): |
214 """Prints issues |reviewer| received and potentially reviewed.""" | 218 """Prints issues |reviewer| received and potentially reviewed.""" |
215 remote = rietveld.Rietveld(instance_url, None, None) | 219 remote = rietveld.Rietveld(instance_url, None, None) |
216 | 220 |
217 # The stats we gather. Feel free to send me a CL to get more stats. | 221 # The stats we gather. Feel free to send me a CL to get more stats. |
218 stats = Stats() | 222 stats = Stats() |
219 | 223 |
220 last_issue = None | |
221 first_day = None | |
222 last_day = None | |
223 | |
224 # Column sizes need to match print_issue() output. | 224 # Column sizes need to match print_issue() output. |
225 print >> sys.stderr, ( | 225 print >> sys.stderr, ( |
226 'Issue Creation Did Latency Owner Reviewers') | 226 'Issue Creation Did Latency Owner Reviewers') |
227 | 227 |
228 # See def search() in rietveld.py to see all the filters you can use. | 228 # See def search() in rietveld.py to see all the filters you can use. |
| 229 issues = [] |
229 for issue in remote.search( | 230 for issue in remote.search( |
230 reviewer=reviewer, | 231 reviewer=reviewer, |
231 created_after=created_after, | 232 created_after=created_after, |
232 created_before=created_before, | 233 created_before=created_before, |
233 with_messages=True): | 234 with_messages=True): |
234 last_issue = issue | 235 issues.append(issue) |
235 if not first_day: | |
236 first_day = issue['created'][:10] | |
237 print_issue(issue, username(reviewer), stats) | 236 print_issue(issue, username(reviewer), stats) |
238 if last_issue: | 237 |
239 last_day = last_issue['created'][:10] | 238 issues.sort(key=lambda x: x['created']) |
| 239 first_day = None |
| 240 last_day = None |
| 241 if issues: |
| 242 first_day = issues[0]['created'][:10] |
| 243 last_day = issues[-1]['created'][:10] |
240 stats.finalize(first_day, last_day) | 244 stats.finalize(first_day, last_day) |
241 | 245 |
242 print >> sys.stderr, ( | 246 print >> sys.stderr, ( |
243 '%s reviewed %d issues out of %d (%1.1f%%). %d were self-review.' % | 247 '%s reviewed %d issues out of %d (%1.1f%%). %d were self-review.' % |
244 (reviewer, stats.actually_reviewed, stats.total, stats.percent_done, | 248 (reviewer, stats.actually_reviewed, stats.total, stats.percent_done, |
245 stats.self_review)) | 249 stats.self_review)) |
246 print >> sys.stderr, ( | 250 print >> sys.stderr, ( |
247 '%4.1f review request/day during %3d days (%4.1f r/d done).' % ( | 251 '%4.1f review request/day during %3d days (%4.1f r/d done).' % ( |
248 stats.review_per_day, stats.days, stats.review_done_per_day)) | 252 stats.review_per_day, stats.days, stats.review_done_per_day)) |
249 print >> sys.stderr, ( | 253 print >> sys.stderr, ( |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 print_reviews( | 352 print_reviews( |
349 options.reviewer, | 353 options.reviewer, |
350 options.begin, | 354 options.begin, |
351 options.end, | 355 options.end, |
352 options.instance_url) | 356 options.instance_url) |
353 return 0 | 357 return 0 |
354 | 358 |
355 | 359 |
356 if __name__ == '__main__': | 360 if __name__ == '__main__': |
357 sys.exit(main()) | 361 sys.exit(main()) |
OLD | NEW |