]> git.donarmstrong.com Git - debbugs.git/blob - cgi/common.pl
[project @ 2000-10-03 19:26:51 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     my $params = "maintenc=" . maintencoded($ref);
101     $params .= "&archive=yes" if ($common_archive);
102     $params .= "&repeatmerged=yes" if ($common_repeatmerged);
103     return $debbugs::gCGIDomain . "pkgreport.cgi" . "?" . $params;
104 }
105
106 sub pkgurl {
107     my $ref = shift;
108     my $params = "pkg=$ref";
109     $params .= "&archive=yes" if ($common_archive);
110     $params .= "&repeatmerged=yes" if ($common_repeatmerged);
111     
112     return $debbugs::gCGIDomain . "pkgreport.cgi" . "?" . "$params";
113 }
114
115 sub htmlsanit {
116     my %saniarray = ('<','lt', '>','gt', '&','amp', '"','quot');
117     my $in = shift;
118     my $out;
119     while ($in =~ m/[<>&"]/) {
120         $out .= $`. '&'. $saniarray{$&}. ';';
121         $in = $';
122     }
123     $out .= $in;
124     return $out;
125 }
126
127 sub bugurl {
128     my $ref = shift;
129     my $params = "bug=$ref";
130     foreach my $val (@_) {
131         $params .= "\&msg=$1" if ($val =~ /^msg=([0-9]+)/);
132         $params .= "\&archive=yes" if (!$common_archive && $val =~ /^archive.*$/);
133     }
134     $params .= "&archive=yes" if ($common_archive);
135     $params .= "&repeatmerged=yes" if ($common_repeatmerged);
136
137     return $debbugs::gCGIDomain . "bugreport.cgi" . "?" . "$params";
138 }
139
140 sub packageurl {
141     my $ref = shift;
142     return $debbugs::gCGIDomain . "package.cgi" . "?" . "package=$ref";
143 }
144
145 sub allbugs {
146     my @bugs = ();
147
148     opendir(D, "$debbugs::gSpoolDir/db") or &quit("opendir db: $!");
149     @bugs = sort {$a<=>$b} grep s/\.status$//,
150                  (grep m/^[0-9]+\.status$/,
151                  (readdir(D)));
152     closedir(D);
153
154     return @bugs;
155 }
156
157 sub htmlizebugs {
158     my @bugs = @_;
159
160     my %section = ();
161
162     my %displayshowpending = ("pending", "outstanding",
163                               "done", "resolved",
164                               "forwarded", "forwarded to upstream software authors");
165
166     if (@bugs == 0) {
167         return hr . h2("No reports found!");
168     }
169
170     foreach my $bug (sort {$a<=>$b} @bugs) {
171         my %status = getbugstatus($bug);
172         next unless %status;
173         my @merged = sort {$a<=>$b} ($bug, split(/ /, $status{mergedwith}));
174         if ($common_repeatmerged || $bug == $merged[0]) {
175             $section{$status{pending} . "_" . $status{severity}} .=
176                 sprintf "<li><a href=\"%s\">#%d: %s</a>\n<br>",
177                     bugurl($bug), $bug, htmlsanit($status{subject});
178             $section{$status{pending} . "_" . $status{severity}} .=
179                 htmlindexentrystatus(\%status) . "\n";
180         }
181     }
182
183     my $result = "";
184     my $anydone = 0;
185     foreach my $pending (qw(pending forwarded done)) {
186         foreach my $severity(@debbugs::gSeverityList) {
187             $severity = $debbugs::gDefaultSeverity if ($severity eq '');
188             next unless defined $section{${pending} . "_" . ${severity}};
189             $result .= hr . h2("$debbugs::gSeverityDisplay{$severity} - $displayshowpending{$pending}");
190             $result .= "(A list of <a href=\"http://www.debian.org/Bugs/db/si/$pending$severity\">all such bugs</a> is available).\n";
191             $result .= ul($section{$pending . "_" . $severity});
192             $anydone = 1 if ($pending eq "done");
193          }
194     }
195
196     $result .= $debbugs::gHTMLExpireNote if ($anydone);
197     return $result;
198 }
199
200 sub submitterbugs {
201     my $submitter = shift;
202     my $chk = sub {
203         my %d = @_;
204         ($subemail = $d{"submitter"}) =~ s/\s*\(.*\)\s*//;
205         if ($subemail =~ m/<(.*)>/) { $subemail = $1 }
206         return $subemail eq $submitter;
207     };
208     return getbugs($chk);
209 }
210
211 sub maintbugs {
212     my $maint = shift;
213     my %maintainers = getmaintainers();
214     my $chk = sub {
215         my %d = @_;
216         ($maintemail = $maintainers{$d{"pkg"}} || "") =~ s/\s*\(.*\)\s*//;
217         if ($maintemail =~ m/<(.*)>/) { $maintemail = $1 }
218         return $maintemail eq $maint;
219     };
220     return getbugs($chk);
221 }
222
223 sub maintencbugs {
224     my $maint = shift;
225     my %maintainers = getmaintainers();
226     return getbugs(sub {my %d=@_; return maintencoded($maintainers{$d{"pkg"}} || "") eq $maint});
227 }
228
229 sub pkgbugs {
230     my $inpkg = shift;
231     return getbugs( sub { my %d = @_; return $inpkg eq $d{"pkg"} });
232 }
233
234 sub getbugs {
235     my $bugfunc = shift;
236
237     if ( $common_archive ) {
238         open I, "<$debbugs::gSpoolDir/index.archive" or &quit("bugindex: $!");
239     } else {
240         open I, "<$debbugs::gSpoolDir/index.db" or &quit("bugindex: $!");
241     }
242     
243     my @result = ();
244     while(<I>) 
245     {
246         if (m/^(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+\[\s*([^]]*)\s*\]\s+(\w+)\s+(.+)$/) {
247             if ($bugfunc->(pkg => $1, bug => $2, submitter => $5,
248                            severity => $6, title => $7))
249             {
250                 push (@result, $2);
251             }
252         }
253     }
254     close I;
255     return sort {$a <=> $b} @result;
256 }
257
258 sub pkgbugsindex {
259     my %descstr = ();
260     if ( $common_archive ) {
261         open I, "<$debbugs::gSpoolDir/index.archive" or &quit("bugindex: $!");
262     } else {
263         open I, "<$debbugs::gSpoolDir/index.db" or &quit("bugindex: $!");
264     }
265     while(<I>) { 
266         $descstr{ $1 } = 1 if (m/^(\S+)/);
267     }
268     return %descstr;
269 }
270
271 sub maintencoded {
272     my $input = shift;
273     my $encoded = '';
274
275     while ($input =~ m/\W/) {
276         $encoded.=$`.sprintf("-%02x_",unpack("C",$&));
277         $input= $';
278     }
279
280     $encoded.= $input;
281     $encoded =~ s/-2e_/\./g;
282     $encoded =~ s/^([^,]+)-20_-3c_(.*)-40_(.*)-3e_/$1,$2,$3,/;
283     $encoded =~ s/^(.*)-40_(.*)-20_-28_([^,]+)-29_$/,$1,$2,$3/;
284     $encoded =~ s/-20_/_/g;
285     $encoded =~ s/-([^_]+)_-/-$1/g;
286     return $encoded;
287 }
288
289 sub getmaintainers {
290     my %maintainer;
291
292     open(MM,"$gMaintainerFile") or &quit("open $gMaintainerFile: $!");
293     while(<MM>) {
294         next unless m/^(\S+)\s+(\S.*\S)\s*$/;
295         ($a,$b)=($1,$2);
296         $a =~ y/A-Z/a-z/;
297         $maintainer{$a}= $b;
298     }
299     close(MM);
300
301     return %maintainer;
302 }
303
304 sub getbugstatus {
305     my $bugnum = shift;
306
307     my %status;
308
309     unless (open(S,"$gSpoolDir/db/$bugnum.status")) {
310         my $archdir = sprintf "%02d", $bugnum % 100;
311         open(S,"$gSpoolDir/archive/$archdir/$bugnum.status" ) or return ();
312     }
313     my @lines = qw(originator date subject msgid package keywords done
314                         forwarded mergedwith severity);
315     while(<S>) {
316         chomp;
317         $status{shift @lines} = $_;
318     }
319     close(S);
320     $status{shift @lines} = '' while(@lines);
321
322     $status{"package"} =~ s/\s*$//;
323     $status{"package"} = 'unknown' if ($status{"package"} eq '');
324     $status{"severity"} = 'normal' if ($status{"severity"} eq '');
325
326     $status{"pending"} = 'pending';
327     $status{"pending"} = 'forwarded' if (length($status{"forwarded"}));
328     $status{"pending"} = 'done'      if (length($status{"done"}));
329
330     return %status;
331 }
332
333 sub buglog {
334     my $bugnum = shift;
335     my $res;
336
337     $res = "$gSpoolDir/db/$bugnum.log"; 
338     return $res if ( -e $res );
339
340     my $archdir = sprintf "%02d", $bugnum % 100;
341     $res = "$gSpoolDir/archive/$archdir/$bugnum.log";
342     return $res if ( -e $res );
343
344     return "";
345 }
346
347 1