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