blob: 3dd8aa70b30367deb012ffb6f602259c4ecfb456 [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Provides the web interface to query the status of a buildbucket job."""
import json
import time
from dashboard import buildbucket_service
from dashboard import request_handler
class BuildbucketJobStatusHandler(request_handler.RequestHandler):
"""Handler for requests of the form /buildbucket_job_status/01234567...
This displays information regarding the status of the buildbucket job in a
human-readable format.
"""
def get(self, job_id):
original_status = buildbucket_service.GetJobStatus(job_id)
error = 'error' in original_status
if error:
error_reason = original_status['error'].get('reason')
status_text = json.dumps(original_status, sort_keys=True, indent=4)
else:
clean_status = _ConvertTimes(_ParseJsonKeys(
original_status.get('build')))
status_text = json.dumps(clean_status, sort_keys=True, indent=4)
self.RenderHtml(
'buildbucket_job_status.html',
{
'job_id': job_id,
'status_text': 'DATA:' + status_text,
'build': None if error else clean_status,
'error': error_reason if error else None,
'original_response': original_status,
})
def _ConvertTimes(dictionary):
"""Replaces all keys that end in '_ts' with human readable times.
It seems from sample results that *_ts in the response are specified in
microseconds since the UNIX epoch.
Args:
dictionary: A dictionary with the original data.
Returns:
A copy of the original dictionary with appropriate replacements.
"""
result = dictionary.copy()
for key in result:
if key.endswith('_ts'):
# We cast as float because the data comes as a string containing the
# number of microseconds since the unix epoch.
time_seconds = float(result[key]) / 1000000
time_string = time.ctime(time_seconds)
result[key.replace('_ts', '_utc')] = time_string
result.pop(key)
return result
def _ParseJsonKeys(dictionary):
"""Replaces values with json strings with objects parsed from them.
Certain nested json objects are returned as strings. We parse them to access
their properties. Note this method is not recursive and only parses objects
in the topmost level, i.e. only string values in the given dictionary and
not in nested dictionaries it might contain.
Args:
dictionary: A dictionary with the original data.
Returns:
A copy of the original dictionary with appropriate replacements.
"""
result = dictionary.copy()
for key in result:
if key.endswith('_json'):
result[key.replace('_json', '')] = json.loads(
result[key])
result.pop(key)
return result