1/*
2 *	aegis - project change supervisor
3 *	Copyright (C) 2000, 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;
21pn = project_name();
22auto ps, cs;
23ps = project[pn].state;
24auto ph, when, n, max, href;
25
26auto script_name;
27script_name = getenv("SCRIPT_NAME");
28if (script_name == "")
29	script_name = "http://localhost/cgi-bin/aegis.cgi";
30
31auto year;
32if (count(arg) > 0)
33        year = arg[0];
34else
35	year = 0 + strftime("%Y", now());
36
37auto earliest, latest;
38earliest = mktime("1-Jan-" ## year ## " 00:00:00");
39latest = mktime("31-Dec-" ## year ## " 23:59:59");
40
41auto color_map;
42color_map =
43{
44	new_change = "128+128+128";
45	develop_begin = "0+0+255";
46	develop_begin_undo = "0+95+95";
47	develop_end = "128+128+255";
48	develop_end_2ar = "96+96+255";
49	develop_end_2ai = "160+160+255";
50	develop_end_undo = "0+255+255";
51	review_begin = "255+192+0";
52	review_begin_undo = "255+128+0";
53	review_pass = "255+255+0";
54	review_pass_undo = "192+255+64";
55	review_fail = "255+0+0";
56	integrate_begin = "0+128+0";
57	integrate_begin_undo = "0+128+128";
58	integrate_fail = "255+0+255";
59	integrate_pass = "0+255+0";
60};
61
62columns({width = 1000; });
63print("Content-Type: text/html");
64print("");
65print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\""
66	## "\"http://www.w3.org/TR/REC-html40/loose.dtd\">");
67print("<html><head>");
68print("<meta name=\"ROBOTS\" content=\"NOINDEX, NOFOLLOW\">");
69print("<meta name=\"GENERATOR\" content=\"" ## script_name ## "\">");
70print("<meta http-equiv=\"Content-Type\" "
71	## "content=\"text/html; charset=ISO-8859-1\">");
72print("<style type=\"text/css\"> "
73	## "tr.even-group { background-color: #CCCCCC; } "
74	## "body { background-color: white; } "
75	## "</style>");
76/*
77 * Netscape 4.x has numerous CSS bugs, two of which need mentioning.
78 * 1. If a style sheet is not present Netscape says 404 Not found, when
79 * it should silently ignore it.  2. Style sheets who's media is not
80 * "screen" will be ignored.  Fortunately we can use (2) to get around (1).
81 */
82print("<link rel=\"stylesheet\" type=\"text/css\" href=\"/aedefault.css\" "
83	## "media=\"all\">");
84auto stack, depth, bn;
85depth=0;
86stack[depth] = project[pn].state.name;
87while ("" != ( bn = project[stack[depth]].state.parent_name )) {
88  stack[++depth] = bn;
89}
90while ( depth >= 0) {
91    print("<link rel=\"stylesheet\" type=\"text/css\" href=\"/" ##
92	 stack[depth--] ## ".css\" " ## "media=\"all\">");
93}
94print("<title>");
95print("Project Progress Histogram");
96print("</title><head><body><h1 align=center>");
97
98print("<a href=\"" ## script_name ## "\">Project</a>");
99auto long_project_name;
100auto prj_name_parts;
101prj_name_parts = split(pn, '.');
102href = script_name ## "?file@proj_menu+project@"
103	## quote_url(prj_name_parts[0]);
104long_project_name = "<a href=\"" ## href ## "\" >"
105	## quote_html(prj_name_parts[0]) ## "</a>";
106auto j;
107for (j = 1; j < count(prj_name_parts); j++)
108{
109    href ##= '.' ## prj_name_parts[j];
110    long_project_name ##= ".<a href=\"" ## href ## "\" >"
111    	## quote_html(prj_name_parts[j]) ## "</a>";
112};
113long_project_name = "&ldquo;" ## long_project_name ## "&rdquo;,<br>";
114/* HTTP limits lines to 510 characters */
115for (j in wrap(long_project_name, 510))
116    print(j);
117
118href = script_name ## "?file@proj_prgr1+project@" ## quote_url(pn);
119print("Progress <a href=\"" ## href ## "\">Histogram</a><br>");
120print(year);
121print("</h1>");
122print("<div class=\"information\">");
123
124/* **********  Scan the Changes in this Branch  ************************* */
125
126auto earliest_year, latest_year;
127earliest_year = 0;
128latest_year = 0;
129auto bucket, month, hist, clr;
130bucket = {};
131bucket.total = {};
132for (ph in ps.branch.history)
133{
134	cs = ps.branch.change[ph.change_number];
135	for (hist in cs.history)
136	{
137		when = hist.when;
138		if (when < earliest || when > latest)
139			continue;
140		month = 0 + strftime("%m", when);
141		if (count(bucket[hist.what]) == 0)
142			bucket[hist.what] = {};
143		bucket[hist.what][month]++;
144		bucket.total[month]++;
145	}
146}
147
148max = 1;
149for (month = 1; month <= 12; ++month)
150{
151	n = 0 + bucket.total[month];
152	if (n > max)
153		max = n;
154}
155max = 400. / max;
156
157/* **********  Print the Histogram  ************************************* */
158
159print("<table align=center>");
160print("<tr><th>Month</th><th>Count</th></tr>");
161for (month = 1; month <= 12; ++month)
162{
163	auto t;
164	for
165	(
166		t = mktime("1-Jan-" ## year ## " 00:00:00");
167		strftime("%m", t) + 0 != month;
168		t += 28 * 24 * 60 * 60
169	)
170		;
171
172	n = 0 + bucket.total[month];
173	print("<tr><td align=right>");
174	if (n > 0)
175	{
176		/*
177		 * Note: don't use first of the month here,
178		 * time zones can have unexpected side effects.
179		 */
180		href = script_name ## "?file@proj_prgr3";
181		href ##= "+project@" ## quote_url(project_name());
182		href ##=  "+" ## strftime("2-%b-%Y", t);
183		print("<a href=\"" ## href ## "\">");
184	}
185	print(strftime("%B", t));
186	if (n > 0)
187		print("</a>");
188	print("</td><td align=right>");
189	print(n);
190	print("</td><td>");
191	for (hist in [new_change, develop_begin, develop_begin_undo,
192		develop_end, develop_end_undo, review_pass, review_pass_undo,
193		review_fail, integrate_begin, integrate_begin_undo,
194		integrate_fail, integrate_pass]
195	)
196	{
197		clr = color_map[hist];
198		n = bucket[hist][month];
199		if (n > 0)
200		{
201			n = round(n * max);
202			if (n < 3)
203				n = 3;
204			href = script_name ## "?file@rect+" ## n
205				## "+12+color+"## clr;
206			print("<img src=\"" ## href ## "\" width=" ## n
207				##" height=12>");
208		}
209	}
210	print("</td></tr>");
211}
212print("</table>");
213
214print("<p>");
215print("Please note: if the number of <dfn>review_fail</dfn>s is zero,");
216print("or relatively low compared to <dfn>review_pass</dfn>es,");
217print("then the process isn't working.");
218print("Reviews are <em>intended</em> to find defects.");
219print("</div>");
220
221/* **********  Legend  ************************************************** */
222
223print("<hr>");
224print("<div class=\"legend\">");
225print("<h2 align=center>Legend</h2>");
226
227print("<table align=center>");
228for (hist in [new_change, develop_begin, develop_begin_undo, develop_end,
229	develop_end_2ar, develop_end_2ai, develop_end_undo, review_begin,
230	review_begin_undo, review_pass, review_pass_undo,  review_fail,
231	integrate_begin, integrate_begin_undo, integrate_fail,
232	integrate_pass]
233)
234{
235	clr = color_map[hist];
236	print("<tr><td valign=top align=center>");
237	href = script_name ## "?file@rect+30+12+color+" ## clr;
238	print("<img src=\"" ## href ## "\" width=30 height=12>");
239	print("</td><td valign=top>");
240	print(hist);
241	print("</td></tr>");
242}
243print("</table>");
244print("</div>");
245
246print("<hr>");
247print("<p align=center class=\"navbar\">[");
248print("<a href=\"" ## script_name ## "\">Project List</a> |");
249href = script_name ## "?file@proj_menu+project@" ## quote_url(pn);
250print("<a href=\"" ## href ## "\">Project Menu</a> |");
251href = script_name ## "?file@changes+project@" ## quote_url(pn);
252print("<a href=\"" ## href ## "\">Change List</a> |");
253href = script_name ## "?file@proj_prgr1+project@" ## quote_url(pn);
254print("<a href=\"" ## href ## "\">Project Progress</a>");
255print("]</p>");
256
257print("<hr>");
258print("This page was generated " ## now() ## ".");
259print("</body></html>");
260