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|Reviewed-on): (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 if not bug_details: |
| 50 return {'error': 'Failed to get bug details from monorail API'} |
| 51 bug_details['comments'] = issue_tracker.GetIssueComments(bug_id) |
| 52 owner = None |
| 53 if bug_details.get('owner'): |
| 54 owner = bug_details.get('owner').get('name') |
| 55 return { |
| 56 'comments': bug_details['comments'], |
| 57 'owner': owner, |
| 58 'published': bug_details['published'], |
| 59 'state': bug_details['state'], |
| 60 'status': bug_details['status'], |
| 61 'summary': bug_details['summary'], |
| 62 } |
| 63 |
| 64 def _GetLinkedRevisions(self, comments): |
| 65 """Parses the comments for commits linked by bugdroid.""" |
| 66 review_urls = [] |
| 67 bugdroid_comments = [c for c in comments if c['author'] == BUGDROID] |
| 68 for comment in bugdroid_comments: |
| 69 m = re.search(REVIEW_RE, comment['content']) |
| 70 if m: |
| 71 review_urls.append(m.group(2)) |
| 72 return review_urls |
| 73 |
| 74 def _GetBisectsForBug(self, bug_id): |
| 75 bisects = try_job.TryJob.query(try_job.TryJob.bug_id == bug_id).fetch() |
| 76 return [{ |
| 77 'status': b.status, |
| 78 'bot': b.bot, |
| 79 'buildbucket_link': '/buildbucket_job_status/%s' % b.buildbucket_job_id, |
| 80 'metric': b.results_data.get('metric'), |
| 81 } for b in bisects] |
OLD | NEW |