]> git.donarmstrong.com Git - debbugs.git/blob - cgi/common.pl
[project @ 2000-10-08 11:42:49 by ajt]
[debbugs.git] / cgi / common.pl
1 #!/usr/bin/perl -w
2
3 my $common_archive = 0;
4 my $common_repeatmerged = 1;
5
6 sub set_option {
7     my ($opt, $val) = @_;
8     if ($opt eq "archive") { $common_archive = $val; }
9     if ($opt eq "repeatmerged") { $common_repeatmerged = $val; }
10 }
11
12 sub quit {
13     my $msg = shift;
14     print "Content-Type: text/html\n\n";
15     print "<HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY>\n";
16     print "An error occurred. Dammit.\n";
17     print "Error was: $msg.\n";
18     print "</BODY></HTML>\n";
19     exit 0;
20 }
21
22 #sub abort {
23 #    my $msg = shift;
24 #    my $Archive = $common_archive ? "archive" : "";
25 #    print header . start_html("Sorry");
26 #    print "Sorry bug #$msg doesn't seem to be in the $Archive database.\n";
27 #    print end_html;
28 #    exit 0;
29 #}
30
31 sub htmlindexentry {
32     my $ref = shift;
33     my %status = getbugstatus($ref);
34     return htmlindexentrystatus(%status) if (%status);
35     return "";
36 }
37
38 sub htmlindexentrystatus {
39     my $s = shift;
40     my %status = %{$s};
41
42     my $result = "";
43
44     if  ($status{severity} eq 'normal') {
45         $showseverity = '';
46     } elsif (grep($status{severity} eq $_, @debbugs::gStrongSeverities)) {
47         $showseverity = "<strong>Severity: $status{severity}</strong>;\n";
48     } else {
49         $showseverity = "Severity: <em>$status{severity}</em>;\n";
50     }
51
52     $result .= "Package: <a href=\"" . pkgurl($status{"package"}) . "\">"
53                . "<strong>" . htmlsanit($status{"package"}) . "</strong></a>;\n"
54                if (length($status{"package"}));
55     $result .= $showseverity;
56     $result .= "Reported by: " . htmlsanit($status{originator});
57     $result .= ";\nTags: <strong>" 
58                  . htmlsanit(join(", ", sort(split(/\s+/, $status{tags}))))
59                  . "</strong>"
60                        if (length($status{tags}));
61
62     my @merged= split(/ /,$status{mergedwith});
63     my $mseparator= ";\nmerged with ";
64     for my $m (@merged) {
65         $result .= $mseparator."<A href=\"" . bugurl($m) . "\">#$m</A>";
66         $mseparator= ", ";
67     }
68
69     if (length($status{done})) {
70         $result .= ";\n<strong>Done:</strong> " . htmlsanit($status{done});
71     } elsif (length($status{forwarded})) {
72         $result .= ";\n<strong>Forwarded</strong> to "
73                    . htmlsanit($status{forwarded});
74     } else {
75         my $daysold = int((time - $status{date}) / 86400);   # seconds to days
76         if ($daysold >= 7) {
77             my $font = "";
78             my $efont = "";
79             $font = "em" if ($daysold > 30);
80             $font = "strong" if ($daysold > 60);
81             $efont = "</$font>" if ($font);
82             $font = "<$font>" if ($font);
83
84             my $yearsold = int($daysold / 364);
85             $daysold = $daysold - $yearsold * 364;
86
87             $result .= ";\n $font";
88             $result .= "1 year and " if ($yearsold == 1);
89             $result .= "$yearsold years and " if ($yearsold > 1);
90             $result .= "1 day old" if ($daysold == 1);
91             $result .= "$daysold days old" if ($daysold != 1);
92             $result .= "$efont";
93         }
94     }
95
96     $result .= ".";
97
98     return $result;
99 }
100
101 sub mainturl {
102     my $ref = shift;
103     my $params = "maintenc=" . maintencoded($ref);
104     $params .= "&archive=yes" if ($common_archive);
105     $params .= "&repeatmerged=yes" if ($common_repeatmerged);
106     return $debbugs::gCGIDomain . "pkgreport.cgi" . "?" . $params;
107 }
108
109 sub pkgurl {
110     my $ref = shift;
111     my $params = "pkg=$ref";
112     $params .= "&archive=yes" if ($common_archive);
113     $params .= "&repeatmerged=yes" if ($common_repeatmerged);
114     
115     return $debbugs::gCGIDomain . "pkgreport.cgi" . "?" . "$params";
116 }
117
118 sub htmlsanit {
119     my %saniarray = ('<','lt', '>','gt', '&','amp', '"','quot');
120     my $in = shift;
121     my $out;
122     while ($in =~ m/[<>&"]/) {
123         $out .= $`. '&'. $saniarray{$&}. ';';
124         $in = $';
125     }
126     $out .= $in;
127     return $out;
128 }
129
130 sub bugurl {
131     my $ref = shift;
132     my $params = "bug=$ref";
133     foreach my $val (@_) {
134         $params .= "\&msg=$1" if ($val =~ /^msg=([0-9]+)/);
135         $params .= "\&archive=yes" if (!$common_archive && $val =~ /^archive.*$/);
136     }
137     $params .= "&archive=yes" if ($common_archive);
138     $params .= "&repeatmerged=yes" if ($common_repeatmerged);
139
140     return $debbugs::gCGIDomain . "bugreport.cgi" . "?" . "$params";
141 }
142
143 sub packageurl {
144     my $ref = shift;
145     return $debbugs::gCGIDomain . "package.cgi" . "?" . "package=$ref";
146 }
147
148 sub allbugs {
149     my @bugs = ();
150
151     opendir(D, "$debbugs::gSpoolDir/db") or &quit("opendir db: $!");
152     @bugs = sort {$a<=>$b} grep s/\.status$//,
153                  (grep m/^[0-9]+\.status$/,
154                  (readdir(D)));
155     closedir(D);
156
157     return @bugs;
158 }
159
160 sub htmlizebugs {
161     my @bugs = @_;
162
163     my %section = ();
164
165     my %displayshowpending = ("pending", "outstanding",
166                               "done", "resolved",
167                               "forwarded", "forwarded to upstream software authors");
168
169     if (@bugs == 0) {
170         return "<HR><H2>No reports found!</H2></HR>\n";
171     }
172
173     foreach my $bug (sort {$a<=>$b} @bugs) {
174         my %status = getbugstatus($bug);
175         next unless %status;
176         my @merged = sort {$a<=>$b} ($bug, split(/ /, $status{mergedwith}));
177         if ($common_repeatmerged || $bug == $merged[0]) {
178             $section{$status{pending} . "_" . $status{severity}} .=
179                 sprintf "<li><a href=\"%s\">#%d: %s</a>\n<br>",
180                     bugurl($bug), $bug, htmlsanit($status{subject});
181             $section{$status{pending} . "_" . $status{severity}} .=
182                 htmlindexentrystatus(\%status) . "\n";
183         }
184     }
185
186     my $result = "";
187     my $anydone = 0;
188     foreach my $pending (qw(pending forwarded done)) {
189         foreach my $severity(@debbugs::gSeverityList) {
190             $severity = $debbugs::gDefaultSeverity if ($severity eq '');
191             next unless defined $section{${pending} . "_" . ${severity}};
192             $result .= "<HR><H2>$debbugs::gSeverityDisplay{$severity} - $displayshowpending{$pending}</H2>\n";
193             $result .= "(A list of <a href=\"http://www.debian.org/Bugs/db/si/$pending$severity\">all such bugs</a> is available).\n";
194             $result .= "<UL>\n";
195             $result .= $section{$pending . "_" . $severity}; 
196             $result .= "</UL>\n";
197             $anydone = 1 if ($pending eq "done");
198          }
199     }
200
201     $result .= $debbugs::gHTMLExpireNote if ($anydone);
202     return $result;
203 }
204
205 sub submitterbugs {
206     my $submitter = shift;
207     my $chk = sub {
208         my %d = @_;
209         ($subemail = $d{"submitter"}) =~ s/\s*\(.*\)\s*//;
210         if ($subemail =~ m/<(.*)>/) { $subemail = $1 }
211         return $subemail eq $submitter;
212     };
213     return getbugs($chk);
214 }
215
216 sub severitybugs {
217     my $status = shift;
218     my $severity = shift;
219     my $chk = sub {
220         my %d = @_; 
221         return ($d{"severity"} eq $severity) && ($d{"status"} eq $status); 
222     };
223     return getbugs($chk);
224 }
225
226 sub maintbugs {
227     my $maint = shift;
228     my %maintainers = getmaintainers();
229     my $chk = sub {
230         my %d = @_;
231         ($maintemail = $maintainers{$d{"pkg"}} || "") =~ s/\s*\(.*\)\s*//;
232         if ($maintemail =~ m/<(.*)>/) { $maintemail = $1 }
233         return $maintemail eq $maint;
234     };
235     return getbugs($chk);
236 }
237
238 sub maintencbugs {
239     my $maint = shift;
240     my %maintainers = getmaintainers();
241     return getbugs(sub {my %d=@_; return maintencoded($maintainers{$d{"pkg"}} || "") eq $maint});
242 }
243
244 sub pkgbugs {
245     my $inpkg = shift;
246     return getbugs( sub { my %d = @_; return $inpkg eq $d{"pkg"} });
247 }
248
249 sub getbugs {
250     my $bugfunc = shift;
251
252     if ( $common_archive ) {
253         open I, "<$debbugs::gSpoolDir/index.archive" or &quit("bugindex: $!");
254     } else {
255         open I, "<$debbugs::gSpoolDir/index.db" or &quit("bugindex: $!");
256     }
257     
258     my @result = ();
259     while(<I>) 
260     {
261         if (m/^(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+\[\s*([^]]*)\s*\]\s+(\w+)\s+(.+)$/) {
262             if ($bugfunc->(pkg => $1, bug => $2, status => $4, submitter => $5,
263                            severity => $6, title => $7))
264             {
265                 push (@result, $2);
266             }
267         }
268     }
269     close I;
270     return sort {$a <=> $b} @result;
271 }
272
273 sub pkgbugsindex {
274     my %descstr = ();
275     if ( $common_archive ) {
276         open I, "<$debbugs::gSpoolDir/index.archive" or &quit("bugindex: $!");
277     } else {
278         open I, "<$debbugs::gSpoolDir/index.db" or &quit("bugindex: $!");
279     }
280     while(<I>) { 
281         $descstr{ $1 } = 1 if (m/^(\S+)/);
282     }
283     return %descstr;
284 }
285
286 sub maintencoded {
287     my $input = shift;
288     my $encoded = '';
289
290     while ($input =~ m/\W/) {
291         $encoded.=$`.sprintf("-%02x_",unpack("C",$&));
292         $input= $';
293     }
294
295     $encoded.= $input;
296     $encoded =~ s/-2e_/\./g;
297     $encoded =~ s/^([^,]+)-20_-3c_(.*)-40_(.*)-3e_/$1,$2,$3,/;
298     $encoded =~ s/^(.*)-40_(.*)-20_-28_([^,]+)-29_$/,$1,$2,$3/;
299     $encoded =~ s/-20_/_/g;
300     $encoded =~ s/-([^_]+)_-/-$1/g;
301     return $encoded;
302 }
303
304 sub getmaintainers {
305     my %maintainer;
306
307     open(MM,"$gMaintainerFile") or &quit("open $gMaintainerFile: $!");
308     while(<MM>) {
309         next unless m/^(\S+)\s+(\S.*\S)\s*$/;
310         ($a,$b)=($1,$2);
311         $a =~ y/A-Z/a-z/;
312         $maintainer{$a}= $b;
313     }
314     close(MM);
315
316     return %maintainer;
317 }
318
319 sub getbugstatus {
320     my $bugnum = shift;
321
322     my %status;
323
324     unless (open(S,"$gSpoolDir/db/$bugnum.status")) {
325         my $archdir = sprintf "%02d", $bugnum % 100;
326         open(S,"$gSpoolDir/archive/$archdir/$bugnum.status" ) or return ();
327     }
328     my @lines = qw(originator date subject msgid package tags done
329                         forwarded mergedwith severity);
330     while(<S>) {
331         chomp;
332         $status{shift @lines} = $_;
333     }
334     close(S);
335     $status{shift @lines} = '' while(@lines);
336
337     $status{"package"} =~ s/\s*$//;
338     $status{"package"} = 'unknown' if ($status{"package"} eq '');
339     $status{"severity"} = 'normal' if ($status{"severity"} eq '');
340
341     $status{"pending"} = 'pending';
342     $status{"pending"} = 'forwarded' if (length($status{"forwarded"}));
343     $status{"pending"} = 'done'      if (length($status{"done"}));
344
345     return %status;
346 }
347
348 sub buglog {
349     my $bugnum = shift;
350     my $res;
351
352     $res = "$gSpoolDir/db/$bugnum.log"; 
353     return $res if ( -e $res );
354
355     my $archdir = sprintf "%02d", $bugnum % 100;
356     $res = "$gSpoolDir/archive/$archdir/$bugnum.log";
357     return $res if ( -e $res );
358
359     return "";
360 }
361
362 1