1/* 2 * aegis - project change supervisor 3 * Copyright (C) 1998, 2002, 2003, 2005-2008 Peter Miller 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see 17 * <http://www.gnu.org/licenses/>. 18 */ 19 20auto pn, p; 21pn = project_name(); 22p = project[pn]; 23auto ps, cs; 24ps = p.state; 25auto ph, when, n, max, href; 26 27auto script_name; 28script_name = getenv("SCRIPT_NAME"); 29if (script_name == "") 30 script_name = "http://localhost/cgi-bin/aegis.cgi"; 31 32auto t, month, year; 33if (count(arg) > 0) 34 t = mktime(arg[0]); 35else 36 t = now(); 37month = 0 + strftime("%m", t); 38year = 0 + strftime("%Y", t); 39 40auto cmap; 41cmap = 42{ 43 chain = "255+0+0"; 44 internal_bug = "255+255+0"; 45 internal_enhancement = "0+255+0"; 46 internal_improvement = "0+255+255"; 47 external_bug = "192+192+0"; 48 external_enhancement = "0+192+0"; 49 external_improvement = "0+192+192"; 50}; 51 52columns({width = 1000; }); 53print("Content-Type: text/html"); 54print(""); 55print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"" 56 ## "\"http://www.w3.org/TR/REC-html40/loose.dtd\">"); 57print("<html><head>"); 58print("<meta name=\"ROBOTS\" content=\"NOINDEX, NOFOLLOW\">"); 59print("<meta name=\"GENERATOR\" content=\"" ## script_name ## "\">"); 60print("<meta http-equiv=\"Content-Type\" " 61 ## "content=\"text/html; charset=ISO-8859-1\">"); 62print("<style type=\"text/css\"> " 63 ## "tr.even-group { background-color: #CCCCCC; } " 64 ## "body { background-color: white; } " 65 ## "</style>"); 66/* 67 * Netscape 4.x has numerous CSS bugs, two of which need mentioning. 68 * 1. If a style sheet is not present Netscape says 404 Not found, when 69 * it should silently ignore it. 2. Style sheets who's media is not 70 * "screen" will be ignored. Fortunately we can use (2) to get around (1). 71 */ 72print("<link rel=\"stylesheet\" type=\"text/css\" href=\"/aedefault.css\" " 73 ## "media=\"all\">"); 74auto stack, depth, bn; 75depth=0; 76stack[depth] = project[pn].state.name; 77while ("" != ( bn = project[stack[depth]].state.parent_name )) { 78 stack[++depth] = bn; 79} 80while ( depth >= 0) { 81 print("<link rel=\"stylesheet\" type=\"text/css\" href=\"/" ## 82 stack[depth--] ## ".css\" " ## "media=\"all\">"); 83} 84print("<title>"); 85print("Project " ## quote_html(pn) ## ", Change Cause Histogram"); 86print("</title><head><body><h1 align=center>"); 87 88print("<a href=\"" ## script_name ## "\">Project</a>"); 89auto long_project_name; 90auto prj_name_parts; 91prj_name_parts = split(pn, '.'); 92href = script_name ## "?file@proj_menu+project@" 93 ## quote_url(prj_name_parts[0]); 94long_project_name = "<a href=\"" ## href ## "\" >" 95 ## quote_html(prj_name_parts[0]) ## "</a>"; 96auto j; 97for (j = 1; j < count(prj_name_parts); j++) 98{ 99 href ##= '.' ## prj_name_parts[j]; 100 long_project_name ##= ".<a href=\"" ## href ## "\" >" 101 ## quote_html(prj_name_parts[j]) ## "</a>"; 102}; 103long_project_name = "“" ## long_project_name ## "”,<br>"; 104/* HTTP limits lines to 510 characters */ 105for (j in wrap(long_project_name, 510)) 106 print(j); 107 108href = script_name ## "?file@proj_cch1+project@" ## quote_url(pn); 109print("Change Cause <a href=\"" ## href ## "\">Histogram</a><br>"); 110print(strftime("%B", t)); 111href = script_name ## "?file@proj_cch2+project@" ## quote_url(pn) 112 ## "+" ## year; 113print("<a href=\"" ## href ## "\">" ## strftime("%Y", t) ## "</a>"); 114print("</h1>"); 115print("<div class=\"information\">"); 116 117auto earliest_mday, latest_mday; 118 119auto bucket, mday, last_mday; 120bucket = {}; 121for (ph in ps.branch.history) 122{ 123 cs = ps.branch.change[ph.change_number]; 124 when = cs.history[count(cs.history) - 1].when; 125 if (year != 0 + strftime("%Y", when)) 126 continue; 127 if (month != 0 + strftime("%m", when)) 128 continue; 129 mday = 0 + strftime("%d", when); 130 if (typeof(bucket[mday]) == "nul") 131 bucket[mday] = {}; 132 bucket[mday][cs.cause]++; 133 bucket[mday].Total++; 134} 135 136max = 1; 137for (mday in keys(bucket)) 138{ 139 n = 0 + bucket[mday].Total; 140 if (n > max) 141 max = n; 142} 143max = 400. / max; 144 145last_mday = 28; 146for (n = 28; n < 32; ++n) 147{ 148 when = mktime(strftime("1-%b-%Y 00:00:00", t)); 149 when += (n - 1) * (24 * 60 * 60); 150 if (strftime("%m", when) + 0 != month) 151 break; 152 last_mday = n; 153} 154 155auto clr; 156print("<table align=center>"); 157print("<tr><th>Day</th><th>Count</th></tr>"); 158for (mday = 1; mday <= last_mday; ++mday) 159{ 160 if (typeof(bucket[mday]) == "nul") 161 bucket[mday] = {}; 162 n = 0 + bucket[mday].Total; 163 print("<tr><td valign=top align=right>"); 164 print(mday); 165 print("</td><td valign=top align=right>"); 166 print(n); 167 print("</td><td valign=top>"); 168 auto cause; 169 for (cause in [chain, 170 internal_bug, internal_enhancement, internal_improvement, 171 external_bug, external_enhancement, external_improvement]) 172 { 173 n = 0 + bucket[mday][cause]; 174 if (n > 0) 175 { 176 clr = cmap[cause]; 177 n = round(n * max); 178 if (n < 3) 179 n = 3; 180 href = script_name ## "?file@rect+" ## n ## "+12"; 181 href ##= "+color+" ## clr; 182 print("<img src=\"" ## href ## "\" width="##n## " height=12>"); 183 } 184 } 185 print("</td></tr>"); 186} 187print("</table>"); 188print("</div>"); 189print("<hr>"); 190 191print("<div class=\"legend\">"); 192print("<h2 align=center>Legend</h2>"); 193print("This table associates each color in the above graph with"); 194print("a change cause. A brief description of each cause is"); 195print("also given."); 196print("<table align=center>"); 197print("<tr><th>Color</th><th>Cause</th><th>Description</th></tr>"); 198 199clr = cmap[chain]; 200href = script_name ## "?file@rect+50+12+color+" ## clr; 201print("<tr><td valign=top>"); 202print("<img src=\""##href##"\" width=50 height=12>"); 203print("</td><td valign=top align=center>"); 204print("chain"); 205print("</td><td valign=top>"); 206print("This cause is used for bugs introduced by previous changes."); 207print("This is a special case of the <dfn>internal_bug</dfn> cause."); 208print("</td></tr>"); 209 210clr = cmap[internal_bug]; 211href = script_name ## "?file@rect+50+12+color+" ## clr; 212print("<tr><td valign=top>"); 213print("<img src=\""##href##"\" width=50 height=12>"); 214print("</td><td valign=top align=center>"); 215print("internal_bug"); 216print("</td><td valign=top>"); 217print("This cause is used for bugs found by the development team, or by"); 218print("the development organization."); 219print("</td></tr>"); 220 221clr = cmap[internal_enhancement]; 222href = script_name ## "?file@rect+50+12+color+" ## clr; 223print("<tr><td valign=top>"); 224print("<img src=\""##href##"\" width=50 height=12>"); 225print("</td><td valign=top align=center>"); 226print("internal_enhancement"); 227print("</td><td valign=top>"); 228print("This cause is used for new functionality requested by the"); 229print("development team, or by the development organization."); 230print("</td></tr>"); 231 232clr = cmap[internal_improvement]; 233href = script_name ## "?file@rect+50+12+color+" ## clr; 234print("<tr><td valign=top>"); 235print("<img src=\""##href##"\" width=50 height=12>"); 236print("</td><td valign=top align=center>"); 237print("internal_improvement"); 238print("</td><td valign=top>"); 239print("This cause is used for improvement to existing functionality"); 240print("(e.g. performance) requested by the development team, or by the"); 241print("development organization."); 242print("</td></tr>"); 243 244clr = cmap[external_bug]; 245href = script_name ## "?file@rect+50+12+color+" ## clr; 246print("<tr><td valign=top>"); 247print("<img src=\""##href##"\" width=50 height=12>"); 248print("</td><td valign=top align=center>"); 249print("external_bug"); 250print("</td><td valign=top>"); 251print("This cause is used for bugs found by the customer, or by a source"); 252print("outside the development organization."); 253print("</td></tr>"); 254 255clr = cmap[external_enhancement]; 256href = script_name ## "?file@rect+50+12+color+" ## clr; 257print("<tr><td valign=top>"); 258print("<img src=\""##href##"\" width=50 height=12>"); 259print("</td><td valign=top align=center>"); 260print("external_enhancement"); 261print("</td><td valign=top>"); 262print("This cause is used for new functionality requested by the customer,"); 263print("or by a source outside the development organization."); 264print("</td></tr>"); 265 266clr = cmap[external_improvement]; 267href = script_name ## "?file@rect+50+12+color+" ## clr; 268print("<tr><td valign=top>"); 269print("<img src=\""##href##"\" width=50 height=12>"); 270print("</td><td valign=top align=center>"); 271print("external_improvement"); 272print("</td><td valign=top>"); 273print("This cause is used for improvement to existing functionality"); 274print("(e.g. performance) requested by the customer, or a source outside"); 275print("the development development organization."); 276print("</td></tr>"); 277 278print("</table>"); 279print("</div>"); 280 281print("<hr>"); 282print("<p align=center class=\"navbar\">["); 283print("<a href=\"" ## script_name ## "\">Project List</a> |"); 284href = script_name ## "?file@proj_menu+project@" ## quote_url(pn); 285print("<a href=\"" ## href ## "\">Project Menu</a> |"); 286href = script_name ## "?file@changes+project@" ## quote_url(pn); 287print("<a href=\"" ## href ## "\">Change List</a> |"); 288href = script_name ## "?file@proj_cch1+project@" ## quote_url(pn); 289print("<a href=\"" ## href ## "\">Project Histogram</a> |"); 290href = script_name ## "?file@proj_cch2+project@" ## quote_url(pn) ## "+" 291 ## year; 292print("<a href=\"" ## href ## "\">Year Histogram</a>"); 293print("]</p>"); 294 295print("<hr>"); 296print("This page was generated " ## now() ## "."); 297print("</body></html>"); 298