From: Dylan William Hardison
Date: Thu, 18 Apr 2019 19:09:12 +0000 (-0400)
Subject: Bug 1545295 - socorro lens chart for crash statistics blocked by CSP (Blocked by...
X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f52c891fd2d16e0d286eefcb6fecdf52e34daccc;p=thirdparty%2Fbugzilla.git
Bug 1545295 - socorro lens chart for crash statistics blocked by CSP (Blocked by Content Security Policy)
---
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 476be3d96..802d8ceed 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -754,14 +754,18 @@ sub DEFAULT_CSP {
# This is from extensions/OrangeFactor/web/js/orange_factor.js
'https://treeherder.mozilla.org/api/failurecount/',
+
+ # socorro lens
+ 'https://crash-stats.mozilla.com/api/SuperSearch/',
],
+ font_src => [ 'self', 'https://fonts.gstatic.com' ],
form_action => [
'self',
# used in template/en/default/search/search-google.html.tmpl
'https://www.google.com/search'
],
- frame_ancestors => ['none'],
+ frame_ancestors => ['self'],
report_only => 1,
);
if (Bugzilla->params->{github_client_id} && !Bugzilla->user->id) {
diff --git a/public/metricsgraphics/css/custom.css b/public/metricsgraphics/css/custom.css
new file mode 100644
index 000000000..4c8a582ef
--- /dev/null
+++ b/public/metricsgraphics/css/custom.css
@@ -0,0 +1,4 @@
+div.chart svg {
+ margin-left: -20px;
+ margin-top: -40px;
+}
diff --git a/public/metricsgraphics/js/main.js b/public/metricsgraphics/js/main.js
index da317488c..61f3b8675 100644
--- a/public/metricsgraphics/js/main.js
+++ b/public/metricsgraphics/js/main.js
@@ -1,164 +1,363 @@
var theme = 'dark';
-(function() {
- 'use strict';
+(function () {
+ 'use strict';
- //set the active pill and section on first load
- var section = (document.location.hash) ? document.location.hash.slice(1) : 'signature_lookup';
+ //set the active pill and section on first load
+ var section = (document.location.hash) ? document.location.hash.slice(1) : 'signature_lookup';
- if (section.indexOf("bugzilla") != -1) {
- $('#trunk').load('charts/bugzilla/' + section + '.htm', function() {
- $('pre code').each(function(i, block) {
- hljs.highlightBlock(block);
+ if (section.indexOf("bugzilla") != -1) {
+ $('#trunk').load('charts/bugzilla/' + section + '.htm', function () {
+ $('pre code').each(function (i, block) {
+ hljs.highlightBlock(block);
+ });
+ });
+ } else {
+ if (section.indexOf("bz_signatures") != -1) {
+ $('#trunk').load('charts/bz_signatures.htm', function () {
+ $('pre code').each(function (i, block) {
+ hljs.highlightBlock(block);
});
});
} else {
- if (section.indexOf("bz_signatures") != -1) {
- $('#trunk').load('charts/bz_signatures.htm', function() {
- $('pre code').each(function(i, block) {
+ $('#trunk').load('charts/' + section + '.htm', function () {
+ $('pre code').each(function (i, block) {
+ hljs.highlightBlock(block);
+ });
+ });
+ }
+ }
+
+ $('.menu a#goto-' + section).addClass('active');
+
+ //handle mouse clicks and so on
+ assignEventListeners();
+
+ function assignEventListeners() {
+ $('button.load').on('click', function (event) {
+ var metric = document.getElementById('select_metric').selectedOptions[0].value;
+ if (metric.indexOf('bugzilla') != -1) {
+ metric = 'bugzilla/' + metric;
+ }
+ var chart = 'charts/' + metric + '.htm';
+ $('#trunk').load(chart, function () {
+ $('pre code').each(function (i, block) {
+ hljs.highlightBlock(block);
+ });
+ });
+ })
+
+ $('a.pill').on('click', function (event) {
+ event.preventDefault();
+ $('a.pill').removeClass('active');
+ $(this).addClass('active');
+
+ var section = $(this).attr('id').slice(5);
+ if (section.indexOf("bugzilla") != -1) {
+ $('#trunk').load('charts/bugzilla/' + section + '.htm', function () {
+ $('pre code').each(function (i, block) {
hljs.highlightBlock(block);
});
});
} else {
- $('#trunk').load('charts/' + section + '.htm', function() {
- $('pre code').each(function(i, block) {
+ $('#trunk').load('charts/' + section + '.htm', function () {
+ $('pre code').each(function (i, block) {
hljs.highlightBlock(block);
});
});
}
- }
- $('.menu a#goto-' + section).addClass('active');
+ document.location.hash = section;
- //handle mouse clicks and so on
- assignEventListeners();
+ return false;
+ })
- function assignEventListeners() {
- $('button.load').on('click', function(event) {
- var metric = document.getElementById('select_metric').selectedOptions[0].value;
- if (metric.indexOf('bugzilla') != -1) {
- metric = 'bugzilla/' + metric;
- }
- var chart = 'charts/' + metric + '.htm';
- $('#trunk').load(chart, function() {
- $('pre code').each(function(i, block) {
- hljs.highlightBlock(block);
- });
- });
- })
-
- $('a.pill').on('click', function(event) {
- event.preventDefault();
- $('a.pill').removeClass('active');
- $(this).addClass('active');
-
- var section = $(this).attr('id').slice(5);
- if (section.indexOf("bugzilla") != -1) {
- $('#trunk').load('charts/bugzilla/' + section + '.htm', function() {
- $('pre code').each(function(i, block) {
- hljs.highlightBlock(block);
- });
- });
- } else {
- $('#trunk').load('charts/' + section + '.htm', function() {
- $('pre code').each(function(i, block) {
- hljs.highlightBlock(block);
- });
- });
- }
+ $('#dark-css').on('click', function () {
+ theme = 'dark';
- document.location.hash = section;
+ $('.missing')
+ .css('background-image', 'url(images/missing-data-dark.png)');
- return false;
- })
+ $('.wip')
+ .css('background-color', '#3b3b3b');
- $('#dark-css').on('click', function () {
- theme = 'dark';
+ $('.trunk-section')
+ .css('border-top-color', '#5e5e5e');
- $('.missing')
- .css('background-image', 'url(images/missing-data-dark.png)');
+ $('.mg-missing-background')
+ .css('stroke', '#ccc');
- $('.wip')
- .css('background-color', '#3b3b3b');
+ $('.head ul li a.pill').removeClass('active');
+ $(this).toggleClass('active');
+ $('#dark').attr({ href: 'css/metricsgraphics-demo-dark.css' });
+ $('#dark-code').attr({ href: 'css/railscasts.css' });
+ $('#accessible').attr({ href: '' });
- $('.trunk-section')
- .css('border-top-color', '#5e5e5e');
+ return false;
+ });
- $('.mg-missing-background')
- .css('stroke', '#ccc');
+ $('#light-css').on('click', function () {
+ theme = 'light';
- $('.head ul li a.pill').removeClass('active');
- $(this).toggleClass('active');
- $('#dark').attr({href : 'css/metricsgraphics-demo-dark.css'});
- $('#dark-code').attr({href : 'css/railscasts.css'});
- $('#accessible').attr({href : ''});
+ $('.missing')
+ .css('background-image', 'url(images/missing-data.png)');
- return false;
- });
+ $('.wip')
+ .css('background-color', '#f1f1f1');
- $('#light-css').on('click', function () {
- theme = 'light';
+ $('.trunk-section')
+ .css('border-top-color', '#ccc');
- $('.missing')
- .css('background-image', 'url(images/missing-data.png)');
+ $('.mg-missing-background')
+ .css('stroke', 'blue');
- $('.wip')
- .css('background-color', '#f1f1f1');
+ $('.head ul li a.pill').removeClass('active');
+ $(this).toggleClass('active');
+ $('#dark').attr({ href: '' });
+ $('#dark-code').attr({ href: '' });
+ $('#accessible').attr({ href: '' });
- $('.trunk-section')
- .css('border-top-color', '#ccc');
+ return false;
+ });
- $('.mg-missing-background')
- .css('stroke', 'blue');
- $('.head ul li a.pill').removeClass('active');
- $(this).toggleClass('active');
- $('#dark').attr({href : ''});
- $('#dark-code').attr({href : ''});
- $('#accessible').attr({href : ''});
- return false;
- });
+ $('#accessible-css').on('click', function () {
+ $('.head ul li a.pill').removeClass('active');
+ $(this).toggleClass('active');
+ $('#accessible').attr({ href: 'css/metricsgraphics-demo-accessible.css' });
+ return false;
+ });
+ }
+
+ // replace all SVG images with inline SVG
+ // http://stackoverflow.com/questions/11978995/how-to-change-color-of-svg
+ // -image-using-css-jquery-svg-image-replacement
+ $('img.svg').each(function () {
+ var $img = jQuery(this);
+ var imgID = $img.attr('id');
+ var imgClass = $img.attr('class');
+ var imgURL = $img.attr('src');
+
+ $.get(imgURL, function (data) {
+ // Get the SVG tag, ignore the rest
+ var $svg = jQuery(data).find('svg');
+
+ // Add replaced image's ID to the new SVG
+ if (typeof imgID !== 'undefined') {
+ $svg = $svg.attr('id', imgID);
+ }
+ // Add replaced image's classes to the new SVG
+ if (typeof imgClass !== 'undefined') {
+ $svg = $svg.attr('class', imgClass + ' replaced-svg');
+ }
+ // Remove any invalid XML tags as per http://validator.w3.org
+ $svg = $svg.removeAttr('xmlns:a');
- $('#accessible-css').on('click', function () {
- $('.head ul li a.pill').removeClass('active');
- $(this).toggleClass('active');
- $('#accessible').attr({href : 'css/metricsgraphics-demo-accessible.css'});
+ // Replace image with new SVG
+ $img.replaceWith($svg);
- return false;
- });
- }
+ }, 'xml');
+ });
+})();
- // replace all SVG images with inline SVG
- // http://stackoverflow.com/questions/11978995/how-to-change-color-of-svg
- // -image-using-css-jquery-svg-image-replacement
- $('img.svg').each(function() {
- var $img = jQuery(this);
- var imgID = $img.attr('id');
- var imgClass = $img.attr('class');
- var imgURL = $img.attr('src');
-
- $.get(imgURL, function(data) {
- // Get the SVG tag, ignore the rest
- var $svg = jQuery(data).find('svg');
-
- // Add replaced image's ID to the new SVG
- if (typeof imgID !== 'undefined') {
- $svg = $svg.attr('id', imgID);
- }
- // Add replaced image's classes to the new SVG
- if (typeof imgClass !== 'undefined') {
- $svg = $svg.attr('class', imgClass + ' replaced-svg');
+document.addEventListener('DOMContentLoaded', function () {
+ document.querySelector('select[name="channel"]').onchange = channelEventHandler;
+ document.querySelector('select[name="match"]').onchange = matchEventHandler;
+ document.querySelector('button[name="zoom"]').onclick = zoomEventHandler;
+ loadGraph(window.location.search);
+}, false);
+
+function channelEventHandler(event) {
+ redraw(event.target.value);
+}
+
+function matchEventHandler(event) {
+ loadGraph(window.location.search, event.target.value);
+}
+
+function zoomEventHandler(event) {
+ var zoom_button = document.getElementById('zoom');
+ var container = window.parent.document.getElementById('chart');
+
+ if (event.target.textContent == '+') {
+ zoom_button.innerHTML = '-';
+ zoom_button.title = 'Zoom Out';
+ container.style.transform = 'scale(2,2)';
+ } else if (event.target.textContent == '-') {
+ zoom_button.innerHTML = '+';
+ zoom_button.title = 'Zoom In';
+ container.style.transform = 'scale(1,1)';
+ }
+}
+
+var items = [];
+var end_date = convertDate(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 1));
+var start_date = convertDate(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 180));
+var globals = {
+ "url_base": "https://crash-stats.mozilla.com/search/?",
+ "url": [],
+ "mouseover": function (d) {
+ var next = new Date(d.date.valueOf() + 1 * 24 * 60 * 60 * 1000);
+ d3.select('svg .mg-active-datapoint').text();
+ $.each(globals.url, function (i) {
+ if (globals.url[i].indexOf("&date=>%3D") !== -1) {
+ globals.url[i] = globals.url[i].substring(0, globals.url[i].indexOf("&date=>%3D"));
+ }
+ globals.url[i] = globals.url[i] + "&date=>%3D" + convertDate(d.date) + "&date=%3C" + convertDate(next);
+ globals.url[i] = globals.url[i].replace("/?&signature", "/?signature");
+ });
+ document.getElementById('chart').title = "Click to show reports for " + convertDate(d.date);
+ }
+};
+
+function convertDate(d) {
+ var day = (d.getDate() < 10) ? '0' + d.getDate().toString() : d.getDate().toString();
+ var month = ((d.getMonth() + 1) < 10) ? '0' + (d.getMonth() + 1).toString() : (d.getMonth() + 1).toString();
+ var year = d.getFullYear().toString();
+ return year + '-' + month + '-' + day;
+}
+
+function getSignaturesFromURL(search, match) {
+ var index = search.indexOf("?s=");
+ search = search.substring(index + 3).replace(/\+/g, '%20');
+ var signatures = [];
+ if (search.indexOf("\\") !== -1) {
+ signatures = search.split("\\");
+ } else if (search.indexOf("%5C") !== -1) {
+ signatures = search.split("%5C");
+ } else {
+ signatures = [search];
+ }
+ var result = [""];
+ var j = 0;
+ $.each(signatures, function (i) {
+ if (result[j].length > 500) result[++j] = "";
+ if (signatures[i] != "") {
+ if (match == "exact") {
+ result[j] = result[j] + "&signature=%3D" + signatures[i]
+ } else {
+ result[j] = result[j] + "&signature=~" + signatures[i]
+ }
+ }
+ });
+ return result;
+}
+
+function draw() {
+ var channel = document.querySelector('select[name="channel"]').selectedOptions[0].value;
+ items = MG.convert.date(items, 'date');
+ MG.data_graphic({
+ data: items,
+ width: 300,
+ height: 170,
+ target: document.getElementById('chart'),
+ x_accessor: 'date',
+ y_accessor: channel,
+ yax_count: 3,
+ chart_type: "line",
+ mouseover: globals.mouseover
+ });
+ if (globals.url.length > 1) {
+ var target = document.getElementById('warn');
+ target.style.visibility = "visible";
+ target.innerHTML = "Report will open " + globals.url.length + " tabs
";
+ }
+ var mouseouts = d3.selectAll('.mg-rollover-rect rect').on('mouseout');
+ d3.selectAll('.mg-rollover-rect rect').on('click', function (d) {
+ $.each(globals.url, function (i) {
+ window.open(globals.url[i], '_blank');
+ });
+ });
+}
+
+function redraw(channel) {
+ MG.data_graphic({
+ data: items,
+ width: 300,
+ height: 170,
+ target: document.getElementById('chart'),
+ x_accessor: 'date',
+ y_accessor: channel,
+ yax_count: 3,
+ chart_type: "line",
+ mouseover: globals.mouseover
+ });
+
+ if (globals.url.length > 1) {
+ var target = document.getElementById('warn');
+ target.style.visibility = "visible";
+ target.innerHTML = "[!] Report will open " + globals.url.length + " tabs due to signature length.";
+ }
+
+ var mouseouts = d3.selectAll('.mg-rollover-rect rect').on('mouseout');
+ d3.selectAll('.mg-rollover-rect rect').on('click', function (d) {
+ $.each(globals.url, function (i) {
+ window.open(globals.url[i], '_blank');
+ });
+ });
+}
+
+function loadGraph(search, match = 'exact') {
+ // Get all signatures from the Bugzilla page
+ var signatures = getSignaturesFromURL(search, match);
+ // Initialize chart data
+ items = [];
+ for (var i = 1; i < 181; i++) {
+ items.push({
+ "date": convertDate(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * i)),
+ "release": 0,
+ "beta": 0,
+ "nightly": 0,
+ "esr": 0,
+ "all": 0
+ });
+ }
+
+ // Process the Socorro data
+ if (items.length >= 180) {
+ var processed = [0, 0];
+ var processed_groups = 0;
+ $.each(signatures, function (i) {
+ var processed_data = 0;
+ // Set the report URL, this will be used to load the data report on click
+ if (!globals.url[i]) globals.url[i] = "";
+ globals.url[i] = globals.url_base + signatures[i];
+ // Iterate through the Socorro data and create the chart data object
+ var url = "https://crash-stats.mozilla.com/api/SuperSearch/?" + signatures[i] + "&date=%3E%3D" + start_date + "&date=%3C%3D" + end_date + "&_histogram.date=release_channel&_histogram_interval=1d&_results_number=0";
+ url = url.replace("/?&signature", "/?signature");
+ d3.json(url, function (data) {
+ if (data.total > 0) {
+ $.each(data, function (key, value) {
+ if (key == "facets") {
+ var histogram_date = value.histogram_date;
+ processed[1] = processed[1] + (histogram_date.length - 1);
+ $.each(histogram_date, function (key, value) {
+ for (var j = 0; j < items.length; j++) {
+ if (items[j].date == value.term.substring(0, 10)) {
+ var channels = value.facets.release_channel;
+ $.each(value.facets.release_channel, function (channel_index, channel_data) {
+ if (Object.keys(items[j]).includes(channel_data.term)) {
+ items[j][channel_data.term] += channel_data.count;
+ }
+ });
+
+ items[j].all += value.count;
+ }
+ }
+ processed_data = processed_data + 1;
+ if (processed_data >= histogram_date.length) processed_groups = processed_groups + 1;
+ if (processed_groups >= signatures.length) draw();
+ });
}
-
- // Remove any invalid XML tags as per http://validator.w3.org
- $svg = $svg.removeAttr('xmlns:a');
-
- // Replace image with new SVG
- $img.replaceWith($svg);
-
- }, 'xml');
+ });
+ } else {
+ processed_groups += 1;
+ if (processed_groups >= signatures.length) draw();
+ }
+ });
});
-})();
+ }
+}
diff --git a/public/metricsgraphics/socorro-lens.html b/public/metricsgraphics/socorro-lens.html
index f0c226361..c79b30aa6 100644
--- a/public/metricsgraphics/socorro-lens.html
+++ b/public/metricsgraphics/socorro-lens.html
@@ -1,25 +1,19 @@
-
+
-
-
+
-
+
@@ -36,205 +30,5 @@
-
-