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