xref: /dragonfly/usr.bin/dsynth/progress.js (revision d50f9ae3)
1/*
2 * Copyright (c) 2015-2017, John R. Marino <draco@marino.st>
3 *
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.
7 *
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.
15 */
16var SbInterval = 10;
17var progwidth = 950;
18var progheight = 14;
19var progtop    = 2;
20var run_active;
21var kfiles = 0;
22var last_kfile = 1;
23var history = [[]];
24
25/* Disabling jQuery caching */
26$.ajaxSetup({
27	cache: false
28});
29
30function catwidth (variable, queued) {
31	if (variable == 0)
32		return 0;
33	var width = variable * progwidth / queued;
34	return (width < 1) ? 1 : Math.round (width);
35}
36
37function 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]);
45}
46
47function minidraw(x, context, color, queued, variable, mcw) {
48	var width = catwidth (variable, queued);
49	if (width == 0)
50		return (0);
51	if (width > mcw)
52		width = mcw;
53	context.fillStyle = color;
54	context.fillRect(x, progtop + 1, width, progheight + 2);
55	return (width);
56}
57
58function update_canvas(stats) {
59	var queued = stats.queued;
60	var built = stats.built;
61	var failed = stats.failed;
62	var skipped = stats.skipped;
63	var ignored = stats.ignored;
64
65	var canvas = document.getElementById('progressbar');
66	if (canvas.getContext === undefined) {
67		/* Not supported */
68		return;
69	}
70
71	var context = canvas.getContext('2d');
72
73	context.fillStyle = '#D8D8D8';
74	context.fillRect(0, progtop + 1, progwidth, progheight + 2);
75	var x = 0;
76	var mcw = maxcatwidth (built, failed, ignored, skipped, queued);
77	x += minidraw(x, context, "#339966", queued, built, mcw);
78	x += minidraw(x, context, "#CC0033", queued, failed, mcw);
79	x += minidraw(x, context, "#FFCC33", queued, ignored, mcw);
80	x += minidraw(x, context, "#CC6633", queued, skipped, mcw);
81}
82
83function filter (txt) {
84	$('#report input').val (txt).trigger('search');
85}
86
87function process_summary(data) {
88	var html;
89	var RB = '<tr>';
90	var RE = '</tr>';
91	var B = '<td>';
92	var E = '</td>';
93
94	kfiles = parseInt (data.kfiles);
95	run_active = parseInt (data.active);
96	$('#profile').html(data.profile);
97	$('#kickoff').html(data.kickoff);
98	$('#polling').html(run_active ? "Active" : "Complete");
99	if (data.stats) {
100		$.each(data.stats, function(status, count) {
101			html = count;
102			$('#stats_' + status).html(html);
103		});
104		update_canvas (data.stats);
105	}
106
107	$('#builders_body tbody').empty();
108	for (n = 0; n < data.builders.length; n++) {
109		var trow = RB + '<td class="b' + data.builders[n].ID +
110			'" onclick="filter(\'[' + data.builders[n].ID +
111			']\')" title="Click to filter for work done by builder ' +
112			data.builders[n].ID + '">'
113			  + data.builders[n].ID + E +
114			B + data.builders[n].elapsed + E +
115			B + data.builders[n].phase + E +
116			B + data.builders[n].origin + E +
117			B + data.builders[n].lines + E +
118			RE;
119		$('#builders_body tbody').append (trow);
120	}
121}
122
123function digit2(n){
124	return n > 9 ? "" + n: "0" + n;
125}
126
127function logfile (origin) {
128	var parts = origin.split('/');
129	return '../' + parts[0] + '___' + parts[1] + '.log';
130}
131
132function format_result (result) {
133	return '<div class="' + result + ' result">' + result + '<div>';
134}
135
136function format_entry (entry, origin) {
137	return '<span class="entry" onclick="filter(\'' + origin+ '\')">' +
138		entry + '</span>';
139}
140
141function information (result, origin, info) {
142	var parts;
143	if (result == "built") {
144		return '<a href="' + logfile (origin) + '">logfile</a>';
145	} else if (result == "failed") {
146		parts = info.split(':');
147		return 'Failed ' + parts[0] + ' phase (<a href="' + logfile (origin) +
148			'">logfile</a>)';
149	} else if (result == "skipped") {
150		return 'Issue with ' + info;
151	} else if (result == "ignored") {
152		parts = info.split(':|:');
153		return parts[0];
154	} else {
155		return "??";
156	}
157}
158
159function skip_info (result, info) {
160	var parts;
161	if (result == "failed") {
162		parts = info.split(':');
163		return parts[1];
164	} else if (result == "ignored") {
165		parts = info.split(':|:');
166		return parts[1];
167	} else {
168		return "";
169	}
170}
171
172function portsmon (origin) {
173	var parts = origin.split('/');
174	var FPClink = '<a title="portsmon for "' + origin + '" href="http://portsmon.freebsd.org/portoverview.py?category=' + parts[0] + '&portname=' + parts[1] + '">' + origin + '</a>';
175	var NPSlink = '<a title="pkgsrc.se overview" href="http://pkgsrc.se/' + origin + '">' + origin + '</a>';
176	return FPClink;
177}
178
179function process_history_file(data, k) {
180	history [k] = [];
181	for (n = 0; n < data.length; n++) {
182		var trow = [];
183		trow.push(format_entry (data[n].entry, data[n].origin));
184		trow.push(data[n].elapsed);
185		trow.push('[' + data[n].ID + ']');
186		trow.push(format_result (data[n].result));
187		trow.push(portsmon (data[n].origin));
188		trow.push(information (data[n].result, data[n].origin, data[n].info));
189		trow.push(skip_info (data[n].result, data[n].info));
190		trow.push(data[n].duration);
191		history [k].push (trow);
192	}
193}
194
195function cycle () {
196	if (run_active) {
197		setTimeout(update_summary_and_builders, SbInterval * 1000);
198	} else {
199		$('#builders_zone_2').fadeOut(2500);
200		$('#main').css('border-top', '1px solid #404066');
201	}
202}
203
204function update_history_success(kfile) {
205	if (kfile == kfiles) {
206		var full_history = [];
207		for (var k = 1; k <= kfiles; k++) {
208			full_history = full_history.concat (history[k]);
209		}
210		$('#report_table').dataTable().fnClearTable();
211		$('#report_table').dataTable().fnAddData(full_history);
212		cycle();
213	} else {
214		last_kfile = kfile + 1;
215		update_history();
216	}
217}
218
219function update_history() {
220	if (kfiles == 0) {
221		cycle();
222		return;
223	}
224	clearInterval(update_history);
225	$.ajax({
226		url: digit2(last_kfile) + '_history.json',
227		dataType: 'json',
228		success: function(data) {
229			process_history_file(data, last_kfile);
230			update_history_success (last_kfile);
231		},
232		error: function(data) {
233			/* May not be there yet, try again shortly */
234			setTimeout(update_history, SbInterval * 500);
235		}
236	})
237}
238
239function update_summary_and_builders() {
240	$.ajax({
241		url: 'summary.json',
242		dataType: 'json',
243		success: function(data) {
244			process_summary(data);
245			clearInterval(update_summary_and_builders);
246			update_history();
247		},
248		error: function(data) {
249			/* May not be there yet, try again shortly */
250			setTimeout(update_summary_and_builders, SbInterval * 500);
251		}
252	});
253}
254
255$(document).ready(function() {
256
257	$('#report_table').dataTable({
258		"aaSorting": [[ 0, 'desc' ]],
259		"bProcessing": true, // Show processing icon
260		"bDeferRender": true, // Defer creating TR/TD until needed
261		"aoColumnDefs": [
262			{"bSortable": false, "aTargets": [1,2,3,5]},
263			{"bSearchable": false, "aTargets": [0,1,6,7]},
264		],
265		"bStateSave": true, // Enable cookie for keeping state
266		"aLengthMenu":[10,20,50, 100, 200],
267		"iDisplayLength": 20,
268		});
269
270	update_summary_and_builders();
271})
272
273$(document).bind("keydown", function(e) {
274  /* Disable F5 refreshing since this is AJAX driven. */
275  if (e.which == 116) {
276    e.preventDefault();
277  }
278});
279