| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from datetime import datetime |
| 6 |
| 7 from google.appengine.api import users |
| 5 from google.appengine.ext import ndb | 8 from google.appengine.ext import ndb |
| 6 | 9 |
| 7 from common import constants | 10 from common import constants |
| 8 from common import time_util | 11 from common import time_util |
| 9 from common.base_handler import BaseHandler | 12 from common.base_handler import BaseHandler |
| 10 from common.base_handler import Permission | 13 from common.base_handler import Permission |
| 11 | 14 |
| 12 | 15 |
| 16 def _GetTriageHistory(analysis): |
| 17 if (not users.is_current_user_admin() or |
| 18 not analysis.completed or |
| 19 not analysis.triage_history): |
| 20 return None |
| 21 |
| 22 triage_history = [] |
| 23 for triage_record in analysis.triage_history: |
| 24 triage_history.append({ |
| 25 'triage_time': time_util.FormatDatetime( |
| 26 datetime.utcfromtimestamp(triage_record['triage_timestamp'])), |
| 27 'result_property': triage_record['result_property'], |
| 28 'user_name': triage_record['user_name'], |
| 29 'triage_status': triage_record['triage_status'] |
| 30 }) |
| 31 |
| 32 return triage_history |
| 33 |
| 34 |
| 13 class FracasResultFeedback(BaseHandler): | 35 class FracasResultFeedback(BaseHandler): |
| 14 PERMISSION_LEVEL = Permission.CORP_USER | 36 PERMISSION_LEVEL = Permission.CORP_USER |
| 15 | 37 |
| 16 def HandleGet(self): | 38 def HandleGet(self): |
| 17 """Gets the analysis and feedback triage result of a crash. | 39 """Gets the analysis and feedback triage result of a crash. |
| 18 | 40 |
| 19 Serve HTML page or JSON result as requested. | 41 Serve HTML page or JSON result as requested. |
| 20 """ | 42 """ |
| 21 key = self.request.get('key') | 43 key = self.request.get('key') |
| 22 | 44 |
| 23 analysis = ndb.Key(urlsafe=key).get() | 45 analysis = ndb.Key(urlsafe=key).get() |
| 24 if not analysis: # pragma: no cover. | 46 if not analysis: # pragma: no cover. |
| 25 return BaseHandler.CreateError( | 47 return BaseHandler.CreateError( |
| 26 'cannot find analysis for crash key %s' % key) | 48 'cannot find analysis for crash key %s' % key) |
| 27 | 49 |
| 28 data = { | 50 data = { |
| 29 'signature': analysis.signature, | 51 'signature': analysis.signature, |
| 30 'version': analysis.crashed_version, | 52 'version': analysis.crashed_version, |
| 31 'channel': analysis.channel, | 53 'channel': analysis.channel, |
| 32 'platform': analysis.platform, | 54 'platform': analysis.platform, |
| 33 'regression_range': analysis.result.get('regression_range'), | 55 'regression_range': analysis.result.get('regression_range'), |
| 56 'culprit_regression_range': analysis.culprit_regression_range, |
| 34 'historical_metadata': analysis.historical_metadata, | 57 'historical_metadata': analysis.historical_metadata, |
| 35 'stack_trace': analysis.stack_trace, | 58 'stack_trace': analysis.stack_trace, |
| 36 'suspected_cls': analysis.result.get('suspected_cls'), | 59 'suspected_cls': analysis.result.get('suspected_cls'), |
| 60 'culprit_cls': analysis.culprit_cls, |
| 37 'suspected_project': analysis.result.get('suspected_project'), | 61 'suspected_project': analysis.result.get('suspected_project'), |
| 62 'culprit_project': analysis.culprit_project, |
| 38 'suspected_components': analysis.result.get('suspected_components'), | 63 'suspected_components': analysis.result.get('suspected_components'), |
| 64 'culprit_components': analysis.culprit_components, |
| 39 'request_time': time_util.FormatDatetime(analysis.requested_time), | 65 'request_time': time_util.FormatDatetime(analysis.requested_time), |
| 40 'analysis_completed': analysis.completed, | 66 'analysis_completed': analysis.completed, |
| 41 'analysis_failed': analysis.failed, | 67 'analysis_failed': analysis.failed, |
| 68 'triage_history': _GetTriageHistory(analysis), |
| 69 'analysis_correct': { |
| 70 'regression_range': analysis.regression_range_triage_status, |
| 71 'suspected_cls': analysis.suspected_cls_triage_status, |
| 72 'suspected_project': analysis.suspected_project_triage_status, |
| 73 'suspected_components': analysis.suspected_components_triage_status, |
| 74 }, |
| 75 'note': analysis.note, |
| 76 'key': analysis.key.urlsafe(), |
| 42 } | 77 } |
| 43 | 78 |
| 44 return { | 79 return { |
| 45 'template': 'crash/fracas_result_feedback.html', | 80 'template': 'crash/fracas_result_feedback.html', |
| 46 'data': data, | 81 'data': data, |
| 47 } | 82 } |
| OLD | NEW |