OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2017 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 """Provides an endpoint for getting details about a sheriffed bug.""" | |
6 | |
7 import json | |
8 import re | |
9 | |
10 from dashboard import oauth2_decorator | |
11 from dashboard.common import request_handler | |
12 from dashboard.models import try_job | |
13 from dashboard.services import issue_tracker_service | |
14 | |
15 | |
16 BUGDROID = 'bugdroid1@chromium.org' | |
17 REVIEW_RE = r'Review-Url: (https?:\/\/[\/\.\w\d]+)' | |
18 | |
19 | |
20 class BugDetailsHandler(request_handler.RequestHandler): | |
21 """Gets details about a sheriffed bug.""" | |
22 | |
23 def post(self): | |
24 """POST is the same as GET for this endpoint.""" | |
25 self.get() | |
26 | |
27 @oauth2_decorator.DECORATOR.oauth_required | |
28 def get(self): | |
29 """Response handler to get details about a specific bug. | |
30 | |
31 Request parameters: | |
32 bug_id: Bug ID number, as a string | |
33 """ | |
34 bug_id = int(self.request.get('bug_id'), 0) | |
35 if bug_id <= 0: | |
36 self.ReportError('Invalid or no bug id specified.') | |
37 return | |
38 | |
39 bug_details = self._GetDetailsFromMonorail(bug_id) | |
40 bug_details['review_urls'] = self._GetLinkedRevisions( | |
41 bug_details['comments']) | |
42 bug_details['bisects'] = self._GetBisectsForBug(bug_id) | |
43 self.response.out.write(json.dumps(bug_details)) | |
44 | |
45 def _GetDetailsFromMonorail(self, bug_id): | |
46 http = oauth2_decorator.DECORATOR.http() | |
47 issue_tracker = issue_tracker_service.IssueTrackerService(http) | |
48 bug_details = issue_tracker.GetIssue(bug_id) | |
49 bug_details['comments'] = issue_tracker.GetIssueComments(bug_id) | |
50 owner = None | |
51 if bug_details.get('owner'): | |
52 owner = bug_details.get('owner').get('name') | |
53 return { | |
54 'comments': bug_details['comments'], | |
55 'owner': owner, | |
56 'published': bug_details['published'], | |
57 'state': bug_details['state'], | |
58 'status': bug_details['status'], | |
59 'summary': bug_details['summary'], | |
60 } | |
61 | |
62 def _GetLinkedRevisions(self, comments): | |
63 """Parses the comments for commits linked by bugdroid.""" | |
64 review_urls = [] | |
65 bugdroid_comments = [c for c in comments if c['author'] == BUGDROID] | |
66 for comment in bugdroid_comments: | |
67 m = re.search(REVIEW_RE, comment['content']) | |
shatch
2017/02/23 17:27:22
nit: I think when angle cl's come through, they're
| |
68 if m: | |
69 review_urls.append(m.group(1)) | |
70 return review_urls | |
71 | |
72 def _GetBisectsForBug(self, bug_id): | |
73 bisects = try_job.TryJob.query(try_job.TryJob.bug_id == bug_id).fetch() | |
74 return [{ | |
75 'status': b.status, | |
76 'bot': b.bot, | |
77 'buildbucket_link': '/buildbucket_job_status/%s' % b.buildbucket_job_id, | |
78 'metric': b.results_data.get('metric'), | |
79 } for b in bisects] | |
OLD | NEW |