2 * Copyright (c) 2015-2017, John R. Marino <draco@marino.st>
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 /* Disabling jQuery caching */
30 function catwidth (variable, queued) {
33 var width = variable * progwidth / queued;
34 return (width < 1) ? 1 : Math.round (width);
37 function maxcatwidth(A, B, C, D, queued) {
38 var cat = new Array();
39 cat[0] = catwidth (A, queued);
40 cat[1] = catwidth (B, queued);
41 cat[2] = catwidth (C, queued);
42 cat[3] = catwidth (D, queued);
43 cat.sort(function(a,b){return a-b});
44 return (progwidth - cat[0] - cat[1] - cat[2]);
47 function minidraw(x, context, color, queued, variable, mcw) {
48 var width = catwidth (variable, queued);
53 context.fillStyle = color;
54 context.fillRect(x, progtop + 1, width, progheight + 2);
58 function update_canvas(stats) {
59 var queued = stats.queued;
60 var built = stats.built;
61 var meta = stats.meta;
62 var failed = stats.failed;
63 var skipped = stats.skipped;
64 var ignored = stats.ignored;
66 var canvas = document.getElementById('progressbar');
67 if (canvas.getContext === undefined) {
72 var context = canvas.getContext('2d');
74 context.fillStyle = '#D8D8D8';
75 context.fillRect(0, progtop + 1, progwidth, progheight + 2);
77 var mcw = maxcatwidth (built, meta, failed, ignored, skipped, queued);
78 x += minidraw(x, context, "#339966", queued, built, mcw);
79 x += minidraw(x, context, "#A577E1", queued, meta, mcw);
80 x += minidraw(x, context, "#CC0033", queued, failed, mcw);
81 x += minidraw(x, context, "#FFCC33", queued, ignored, mcw);
82 x += minidraw(x, context, "#CC6633", queued, skipped, mcw);
85 function filter (txt) {
86 $('#report input').val (txt).trigger('search');
89 function process_summary(data) {
96 kfiles = parseInt (data.kfiles);
97 run_active = parseInt (data.active);
98 $('#profile').html(data.profile);
99 $('#kickoff').html(data.kickoff);
100 $('#polling').html(run_active ? "Active" : "Complete");
102 $.each(data.stats, function(status, count) {
104 $('#stats_' + status).html(html);
106 update_canvas (data.stats);
109 $('#builders_body tbody').empty();
110 for (n = 0; n < data.builders.length; n++) {
111 var trow = RB + '<td class="b' + data.builders[n].ID +
112 '" onclick="filter(\'[' + data.builders[n].ID +
113 ']\')" title="Click to filter for work done by builder ' +
114 data.builders[n].ID + '">'
115 + data.builders[n].ID + E +
116 B + data.builders[n].elapsed + E +
117 B + data.builders[n].phase + E +
118 B + data.builders[n].origin + E +
119 B + data.builders[n].lines + E +
121 $('#builders_body tbody').append (trow);
126 return n > 9 ? "" + n: "0" + n;
129 function logfile (origin) {
130 var parts = origin.split('/');
131 return '../' + parts[0] + '___' + parts[1] + '.log';
134 function format_result (result) {
135 return '<div class="' + result + ' result">' + result + '<div>';
138 function format_entry (entry, origin) {
139 return '<span class="entry" onclick="filter(\'' + origin+ '\')">' +
143 function information (result, origin, info) {
145 if (result == "meta") {
146 return 'meta-node complete.';
147 } else if (result == "built") {
148 return '<a href="' + logfile (origin) + '">logfile</a>';
149 } else if (result == "failed") {
150 parts = info.split(':');
151 return 'Failed ' + parts[0] + ' phase (<a href="' + logfile (origin) +
153 } else if (result == "skipped") {
154 return 'Issue with ' + info;
155 } else if (result == "ignored") {
156 parts = info.split(':|:');
163 function skip_info (result, info) {
165 if (result == "failed") {
166 parts = info.split(':');
168 } else if (result == "ignored") {
169 parts = info.split(':|:');
176 function portsmon (origin) {
177 var portparts = origin.split('/');
178 var nameparts = portparts[1].split('@');
179 var FPClink = '<a title="portsmon for "' + origin + '" href="https://www.freshports.org/' + portparts[0] + '/' + nameparts[0] + '">' + origin + '</a>';
180 var NPSlink = '<a title="pkgsrc.se overview" href="http://pkgsrc.se/' + origin + '">' + origin + '</a>';
184 function process_history_file(data, k) {
186 for (n = 0; n < data.length; n++) {
188 trow.push(format_entry (data[n].entry, data[n].origin));
189 trow.push(data[n].elapsed);
190 trow.push('[' + data[n].ID + ']');
191 trow.push(format_result (data[n].result));
192 trow.push(portsmon (data[n].origin));
193 trow.push(information (data[n].result, data[n].origin, data[n].info));
194 trow.push(skip_info (data[n].result, data[n].info));
195 trow.push(data[n].duration);
196 history [k].push (trow);
202 setTimeout(update_summary_and_builders, SbInterval * 1000);
204 $('#builders_zone_2').fadeOut(2500);
205 $('#main').css('border-top', '1px solid #404066');
209 function update_history_success(kfile) {
210 if (kfile == kfiles) {
211 var full_history = [];
212 for (var k = 1; k <= kfiles; k++) {
213 full_history = full_history.concat (history[k]);
215 $('#report_table').dataTable().fnClearTable();
216 $('#report_table').dataTable().fnAddData(full_history);
219 last_kfile = kfile + 1;
224 function update_history() {
229 clearInterval(update_history);
231 url: digit2(last_kfile) + '_history.json',
233 success: function(data) {
234 process_history_file(data, last_kfile);
235 update_history_success (last_kfile);
237 error: function(data) {
238 /* May not be there yet, try again shortly */
239 setTimeout(update_history, SbInterval * 500);
244 function update_summary_and_builders() {
248 success: function(data) {
249 process_summary(data);
250 clearInterval(update_summary_and_builders);
253 error: function(data) {
254 /* May not be there yet, try again shortly */
255 setTimeout(update_summary_and_builders, SbInterval * 500);
260 $(document).ready(function() {
262 $('#report_table').dataTable({
263 "aaSorting": [[ 0, 'desc' ]],
264 "bProcessing": true, // Show processing icon
265 "bDeferRender": true, // Defer creating TR/TD until needed
267 {"bSortable": false, "aTargets": [1,2,3,5]},
268 {"bSearchable": false, "aTargets": [0,1,6,7]},
270 "bStateSave": true, // Enable cookie for keeping state
271 "aLengthMenu":[10,20,50, 100, 200],
272 "iDisplayLength": 20,
275 update_summary_and_builders();
278 $(document).bind("keydown", function(e) {
279 /* Disable F5 refreshing since this is AJAX driven. */
280 if (e.which == 116) {