OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 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 """This script queries the Chromium issue tracker and e-mails the results. | 6 """This script queries the Chromium issue tracker and e-mails the results. |
7 | 7 |
8 It queries issue tracker using Issue Tracker API. The query | 8 It queries issue tracker using Issue Tracker API. The query |
9 parameters can be specified by command-line arguments. For example, with the | 9 parameters can be specified by command-line arguments. For example, with the |
10 following command: | 10 following command: |
11 | 11 |
12 'python bug_hunter.py -q video Status:Unconfirmed OR audio Status:Unconfirmed | 12 'python bug_hunter.py -q video Status:Unconfirmed OR audio Status:Unconfirmed |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 | 79 |
80 _INTERVAL_UNIT_CHOICES = ('hours', 'days', 'weeks') | 80 _INTERVAL_UNIT_CHOICES = ('hours', 'days', 'weeks') |
81 | 81 |
82 # URLs in this list are excluded from URL extraction from bug | 82 # URLs in this list are excluded from URL extraction from bug |
83 # content/comments. Each list element should not contain the url ending in | 83 # content/comments. Each list element should not contain the url ending in |
84 # '/'. For example, the element should be 'http://www.google.com' but not | 84 # '/'. For example, the element should be 'http://www.google.com' but not |
85 # 'http://www.google.com/' | 85 # 'http://www.google.com/' |
86 _URL_EXCLUSION_LIST = ('http://www.youtube.com/html5', | 86 _URL_EXCLUSION_LIST = ('http://www.youtube.com/html5', |
87 'http://www.google.com') | 87 'http://www.google.com') |
88 _ISSUE_ELEMENT_IN_EMAIL_CHOICES = ('issue_id', 'author', 'status', 'state', | 88 _ISSUE_ELEMENT_IN_EMAIL_CHOICES = ('issue_id', 'author', 'status', 'state', |
89 'content', 'comments', 'labels', 'urls') | 89 'content', 'comments', 'labels', 'urls', |
| 90 'mstone') |
90 | 91 |
91 | 92 |
92 def ParseArgs(): | 93 def ParseArgs(): |
93 """Returns options dictionary from parsed command line arguments.""" | 94 """Returns options dictionary from parsed command line arguments.""" |
94 parser = optparse.OptionParser() | 95 parser = optparse.OptionParser() |
95 | 96 |
96 parser.add_option('-e', '--email-entries', | 97 parser.add_option('-e', '--email-entries', |
97 help=('A comma-separated list of issue entries that are ' | 98 help=('A comma-separated list of issue entries that are ' |
98 'sent in the email content. ' | 99 'sent in the email content. ' |
99 'Possible strings are %s. Default: %%default.' % | 100 'Possible strings are %s. Default: %%default.' % |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 if 'comments' in self._options.email_entries: | 240 if 'comments' in self._options.email_entries: |
240 comments = ''.join( | 241 comments = ''.join( |
241 [''.join(comment) if not comment else '' | 242 [''.join(comment) if not comment else '' |
242 for comment | 243 for comment |
243 in self.GetComments(issue_id, self._options.max_comments)]) | 244 in self.GetComments(issue_id, self._options.max_comments)]) |
244 content = BugHunterUtils.StripHTML(entry.content.text) | 245 content = BugHunterUtils.StripHTML(entry.content.text) |
245 url_list = list( | 246 url_list = list( |
246 set(re.findall(r'(https?://\S+)', content + comments))) | 247 set(re.findall(r'(https?://\S+)', content + comments))) |
247 url_list = [url for url in url_list | 248 url_list = [url for url in url_list |
248 if not url.rstrip('/') in _URL_EXCLUSION_LIST] | 249 if not url.rstrip('/') in _URL_EXCLUSION_LIST] |
249 issues.append({'issue_id': issue_id, 'title': entry.title.text, | 250 mstone = '' |
250 'author': entry.author[0].name.text, | 251 r = re.compile(r'Mstone-(\d*)') |
251 'status': entry.status.text, | 252 for label in label_list: |
252 'state': entry.state.text, 'content': content, | 253 m = r.search(label) |
253 'comments': comments, 'labels': label_list, | 254 if m: |
254 'urls': url_list}) | 255 mstone = m.group(1) |
| 256 issues.append( |
| 257 {'issue_id': issue_id, 'title': entry.title.text, |
| 258 'author': entry.author[0].name.text, |
| 259 'status': entry.status.text if entry.status is not None else '', |
| 260 'state': entry.state.text if entry.state is not None else '', |
| 261 'content': content, 'mstone': mstone, 'comments': comments, |
| 262 'labels': label_list, 'urls': url_list}) |
255 return sorted(issues, key=itemgetter('issue_id'), reverse=True) | 263 return sorted(issues, key=itemgetter('issue_id'), reverse=True) |
256 | 264 |
257 def _SetUpEmailSubjectMsg(self, issues): | 265 def _SetUpEmailSubjectMsg(self, issues): |
258 """Set up email subject and its content. | 266 """Set up email subject and its content. |
259 | 267 |
260 Args: | 268 Args: |
261 issues: Please refer to the return value in GetIssues(). | 269 issues: Please refer to the return value in GetIssues(). |
262 | 270 |
263 Returns: | 271 Returns: |
264 A tuple of two strings (email subject and email content). | 272 A tuple of two strings (email subject and email content). |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 bh = BugHunter(ops) | 371 bh = BugHunter(ops) |
364 issues = bh.GetIssues() | 372 issues = bh.GetIssues() |
365 if issues and ops.sender_email_address and ops.receiver_email_address: | 373 if issues and ops.sender_email_address and ops.receiver_email_address: |
366 bh.SendResultEmail(issues) | 374 bh.SendResultEmail(issues) |
367 if issues: | 375 if issues: |
368 bh.WriteIssuesToFileInCSV(issues, ops.output_filename) | 376 bh.WriteIssuesToFileInCSV(issues, ops.output_filename) |
369 | 377 |
370 | 378 |
371 if __name__ == '__main__': | 379 if __name__ == '__main__': |
372 Main() | 380 Main() |
OLD | NEW |