Index: trunk/tools/bugzilla/bugzilla-4.0/weekly-bug-summary.cgi |
— | — | @@ -1,385 +0,0 @@ |
2 | | -#!/usr/bin/perl -wT |
3 | | - |
4 | | -# its stolen from somewhere but was mostly re-written by Dirk Mueller <mueller@kde.org>, 08/2006 |
5 | | -# templatized by Matt Rogers <mattr@kde.org>, 12/2007 |
6 | | -use strict; |
7 | | -use lib "."; |
8 | | - |
9 | | -use Bugzilla; |
10 | | -use Bugzilla::Constants; |
11 | | -use Bugzilla::Util; |
12 | | -use Bugzilla::Error; |
13 | | -use Bugzilla::Field; |
14 | | - |
15 | | -sub total_bugs_in_bugzilla() |
16 | | -{ |
17 | | - my $dbh = Bugzilla->dbh; |
18 | | - |
19 | | - # figure out total bugs |
20 | | - my (@totalbugs) = $dbh->selectrow_array( |
21 | | - "SELECT count(bugs.bug_id) FROM bugs WHERE bugs.bug_severity != 'enhancement' AND |
22 | | - ( bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or |
23 | | - bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED')" |
24 | | - ); |
25 | | - |
26 | | - # figure out total number of wishes |
27 | | - my (@totalwishes) = $dbh->selectrow_array ( |
28 | | - "SELECT count(bugs.bug_id) FROM bugs WHERE bugs.bug_severity = 'enhancement' AND |
29 | | - ( bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or |
30 | | - bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED')" |
31 | | - ); |
32 | | - |
33 | | - return ($totalbugs[0], $totalwishes[0]); |
34 | | -} |
35 | | - |
36 | | -sub bugs_opened() |
37 | | -{ |
38 | | - my($product, $days) = @_; |
39 | | - |
40 | | - my $sqlproduct = ""; |
41 | | - $sqlproduct = "AND bugs.product_id=$product" |
42 | | - if(defined $product and $product ne "%"); |
43 | | - |
44 | | - my ($count) = Bugzilla->dbh->selectrow_array( |
45 | | - "SELECT count(bugs.bug_id) FROM bugs |
46 | | - WHERE creation_ts >= from_days(to_days(NOW())-?) |
47 | | - $sqlproduct AND bugs.bug_severity != 'enhancement'", undef, ($days) |
48 | | - ); |
49 | | - |
50 | | - return $count; |
51 | | -} |
52 | | - |
53 | | -sub wishes_opened() |
54 | | -{ |
55 | | - my($product, $days) = @_; |
56 | | - |
57 | | - my $sqlproduct = ""; |
58 | | - $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product) |
59 | | - if(defined $product and $product ne "%"); |
60 | | - |
61 | | - my ($count) = Bugzilla->dbh->selectrow_array( |
62 | | - "SELECT count(bugs.bug_id) FROM bugs |
63 | | - WHERE creation_ts >= from_days(to_days(NOW())-?) |
64 | | - $sqlproduct AND bugs.bug_severity = 'enhancement'", undef, ($days) |
65 | | - ); |
66 | | - |
67 | | - return $count; |
68 | | -} |
69 | | - |
70 | | -sub bugs_closed() |
71 | | -{ |
72 | | - my($product, $days) = @_; |
73 | | - my $query = ""; |
74 | | - my $sqlproduct = ""; |
75 | | - $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product) |
76 | | - if(defined $product and $product ne "%"); |
77 | | - |
78 | | - my ($count) = Bugzilla->dbh->selectrow_array(" |
79 | | -select |
80 | | - count(distinct bugs.bug_id) |
81 | | -from |
82 | | - bugs, bugs_activity |
83 | | -where |
84 | | - bugs.bug_severity != 'enhancement' AND |
85 | | - (bugs_activity.added='RESOLVED' or bugs_activity.added='CLOSED' or |
86 | | - bugs_activity.added='NEEDSINFO') |
87 | | -and |
88 | | - bugs_activity.bug_when >= FROM_DAYS(TO_DAYS(NOW())-?) |
89 | | -and |
90 | | - bugs.bug_id = bugs_activity.bug_id |
91 | | - $sqlproduct |
92 | | - ", undef, ($days)); |
93 | | - |
94 | | - return($count); |
95 | | -} |
96 | | - |
97 | | -sub wishes_closed() |
98 | | -{ |
99 | | - my($product, $days) = @_; |
100 | | - my $query = ""; |
101 | | - my $sqlproduct = ""; |
102 | | - $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product) |
103 | | - if(defined $product and $product ne "%"); |
104 | | - |
105 | | - # We are going to build a long SQL query. |
106 | | - my ($count) = Bugzilla->dbh->selectrow_array(" |
107 | | -select |
108 | | - count(distinct bugs.bug_id) |
109 | | -from |
110 | | - bugs, bugs_activity |
111 | | -where |
112 | | - bugs.bug_severity = 'enhancement' AND |
113 | | - (bugs_activity.added='RESOLVED' or bugs_activity.added='CLOSED' or |
114 | | - bugs_activity.added='NEEDSINFO') |
115 | | -and |
116 | | - bugs_activity.bug_when >= FROM_DAYS(TO_DAYS(NOW())-?) |
117 | | -and |
118 | | - bugs.bug_id = bugs_activity.bug_id |
119 | | - $sqlproduct |
120 | | - ", undef, ($days)); |
121 | | - |
122 | | - return($count); |
123 | | -} |
124 | | - |
125 | | -sub open_wishes() |
126 | | -{ |
127 | | - my($product) = @_; |
128 | | - |
129 | | - my $sqlproduct = ""; |
130 | | - $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product) |
131 | | - if(defined $product and $product ne "%"); |
132 | | - |
133 | | - # We are going to build a long SQL query. |
134 | | - my ($count) = Bugzilla->dbh->selectrow_array(" |
135 | | -SELECT |
136 | | - count(bugs.bug_id) |
137 | | -FROM bugs |
138 | | -WHERE bugs.bug_severity = 'enhancement' AND |
139 | | - (bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or |
140 | | - bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED') |
141 | | -$sqlproduct"); |
142 | | - |
143 | | - return $count; |
144 | | -} |
145 | | - |
146 | | - |
147 | | -# $format can be HTML or XML |
148 | | -sub print_product_bug_lists() { |
149 | | - my($number, $days, $format, $fh) = @_; |
150 | | - |
151 | | - my $query; |
152 | | - |
153 | | - my @results; |
154 | | - |
155 | | - # We are going to build a long SQL query. |
156 | | - my $sth = Bugzilla->dbh->prepare(" |
157 | | -select |
158 | | - products.name, bugs.product_id, count(bugs.product_id) as n |
159 | | -from |
160 | | - bugs, products |
161 | | -where |
162 | | - (bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or |
163 | | - bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED') |
164 | | -and |
165 | | - bugs.bug_severity != 'enhancement' |
166 | | -and |
167 | | - products.id = bugs.product_id |
168 | | - |
169 | | -group by product_id |
170 | | -order by n desc |
171 | | -limit $number |
172 | | - "); |
173 | | - $sth->execute; |
174 | | - |
175 | | - # For each product we want to show the difference in the last period. |
176 | | - # But this will involve two sql connections at once, which the bugzilla |
177 | | - # functions don't handle too nicely. |
178 | | - # So lets collect the data first and then print the table. |
179 | | - my %product_count; |
180 | | - my %product_id; |
181 | | - |
182 | | - while (my ($product, $p_id, $count) = $sth->fetchrow_array) { |
183 | | - $product_count{$product} = $count; |
184 | | - $product_id{$product} = $p_id; |
185 | | - } |
186 | | - |
187 | | - |
188 | | - foreach my $product (reverse sort |
189 | | - {$product_count{$a} <=> $product_count{$b}} |
190 | | - keys (%product_count)) { |
191 | | - my %product_results; |
192 | | - my $bopened = &bugs_opened($product_id{$product}, $days); |
193 | | - my $bclosed = &bugs_closed($product_id{$product}, $days); |
194 | | - $product_results{'id'} = $product_id{$product}; |
195 | | - $product_results{'name'} = $product; |
196 | | - $product_results{'count'} = $product_count{$product}; |
197 | | - $product_results{'bugs_opened'} = $bopened; |
198 | | - $product_results{'bugs_closed'} = $bclosed; |
199 | | - $product_results{'bugs_change'} = $bopened - $bclosed; |
200 | | - if( $product_results{'bugs_change'} > 0 ) { |
201 | | - $product_results{'bugs_change_color'} = "#FF9999"; |
202 | | - } elsif( $product_results{'bugs_change'} < 0 ) { |
203 | | - $product_results{'bugs_change_color'} = "#99FF99"; |
204 | | - } |
205 | | - $product_results{'total_wishes'} = &open_wishes($product_id{$product}); |
206 | | - $product_results{'open_wishes'} = &wishes_opened($product_id{$product}, $days); |
207 | | - $product_results{'closed_wishes'} = &wishes_closed($product_id{$product}, $days); |
208 | | - $product_results{'wishes_change'} = $product_results{'open_wishes'} - |
209 | | - $product_results{'closed_wishes'}; |
210 | | - if( $product_results{'wishes_change'} > 0 ) { |
211 | | - $product_results{'wish_change_color'} = "#FF9999"; |
212 | | - } elsif( $product_results{'wishes_change'} < 0 ) { |
213 | | - $product_results{'wish_change_color'} = "#99FF99"; |
214 | | - } |
215 | | - push @results, \%product_results; |
216 | | - } |
217 | | - |
218 | | - return \@results; |
219 | | -} |
220 | | - |
221 | | -sub print_bug_hunters_list() { |
222 | | - my($number, $days) = @_; |
223 | | - my @results; |
224 | | - my $query; |
225 | | - |
226 | | - my $sth = Bugzilla->dbh->prepare(" |
227 | | -select |
228 | | - assign.login_name, count(assign.login_name), count(assign.login_name) as n |
229 | | -from |
230 | | - bugs, bugs_activity, profiles assign |
231 | | -where |
232 | | - (bugs_activity.added='RESOLVED' or bugs_activity.added = 'CLOSED' or |
233 | | - bugs_activity.added='NEEDSINFO') |
234 | | -and |
235 | | - bugs_activity.bug_when >= from_days(TO_DAYS(NOW()) - ?) |
236 | | -and |
237 | | - bugs_activity.who = assign.userid |
238 | | -and |
239 | | - bugs.bug_id = bugs_activity.bug_id |
240 | | -and |
241 | | - (bugs.bug_status = 'RESOLVED' or bugs.bug_status = 'CLOSED') |
242 | | -group by assign.login_name |
243 | | -order by n desc |
244 | | -limit ? |
245 | | - "); |
246 | | - |
247 | | - $sth->execute($days, $number); |
248 | | - while (my ($user, $count, $n) = $sth->fetchrow_array()) { |
249 | | - |
250 | | - my %bh_results; |
251 | | - |
252 | | - # defang the email address |
253 | | - $user =~ y/\@\./ / if (Bugzilla->user->id == 0); |
254 | | - $bh_results{'user'} = $user; |
255 | | - $bh_results{'count'} = $count; |
256 | | - |
257 | | - push @results, \%bh_results; |
258 | | - } |
259 | | - |
260 | | - return \@results; |
261 | | -} |
262 | | - |
263 | | -sub print_bug_fixers_list() { |
264 | | - my($number, $days) = @_; |
265 | | - my @results; |
266 | | - |
267 | | - my $sth = Bugzilla->dbh->prepare(" |
268 | | -SELECT |
269 | | - profiles.login_name, bugs.bug_id, |
270 | | - MIN(UNIX_TIMESTAMP(bugs_activity.bug_when)-UNIX_TIMESTAMP(bugs.creation_ts)) |
271 | | - AS open_time |
272 | | -FROM |
273 | | - bugs, bugs_activity, profiles, longdescs |
274 | | -WHERE |
275 | | - bugs.resolution='FIXED' |
276 | | -AND |
277 | | - bugs.bug_status='RESOLVED' |
278 | | -AND |
279 | | - bugs_activity.bug_when >= FROM_DAYS(TO_DAYS(NOW())-?) |
280 | | -AND |
281 | | - bugs.bug_id=bugs_activity.bug_id |
282 | | -AND |
283 | | - bugs_activity.added='FIXED' |
284 | | -AND |
285 | | - bugs_activity.who=profiles.userid |
286 | | -AND |
287 | | - bugs.reporter != bugs_activity.who |
288 | | -AND |
289 | | - longdescs.bug_id = bugs.bug_id |
290 | | -AND |
291 | | - longdescs.who = bugs_activity.who |
292 | | -AND |
293 | | - longdescs.thetext like \"SVN commit%\" |
294 | | -GROUP BY |
295 | | - profiles.login_name, bugs.bug_id |
296 | | -ORDER BY |
297 | | - open_time ASC |
298 | | -LIMIT ?"); |
299 | | - |
300 | | - $sth->execute($days, $number); |
301 | | - |
302 | | - while (my ($user, $bugid, $elapsed) = $sth->fetchrow_array) { |
303 | | - |
304 | | - my %bf_results; |
305 | | - |
306 | | - # defang the email address |
307 | | - $user =~ y/\@\./ / if (Bugzilla->user->id == 0); |
308 | | - $bf_results{'name'} = $user; |
309 | | - $bf_results{'elapsed'} = ${elapsed}; |
310 | | - my $html_elapsed = "${elapsed}s"; |
311 | | - $html_elapsed = int($elapsed/60) . " min" if ($elapsed > 60); |
312 | | - $html_elapsed = int($elapsed/(60*60)) . " h" if ($elapsed > (4*60*60)); |
313 | | - $html_elapsed = int($elapsed/(60*60*24)) . " days" if ($elapsed > (58*60*60)); |
314 | | - $bf_results{'formatted_elapsed'} = $html_elapsed; |
315 | | - $bf_results{'bugid'} = $bugid; |
316 | | - |
317 | | - push @results, \%bf_results; |
318 | | - } |
319 | | - |
320 | | - return \@results; |
321 | | -} |
322 | | - |
323 | | - |
324 | | -Bugzilla->login(LOGIN_OPTIONAL); |
325 | | - |
326 | | -# For most scripts we don't make $cgi and $template global variables. But |
327 | | -# when preparing Bugzilla for mod_perl, this script used these |
328 | | -# variables in so many subroutines that it was easier to just |
329 | | -# make them globals. |
330 | | -local our $cgi = Bugzilla->cgi; |
331 | | -local our $template = Bugzilla->template; |
332 | | -local our $vars = {}; |
333 | | - |
334 | | -# Output appropriate HTTP response headers |
335 | | -print $cgi->header(-type => 'text/html', -expires => '+3M'); |
336 | | - |
337 | | -my %defaults; |
338 | | - |
339 | | -# If they didn't tell us a time period we choose the last week. |
340 | | -my $current_days = 7; |
341 | | -$current_days = $cgi->param('days') if (defined $cgi->param('days')); |
342 | | -$current_days = 7 if (!detaint_natural($current_days)); |
343 | | -$defaults{'days'} = $current_days; |
344 | | - |
345 | | -my $current_tops = 20; |
346 | | -$current_tops = $cgi->param('tops') if (defined $cgi->param('tops')); |
347 | | -$current_tops = 20 if (!detaint_natural($current_tops)); |
348 | | -$defaults{'tops'} = $current_tops; |
349 | | - |
350 | | -$vars->{'duration'} = $current_days; |
351 | | -$vars->{'top_number'} = $current_tops; |
352 | | - |
353 | | -($vars->{'totalbugs'}, $vars->{'totalwishes'}) = &total_bugs_in_bugzilla(); |
354 | | - |
355 | | -my $bo = &bugs_opened("%", $current_days); |
356 | | -my $wo = &wishes_opened("%", $current_days); |
357 | | -my $bc = &bugs_closed("%", $current_days); |
358 | | -my $wc = &wishes_closed("%", $current_days); |
359 | | - |
360 | | -$vars->{'new_open_bugs'} = $bo; |
361 | | -$vars->{'new_closed_bugs'} = $bc; |
362 | | -$vars->{'new_open_wishes'} = $wo; |
363 | | -$vars->{'new_closed_wishes'} = $wc; |
364 | | - |
365 | | -my @tops = (10, 20, 30, 50, 100); |
366 | | -$vars->{'tops'} = \@tops; |
367 | | - |
368 | | -my @days = (1, 2, 7, 14, 31, 180, 365); |
369 | | -$vars->{'days'} = \@days; |
370 | | - |
371 | | -$vars->{'default'} = \%defaults; |
372 | | - |
373 | | -$vars->{'product_bug_lists'} = &print_product_bug_lists($current_tops, $current_days, "HTML"); |
374 | | - |
375 | | -$vars->{'bug_hunters_list'} = &print_bug_hunters_list($current_tops, $current_days); |
376 | | - |
377 | | -$vars->{'bug_fixers_list'} = &print_bug_fixers_list($current_tops, $current_days); |
378 | | - |
379 | | -$template->process("reports/weekly-bug-summary.html.tmpl", $vars) |
380 | | - || ThrowTemplateError($template->error()); |
381 | | - |
382 | | - |
383 | | - |
384 | | - |
385 | | - |
386 | | -print "</div>\n"; |