зеркало из https://github.com/mozilla/eideticker.git
Bug 1050552 - Allow storage of multiple dashboards at one URL;r=davehunt
This commit is contained in:
Родитель
4ddc6803aa
Коммит
5de4435bd5
|
@ -7,6 +7,7 @@ import optparse
|
|||
import os
|
||||
import requests
|
||||
import sys
|
||||
import urlparse
|
||||
|
||||
exit_status = 0
|
||||
MAX_WORKERS = 8
|
||||
|
@ -43,6 +44,11 @@ def validate_json_response(r):
|
|||
|
||||
return True
|
||||
|
||||
def urljoin(*args):
|
||||
baseurl = args[0]
|
||||
path = "/".join(args[1:])
|
||||
return urlparse.urljoin(baseurl, path)
|
||||
|
||||
def download_file(url, filename):
|
||||
r = requests.get(url)
|
||||
if not validate_response(r):
|
||||
|
@ -77,21 +83,25 @@ def download_testdata(url, baseurl, filename, options, metadatadir,
|
|||
videodir, profiledir):
|
||||
r = requests.get(url)
|
||||
if not validate_json_response(r):
|
||||
print "WARNING: %s json data invalid" % url
|
||||
return
|
||||
|
||||
open(filename, 'w').write(r.content)
|
||||
|
||||
testdata = r.json()['testdata']
|
||||
with concurrent.futures.ThreadPoolExecutor(MAX_WORKERS) as executor:
|
||||
testdata = r.json()['testdata']
|
||||
for appname in testdata.keys():
|
||||
for date in testdata[appname].keys():
|
||||
for datapoint in testdata[appname][date]:
|
||||
uuid = datapoint['uuid']
|
||||
if options.download_metadata:
|
||||
metadata_filename = "%s.json" % uuid
|
||||
executor.submit(download_metadata,
|
||||
baseurl + 'metadata/%s.json' % uuid,
|
||||
urljoin(baseurl, 'metadata',
|
||||
metadata_filename),
|
||||
baseurl,
|
||||
os.path.join(metadatadir,
|
||||
'%s.json' % uuid),
|
||||
metadata_filename),
|
||||
options, videodir,
|
||||
profiledir)
|
||||
|
||||
|
@ -103,9 +113,13 @@ parser.add_option("--full-mirror", action="store_true",
|
|||
parser.add_option("--skip-metadata", action="store_false",
|
||||
dest="download_metadata", default=True,
|
||||
help="Skip downloading metadata JSON files")
|
||||
parser.add_option("--dashboard-id", action="store",
|
||||
dest="dashboard_id",
|
||||
help="Only download information for dashboard id")
|
||||
parser.add_option("--device-id", action="store",
|
||||
dest="device_id",
|
||||
help="Only download information for device id")
|
||||
help="Only download information for device id (must be used "
|
||||
"in conjunction with --dashboard-id)")
|
||||
parser.add_option("--rewrite-metadata", action="store_true",
|
||||
dest="rewrite_metadata", default=False,
|
||||
help="Rewrite metadata to use absolute URLs to original "
|
||||
|
@ -117,7 +131,11 @@ if len(args) != 2:
|
|||
sys.exit(1)
|
||||
|
||||
if options.full_mirror and not options.download_metadata:
|
||||
parser.error("ERROR: Need to download metadata for full mirror")
|
||||
parser.error("Need to download metadata for full mirror")
|
||||
sys.exit(1)
|
||||
|
||||
if options.device_id and not options.dashboard_id:
|
||||
parser.error("--device-id must be used in conjunction with --dashboard-id")
|
||||
sys.exit(1)
|
||||
|
||||
(baseurl, outputdir) = args
|
||||
|
@ -130,44 +148,69 @@ metadatadir = os.path.join(outputdir, 'metadata')
|
|||
videodir = os.path.join(outputdir, 'videos')
|
||||
profiledir = os.path.join(outputdir, 'profiles')
|
||||
|
||||
r = requests.get(baseurl + 'devices.json')
|
||||
r = requests.get(urljoin(baseurl, 'dashboard.json'))
|
||||
if not validate_json_response(r):
|
||||
print "Can't download device list, exiting"
|
||||
print "Can't download dashboard list, exiting"
|
||||
sys.exit(1)
|
||||
devicedict = r.json()
|
||||
save_file(os.path.join(outputdir, 'dashboard.json'), r.content)
|
||||
|
||||
save_file(os.path.join(outputdir, 'devices.json'), r.content)
|
||||
|
||||
if options.device_id:
|
||||
if options.device_id in r.json()['devices'].keys():
|
||||
deviceids = [ options.device_id ]
|
||||
dashboard_ids = map(lambda d: d['id'], r.json()['dashboards'])
|
||||
if options.dashboard_id:
|
||||
if options.dashboard_id in dashboard_ids:
|
||||
dashboard_ids = [ options.dashboard_id ]
|
||||
else:
|
||||
print "WARNING: Device id '%s' specified but unavailable. Skipping." % \
|
||||
options.device_id
|
||||
deviceids = []
|
||||
else:
|
||||
deviceids = devicedict['devices'].keys()
|
||||
print "ERROR: dashboard id '%s' specified but unavailable." % \
|
||||
options.dashboard_id
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(MAX_WORKERS) as executor:
|
||||
for deviceid in deviceids:
|
||||
for branchid in devicedict['devices'][deviceid]['branches']:
|
||||
r = requests.get(baseurl + '%s/%s/tests.json' % (deviceid, branchid))
|
||||
if not validate_json_response(r):
|
||||
print "Skipping tests for device: %s, branch: %s" % (
|
||||
deviceid, branchid)
|
||||
continue
|
||||
for dashboard_id in dashboard_ids:
|
||||
dashboard_dir = os.path.join(outputdir, dashboard_id)
|
||||
create_dir(dashboard_dir)
|
||||
|
||||
testdir = os.path.join(outputdir, deviceid, branchid)
|
||||
create_dir(testdir)
|
||||
save_file(os.path.join(testdir, 'tests.json'), r.content)
|
||||
testnames = r.json()['tests'].keys()
|
||||
for testname in testnames:
|
||||
executor.submit(download_testdata,
|
||||
baseurl + '%s/%s/%s.json' % (deviceid, branchid, testname),
|
||||
baseurl,
|
||||
os.path.join(outputdir, deviceid, branchid,
|
||||
'%s.json' % testname),
|
||||
options,
|
||||
metadatadir, videodir, profiledir)
|
||||
r = requests.get(urljoin(baseurl, dashboard_id, 'devices.json'))
|
||||
if not validate_json_response(r):
|
||||
print "ERROR: Can't download device list for dashboard '%s', " \
|
||||
"exiting" % dashboard_id
|
||||
sys.exit(1)
|
||||
|
||||
save_file(os.path.join(dashboard_dir, 'devices.json'), r.content)
|
||||
devices = r.json()['devices']
|
||||
|
||||
if options.device_id:
|
||||
if options.device_id in devices.keys():
|
||||
deviceids = [ options.device_id ]
|
||||
else:
|
||||
print "WARNING: Device id '%s' specified but unavailable. " \
|
||||
"Skipping." % options.device_id
|
||||
deviceids = []
|
||||
else:
|
||||
deviceids = devices.keys()
|
||||
|
||||
for deviceid in deviceids:
|
||||
for branchid in devices[deviceid]['branches']:
|
||||
r = requests.get(urljoin(baseurl, dashboard_id, deviceid,
|
||||
branchid, 'tests.json'))
|
||||
if not validate_json_response(r):
|
||||
print "WARNING: Skipping tests for dashboard %s, " \
|
||||
"device: %s, branch: %s" % (dashboard_id, deviceid,
|
||||
branchid)
|
||||
continue
|
||||
|
||||
testdir = os.path.join(dashboard_dir, deviceid, branchid)
|
||||
create_dir(testdir)
|
||||
save_file(os.path.join(testdir, 'tests.json'), r.content)
|
||||
|
||||
tests = r.json()['tests']
|
||||
for testname in tests.keys():
|
||||
testfilename = '%s.json' % testname
|
||||
executor.submit(download_testdata,
|
||||
urljoin(baseurl, dashboard_id, deviceid,
|
||||
branchid, testfilename),
|
||||
baseurl,
|
||||
os.path.join(outputdir, dashboard_id,
|
||||
deviceid, branchid,
|
||||
testfilename),
|
||||
options,
|
||||
metadatadir, videodir, profiledir)
|
||||
|
||||
sys.exit(exit_status)
|
||||
|
|
|
@ -118,6 +118,7 @@ def runtest(dm, device_prefs, options, product, appinfo, testinfo,
|
|||
|
||||
# Write testdata
|
||||
eideticker.update_dashboard_testdata(options.dashboard_dir,
|
||||
options.dashboard_id,
|
||||
options.device_id,
|
||||
options.branch_id, testinfo,
|
||||
productname, appdate,
|
||||
|
@ -131,6 +132,12 @@ def main(args=sys.argv[1:]):
|
|||
parser.add_option("--enable-profiling",
|
||||
action="store_true", dest="enable_profiling",
|
||||
help="Create SPS profile to go along with capture")
|
||||
parser.add_option("--dashboard-id", action="store", dest="dashboard_id",
|
||||
help="id of dashboard (used in output json)",
|
||||
default=os.environ.get('DASHBOARD_ID'))
|
||||
parser.add_option("--dashboard-name", action="store", dest="dashboard_name",
|
||||
help="name of dashboard to display",
|
||||
default=os.environ.get('DASHBOARD_NAME'))
|
||||
parser.add_option("--device-id", action="store", dest="device_id",
|
||||
help="id of device (used in output json)",
|
||||
default=os.environ.get('DEVICE_ID'))
|
||||
|
@ -166,14 +173,19 @@ def main(args=sys.argv[1:]):
|
|||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
if not options.dashboard_id:
|
||||
parser.error("Must specify dashboard id (either with --dashboard-id "
|
||||
"or with DASHBOARD_ID environment variable)")
|
||||
if not options.dashboard_name:
|
||||
parser.error("Must specify dashboard name (either with "
|
||||
"--dashboard-name or with DASHBOARD_NAME environment "
|
||||
"varaiable)")
|
||||
if not options.device_id:
|
||||
print "ERROR: Must specify device id (either with --device-id or with " \
|
||||
"DEVICE_ID environment variable)"
|
||||
sys.exit(1)
|
||||
parser.error("Must specify device id (either with --device-id or with "
|
||||
"DEVICE_ID environment variable)")
|
||||
if not options.branch_id:
|
||||
print "ERROR: Must specify branch (either with --branch or with " \
|
||||
"BRANCH environment variable)"
|
||||
sys.exit(1)
|
||||
parser.error("Must specify branch (either with --branch or with "
|
||||
"BRANCH environment variable)")
|
||||
|
||||
# get device info
|
||||
device_prefs = eideticker.getDevicePrefs(options)
|
||||
|
@ -195,9 +207,11 @@ def main(args=sys.argv[1:]):
|
|||
else:
|
||||
print "ERROR: Unknown device type '%s'" % options.devicetype
|
||||
|
||||
# update device index
|
||||
eideticker.update_dashboard_device_list(options.dashboard_dir, options.device_id,
|
||||
options.branch_id, device_info)
|
||||
# update dashboard / device index
|
||||
eideticker.update_dashboard_list(options.dashboard_dir, options.dashboard_id,
|
||||
options.dashboard_name)
|
||||
eideticker.update_dashboard_device_list(options.dashboard_dir, options.dashboard_id,
|
||||
options.device_id, options.branch_id, device_info)
|
||||
|
||||
# get application/build info
|
||||
if options.devicetype == "android":
|
||||
|
@ -236,8 +250,8 @@ def main(args=sys.argv[1:]):
|
|||
for testkey in args:
|
||||
testinfo = eideticker.get_testinfo(testkey)
|
||||
|
||||
eideticker.update_dashboard_test_list(options.dashboard_dir, options.device_id,
|
||||
options.branch_id,
|
||||
eideticker.update_dashboard_test_list(options.dashboard_dir, options.dashboard_id,
|
||||
options.device_id, options.branch_id,
|
||||
testinfo)
|
||||
|
||||
current_date = time.strftime("%Y-%m-%d")
|
||||
|
|
|
@ -89,19 +89,21 @@
|
|||
|
||||
<body>
|
||||
<div class="navbar navbar-default navbar-static-top">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand">Eideticker Dashboard</a>
|
||||
</div>
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand">Eideticker Dashboard</a>
|
||||
</div>
|
||||
<ul id="dashboard-chooser" class="nav navbar-nav">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="chooser">
|
||||
<div class="list-group" id="device-chooser"></div>
|
||||
<div class="list-group" id="branch-chooser"></div>
|
||||
<div class="list-group" id="test-chooser"></div>
|
||||
</div>
|
||||
<div id="chooser">
|
||||
<div class="list-group" id="device-chooser"></div>
|
||||
<div class="list-group" id="branch-chooser"></div>
|
||||
<div class="list-group" id="test-chooser"></div>
|
||||
</div>
|
||||
|
||||
<div id="data-view">
|
||||
</div>
|
||||
<div id="data-view">
|
||||
</div>
|
||||
|
||||
<footer id="footer">
|
||||
<p>Built by <a href="http://wiki.mozilla.org/Auto-tools">Mozilla Firefox Automation & Tools Engineering</a>. Source available on <a href="https://github.com/mozilla/eideticker">github</a>. Bug or feature request? File it on <a href="http://bugzilla.mozilla.org">bugzilla</a> in the <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=Eideticker">Eideticker component</a>.</p>
|
||||
|
|
|
@ -8,8 +8,9 @@ function getResourceURL(path) {
|
|||
return serverPrefix + path;
|
||||
}
|
||||
|
||||
function updateContent(testInfo, deviceId, branchId, testId, measureId, timeRange) {
|
||||
$.getJSON(getResourceURL([deviceId, branchId, testId].join('/') + '.json'), function(dict) {
|
||||
function updateContent(testInfo, dashboardId, deviceId, branchId, testId, measureId, timeRange) {
|
||||
$.getJSON(getResourceURL([dashboardId, deviceId, branchId,
|
||||
testId].join('/') + '.json'), function(dict) {
|
||||
if (!dict || !dict['testdata']) {
|
||||
$('#data-view').html(ich.noGraph({
|
||||
"title": testInfo.shortDesc,
|
||||
|
@ -88,7 +89,7 @@ function updateContent(testInfo, deviceId, branchId, testId, measureId, timeRang
|
|||
$('#measure-'+measureId).attr("selected", "true");
|
||||
$('#measure').change(function() {
|
||||
var newMeasureId = $(this).val();
|
||||
window.location.hash = '/' + [ deviceId, branchId, testId,
|
||||
window.location.hash = '/' + [ dashboardId, deviceId, branchId, testId,
|
||||
newMeasureId, timeRange ].join('/');
|
||||
});
|
||||
}
|
||||
|
@ -97,10 +98,9 @@ function updateContent(testInfo, deviceId, branchId, testId, measureId, timeRang
|
|||
$('#time-range-' + timeRange).attr("selected", "true");
|
||||
$('#time-range').change(function() {
|
||||
var newTimeRange = $(this).val();
|
||||
window.location.hash = '/' + [ deviceId, branchId, testId,
|
||||
window.location.hash = '/' + [ dashboardId, deviceId, branchId, testId,
|
||||
measureId, newTimeRange ].join('/');
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -372,91 +372,138 @@ function updateGraph(title, rawdata, measureId) {
|
|||
}
|
||||
|
||||
$(function() {
|
||||
var graphData = {};
|
||||
var dashboards;
|
||||
var devices;
|
||||
var deviceIds;
|
||||
var currentDashboardId;
|
||||
|
||||
$.getJSON(getResourceURL('devices.json'), function(deviceData) {
|
||||
var devices = deviceData['devices'];
|
||||
var deviceIds = Object.keys(devices).sort();
|
||||
function getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest) {
|
||||
var device = devices[deviceId];
|
||||
var tests = device[branchId].tests;
|
||||
var testIds = Object.keys(tests).sort();
|
||||
var testId;
|
||||
if (preferredTest && testIds.indexOf(preferredTest) >= 0) {
|
||||
// this deviceid/branch combo has our preferred test, return it
|
||||
return preferredTest;
|
||||
} else {
|
||||
// this deviceid/branch combo *doesn't* have our preferred test,
|
||||
// fall back to the first one
|
||||
return testIds[0];
|
||||
}
|
||||
}
|
||||
|
||||
var deviceBranchPairs = [];
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
devices[deviceId].branches.forEach(function(branchId) {
|
||||
deviceBranchPairs.push([deviceId, branchId]);
|
||||
});
|
||||
function updateDashboardChooser() {
|
||||
$('#dashboard-chooser').empty();
|
||||
dashboards.forEach(function(dashboard) {
|
||||
$('<li id="dashboard-' + dashboard.id + '"><a href="' + '#/' +
|
||||
dashboard.id + '">' + dashboard.name +
|
||||
"</a></li>").appendTo($('#dashboard-chooser'));
|
||||
});
|
||||
$.when.apply($, deviceBranchPairs.map(function(pair) {
|
||||
var deviceId = pair[0];
|
||||
var branchId = pair[1];
|
||||
$("#dashboard-" + currentDashboardId).addClass("active");
|
||||
}
|
||||
|
||||
return $.getJSON(getResourceURL([deviceId, branchId, 'tests.json'].join('/')),
|
||||
function(testData) {
|
||||
var tests = testData['tests'];
|
||||
if (!devices[deviceId][branchId]) {
|
||||
devices[deviceId][branchId] = {};
|
||||
}
|
||||
devices[deviceId][branchId]['tests'] = tests;
|
||||
});
|
||||
})).done(function() {
|
||||
var defaultDeviceId = deviceIds[0];
|
||||
function updateDeviceChooser(timeRange, preferredBranchId, preferredTest) {
|
||||
$('#device-chooser').empty();
|
||||
|
||||
function getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest) {
|
||||
var device = devices[deviceId];
|
||||
var tests = device[branchId].tests;
|
||||
var testIds = Object.keys(tests).sort();
|
||||
var testId;
|
||||
if (preferredTest && testIds.indexOf(preferredTest) >= 0) {
|
||||
// this deviceid/branch combo has our preferred test, return it
|
||||
return preferredTest;
|
||||
} else {
|
||||
// this deviceid/branch combo *doesn't* have our preferred test,
|
||||
// fall back to the first one
|
||||
return testIds[0];
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
var device = devices[deviceId];
|
||||
|
||||
var branchId;
|
||||
if (preferredBranchId && device.branches.indexOf(preferredBranchId) >= 0) {
|
||||
branchId = preferredBranchId;
|
||||
} else {
|
||||
branchId = device.branches.sort()[0];
|
||||
}
|
||||
|
||||
var testId = getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest);
|
||||
var defaultMeasureId = device[branchId].tests[testId].defaultMeasureId;
|
||||
|
||||
var deviceURL = "#/" + [ currentDashboardId, deviceId, branchId, testId, defaultMeasureId, timeRange ].join('/');
|
||||
$('<a href="' + deviceURL + '" id="device-' + deviceId + '" deviceid= ' + deviceId + ' class="list-group-item">' + devices[deviceId].name+'</a></li>').appendTo(
|
||||
$('#device-chooser'));
|
||||
});
|
||||
}
|
||||
|
||||
function updateBranchChooser(timeRange, deviceId, preferredTest) {
|
||||
$('#branch-chooser').empty();
|
||||
|
||||
var device = devices[deviceId];
|
||||
device.branches.forEach(function(branchId) {
|
||||
var testId = getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest);
|
||||
var defaultMeasureId = device[branchId].tests[testId].defaultMeasureId;
|
||||
|
||||
var url = "#/" + [ currentDashboardId, deviceId, branchId, testId, defaultMeasureId, timeRange ].join('/');
|
||||
$('<a href="' + url + '" id="branch-' + branchId + '" class="list-group-item">' + branchId +'</a></li>').appendTo(
|
||||
$('#branch-chooser'));
|
||||
});
|
||||
}
|
||||
|
||||
function updateDashboard(dashboardId, cb) {
|
||||
if (currentDashboardId === dashboardId) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
currentDashboardId = dashboardId;
|
||||
|
||||
$.getJSON(getResourceURL([dashboardId, 'devices.json'].join('/')), function(deviceData) {
|
||||
devices = deviceData['devices'];
|
||||
|
||||
deviceIds = Object.keys(devices).sort();
|
||||
|
||||
var deviceBranchPairs = [];
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
devices[deviceId].branches.forEach(function(branchId) {
|
||||
deviceBranchPairs.push([deviceId, branchId]);
|
||||
});
|
||||
});
|
||||
$.when.apply($, deviceBranchPairs.map(function(pair) {
|
||||
var deviceId = pair[0];
|
||||
var branchId = pair[1];
|
||||
|
||||
return $.getJSON(getResourceURL([dashboardId, deviceId, branchId,
|
||||
'tests.json'].join('/')),
|
||||
function(testData) {
|
||||
var tests = testData['tests'];
|
||||
if (!devices[deviceId][branchId]) {
|
||||
devices[deviceId][branchId] = {};
|
||||
}
|
||||
devices[deviceId][branchId]['tests'] = tests;
|
||||
});
|
||||
})).done(cb);
|
||||
});
|
||||
}
|
||||
|
||||
$.getJSON(getResourceURL('dashboard.json'), function(dashboardData) {
|
||||
dashboards = dashboardData.dashboards.sort(function(x, y) {
|
||||
return y.id < x.id;
|
||||
});
|
||||
|
||||
var routes = {
|
||||
'/:dashboardId': {
|
||||
on: function(dashboardId) {
|
||||
updateDashboard(dashboardId, function() {
|
||||
updateDashboardChooser();
|
||||
|
||||
var defaultDeviceId = deviceIds[0];
|
||||
var defaultBranchId = devices[defaultDeviceId].branches[0];
|
||||
var defaultTestId = Object.keys(devices[defaultDeviceId][defaultBranchId].tests).sort()[0];
|
||||
var defaultMeasureId = devices[defaultDeviceId][defaultBranchId].tests[defaultTestId].defaultMeasureId;
|
||||
var defaultTimeRange = 7;
|
||||
|
||||
window.location.hash = '/' + [ currentDashboardId, defaultDeviceId,
|
||||
defaultBranchId,
|
||||
defaultTestId,
|
||||
defaultMeasureId,
|
||||
defaultTimeRange ].join('/');
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
'/:dashboardId/:deviceId/:branchId/:testId/:measureId/:timeRange': {
|
||||
on: function(dashboardId, deviceId, branchId, testId, measureId, timeRange) {
|
||||
updateDashboard(dashboardId, function() {
|
||||
updateDashboardChooser();
|
||||
|
||||
function updateDeviceChooser(timeRange, preferredBranchId, preferredTest) {
|
||||
$('#device-chooser').empty();
|
||||
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
var device = devices[deviceId];
|
||||
|
||||
var branchId;
|
||||
if (preferredBranchId && device.branches.indexOf(preferredBranchId) >= 0) {
|
||||
branchId = preferredBranchId;
|
||||
} else {
|
||||
branchId = device.branches.sort()[0];
|
||||
}
|
||||
|
||||
var testId = getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest);
|
||||
var defaultMeasureId = device[branchId].tests[testId].defaultMeasureId;
|
||||
|
||||
var deviceURL = "#/" + [ deviceId, branchId, testId, defaultMeasureId, timeRange ].join('/');
|
||||
$('<a href="' + deviceURL + '" id="device-' + deviceId + '" deviceid= ' + deviceId + ' class="list-group-item">' + devices[deviceId].name+'</a></li>').appendTo(
|
||||
$('#device-chooser'));
|
||||
});
|
||||
}
|
||||
|
||||
function updateBranchChooser(timeRange, deviceId, preferredTest) {
|
||||
$('#branch-chooser').empty();
|
||||
|
||||
var device = devices[deviceId];
|
||||
device.branches.forEach(function(branchId) {
|
||||
var testId = getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest);
|
||||
var defaultMeasureId = device[branchId].tests[testId].defaultMeasureId;
|
||||
|
||||
var url = "#/" + [ deviceId, branchId, testId, defaultMeasureId, timeRange ].join('/');
|
||||
$('<a href="' + url + '" id="branch-' + branchId + '" class="list-group-item">' + branchId +'</a></li>').appendTo(
|
||||
$('#branch-chooser'));
|
||||
});
|
||||
}
|
||||
|
||||
var currentBranchId = null;
|
||||
var currentDeviceId = null;
|
||||
var currentTestId = null;
|
||||
|
||||
var routes = {
|
||||
'/:deviceId/:branchId/:testId/:measureId/:timeRange': {
|
||||
on: function(deviceId, branchId, testId, measureId, timeRange) {
|
||||
if (!devices[deviceId] || !devices[deviceId][branchId] || !devices[deviceId][branchId]['tests'][testId]) {
|
||||
$('#data-view').html("<p class='lead'>That device/branch/test/measure combination does not seem to exist. Maybe you're using an expired link? <a href=''>Reload page</a>?</p>");
|
||||
return;
|
||||
|
@ -481,8 +528,9 @@ $(function() {
|
|||
if (testIdAttr) {
|
||||
var defaultMeasureId = tests[testIdAttr].defaultMeasureId;
|
||||
$(this).attr('href', '#/' +
|
||||
[ deviceId, branchId, testIdAttr,
|
||||
defaultMeasureId, timeRange ].join('/'));
|
||||
[ currentDashboardId, deviceId, branchId,
|
||||
testIdAttr, defaultMeasureId,
|
||||
timeRange ].join('/'));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -493,34 +541,24 @@ $(function() {
|
|||
|
||||
var testInfo = tests[testId];
|
||||
updateFooter();
|
||||
updateContent(testInfo, deviceId, branchId, testId, measureId, timeRange);
|
||||
}
|
||||
updateContent(testInfo, dashboardId, deviceId, branchId, testId,
|
||||
measureId, timeRange);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var defaultDeviceId = deviceIds[0];
|
||||
var defaultBranchId = devices[defaultDeviceId].branches[0];
|
||||
var defaultTestId = Object.keys(devices[defaultDeviceId][defaultBranchId].tests).sort()[0];
|
||||
var defaultMeasureId = devices[defaultDeviceId][defaultBranchId].tests[defaultTestId].defaultMeasureId;
|
||||
var defaultTimeRange = 7;
|
||||
|
||||
var defaultRouteHash = '/' + [ defaultDeviceId,
|
||||
defaultBranchId,
|
||||
defaultTestId,
|
||||
defaultMeasureId,
|
||||
defaultTimeRange ].join('/');
|
||||
|
||||
var router = Router(routes).configure({
|
||||
'notfound': function() {
|
||||
$('#data-view').html(ich.noGraph({
|
||||
"title": "Invalid URL",
|
||||
"errorReason": "Invalid or expired route (probably due to a " +
|
||||
"change in Eideticker). Try selecting a valid combination " +
|
||||
"from the menu on the left."
|
||||
}));
|
||||
}
|
||||
});
|
||||
router.init(defaultRouteHash);
|
||||
var router = Router(routes).configure({
|
||||
'notfound': function() {
|
||||
$('#data-view').html(ich.noGraph({
|
||||
"title": "Invalid URL",
|
||||
"errorReason": "Invalid or expired route (probably due to a " +
|
||||
"change in Eideticker). Try selecting a valid combination " +
|
||||
"from the menu on the left."
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
router.init('/'+ dashboards[0].id);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from dashboard import add_dashboard_options, copy_dashboard_files, update_dashboard_device_list, update_dashboard_test_list, update_dashboard_testdata, upload_dashboard
|
||||
from dashboard import add_dashboard_options, copy_dashboard_files, update_dashboard_list, update_dashboard_device_list, update_dashboard_test_list, update_dashboard_testdata, upload_dashboard
|
||||
from runner import AndroidBrowserRunner
|
||||
from options import OptionParser, CaptureOptionParser, TestOptionParser
|
||||
from device import getDevicePrefs, getDevice
|
||||
|
|
|
@ -68,9 +68,33 @@ def copy_dashboard_files(dashboard_dir, indexfile='index.html'):
|
|||
os.remove(dest)
|
||||
shutil.copyfile(source, dest)
|
||||
|
||||
def update_dashboard_device_list(dashboard_dir, device_id, branch_id, device_info):
|
||||
def update_dashboard_list(dashboard_dir, dashboard_id, dashboard_name):
|
||||
dashboards = []
|
||||
dashboard_filename = os.path.join(dashboard_dir, 'dashboard.json')
|
||||
if os.path.isfile(dashboard_filename):
|
||||
dashboards = json.loads(open(dashboard_filename).read())['dashboards']
|
||||
|
||||
found_dashboard = False
|
||||
for dashboard in dashboards:
|
||||
if dashboard['id'] == dashboard_id:
|
||||
dashboard['name'] = dashboard_name
|
||||
found_dashboard = True
|
||||
|
||||
if not found_dashboard:
|
||||
dashboards.append({'id': dashboard_id, 'name': dashboard_name})
|
||||
|
||||
with open(dashboard_filename, 'w') as f:
|
||||
f.write(json.dumps({'dashboards': dashboards}))
|
||||
|
||||
def update_dashboard_device_list(dashboard_dir, dashboard_id, device_id, branch_id,
|
||||
device_info):
|
||||
devices = {}
|
||||
device_filename = os.path.join(dashboard_dir, 'devices.json')
|
||||
|
||||
device_dirname = os.path.join(dashboard_dir, dashboard_id)
|
||||
if not os.path.exists(device_dirname):
|
||||
os.makedirs(device_dirname)
|
||||
|
||||
device_filename = os.path.join(device_dirname, 'devices.json')
|
||||
if os.path.isfile(device_filename):
|
||||
devices = json.loads(open(device_filename).read())['devices']
|
||||
|
||||
|
@ -85,8 +109,8 @@ def update_dashboard_device_list(dashboard_dir, device_id, branch_id, device_inf
|
|||
with open(device_filename, 'w') as f:
|
||||
f.write(json.dumps({'devices': devices}))
|
||||
|
||||
def update_dashboard_test_list(dashboard_dir, device_id, branch_id, testinfo):
|
||||
testsdirname = os.path.join(dashboard_dir, device_id, branch_id)
|
||||
def update_dashboard_test_list(dashboard_dir, dashboard_id, device_id, branch_id, testinfo):
|
||||
testsdirname = os.path.join(dashboard_dir, dashboard_id, device_id, branch_id)
|
||||
if not os.path.exists(testsdirname):
|
||||
os.makedirs(testsdirname)
|
||||
|
||||
|
@ -105,10 +129,11 @@ def update_dashboard_test_list(dashboard_dir, device_id, branch_id, testinfo):
|
|||
'lastUpdated': update_timestamp,
|
||||
'tests': tests}))
|
||||
|
||||
def update_dashboard_testdata(dashboard_dir, device_id, branch_id, testinfo,
|
||||
productname, productdate, datapoint, metadata):
|
||||
def update_dashboard_testdata(dashboard_dir, dashboard_id, device_id,
|
||||
branch_id, testinfo, productname, productdate,
|
||||
datapoint, metadata):
|
||||
# get existing data
|
||||
fname = os.path.join(dashboard_dir, device_id, branch_id,
|
||||
fname = os.path.join(dashboard_dir, dashboard_id, device_id, branch_id,
|
||||
'%s.json' % testinfo['key'])
|
||||
testdata = NestedDict()
|
||||
if os.path.isfile(fname):
|
||||
|
|
Загрузка…
Ссылка в новой задаче