5 use POSIX qw(strftime nice);
7 use Debbugs::Config qw(:globals :text :config);
9 use Debbugs::CGI qw(:util :url :html);
10 use Debbugs::Common qw(getmaintainers getparsedaddrs);
11 use Debbugs::Bugs qw(count_bugs);
12 use Debbugs::Status qw(:status);
13 use Debbugs::Packages qw(getpkgsrc);
14 use Debbugs::Text qw(:templates);
18 my $q = new CGI::Simple;
19 my %param = cgi_parameters(query => $q,
20 single => [qw(indexon repeatmerged archive sortby),
21 qw(skip max_results first),
23 default => {indexon => 'pkg',
24 repeatmerged => 'yes',
32 if (defined $param{first}) {
33 # rip out all non-words from first
34 $param{first} =~ s/\W//g;
36 if (defined $param{next}) {
37 $param{skip}+=$param{max_results};
39 elsif (defined $param{prev}) {
40 $param{skip}-=$param{max_results};
41 $param{skip} = 0 if $param{skip} < 0;
44 my $indexon = $param{indexon};
45 if ($param{indexon} !~ m/^(pkg|src|maint|submitter|tag)$/) {
46 quitcgi("You have to choose something to index on");
49 my $repeatmerged = $param{repeatmerged} eq 'yes';
50 my $archive = $param{archive} eq "yes";
51 my $sortby = $param{sortby};
52 if ($sortby !~ m/^(alpha|count)$/) {
53 quitcgi("Don't know how to sort like that");
56 my $Archived = $archive ? " Archived" : "";
58 my %maintainers = %{&getmaintainers()};
61 my $dtime = strftime "%a, %e %b %Y %T UTC", gmtime;
68 if ($indexon eq "pkg") {
70 %count = count_bugs(function => sub {my %d=@_; return splitpackages($d{"pkg"})},
73 if (defined $param{first}) {
75 if (/^\Q$param{first}\E/) {
83 $note = "<p>Note that with multi-binary packages there may be other\n";
84 $note .= "reports filed under the different binary package names.</p>\n";
85 foreach my $pkg (keys %count) {
86 $sortkey{$pkg} = lc $pkg;
87 $htmldescrip{$pkg} = sprintf('<a href="%s">%s</a> (%s)',
88 package_links(package => $pkg, links_only=>1),
90 package_links(maint=>$maintainers{$pkg}//['']));
92 } elsif ($indexon eq "src") {
93 $tag = "source package";
94 my $pkgsrc = getpkgsrc();
95 if (defined $param{first}) {
97 if (/^\Q$param{first}\E/) {
105 %count = count_bugs(function => sub {my %d=@_;
108 } splitpackages($d{"pkg"});
113 foreach my $src (keys %count) {
114 $sortkey{$src} = lc $src;
115 $htmldescrip{$src} = sprintf('<a href="%s">%s</a> (%s)',
116 package_links(src => $src, links_only=>1),
118 package_links(maint => $maintainers{$src}//['']));
120 } elsif ($indexon eq "maint") {
122 my %email2maint = ();
123 %count = count_bugs(function => sub {my %d=@_;
125 my @me = getparsedaddrs($maintainers{$_});
126 foreach my $addr (@me) {
127 $email2maint{$addr->address} = $addr->format
128 unless exists $email2maint{$addr->address};
130 map { $_->address } @me;
131 } splitpackages($d{"pkg"});
135 if (defined $param{first}) {
137 if (/^\Q$param{first}\E/) {
145 $note = "<p>Note that maintainers may use different Maintainer fields for\n";
146 $note .= "different packages, so there may be other reports filed under\n";
147 $note .= "different addresses.</p>\n";
148 foreach my $maint (keys %count) {
149 $sortkey{$maint} = lc $email2maint{$maint} || "(unknown)";
150 $htmldescrip{$maint} = package_links(maint => $email2maint{$maint}//['']);
152 } elsif ($indexon eq "submitter") {
155 %count = count_bugs(function => sub {my %d=@_;
156 my @se = getparsedaddrs($d{"submitter"} || "");
157 foreach my $addr (@se) {
158 $fullname{$addr->address} = $addr->format
159 unless exists $fullname{$addr->address};
161 map { $_->address } @se;
165 if (defined $param{first}) {
167 if (/^\Q$param{first}\E/) {
175 foreach my $sub (keys %count) {
176 $sortkey{$sub} = lc $fullname{$sub};
177 $htmldescrip{$sub} = sprintf('<a href="%s">%s</a>',
179 html_escape($fullname{$sub}));
181 $note = "<p>Note that people may use different email accounts for\n";
182 $note .= "different bugs, so there may be other reports filed under\n";
183 $note .= "different addresses.</p>\n";
184 } elsif ($indexon eq "tag") {
186 %count = count_bugs(function => sub {my %d=@_; return split ' ', $d{tags}; },
189 if (defined $param{first}) {
191 if (/^\Q$param{first}\E/) {
200 foreach my $keyword (keys %count) {
201 $sortkey{$keyword} = lc $keyword;
202 $htmldescrip{$keyword} = sprintf('<a href="%s">%s</a>',
204 html_escape($keyword));
208 my $result = "<ul>\n";
210 if ($sortby eq "count") {
211 @orderedentries = sort { $count{$a} <=> $count{$b} } keys %count;
212 } else { # sortby alpha
213 @orderedentries = sort { $sortkey{$a} cmp $sortkey{$b} } keys %count;
215 my $skip = $param{skip};
216 my $max_results = $param{max_results};
217 foreach my $x (@orderedentries) {
218 if (not defined $param{first}) {
219 $skip-- and next if $skip > 0;
220 last if --$max_results < 0;
222 $result .= "<li>" . $htmldescrip{$x} . " has $count{$x} " .
223 ($count{$x} == 1 ? "bug" : "bugs") . "</li>\n";
225 $result .= "</ul>\n";
227 print "Content-Type: text/html\n\n";
229 print fill_in_template(template=>'cgi/pkgindex.tmpl',
230 variables => {count => \%count,
233 html_escape => \&Debbugs::CGI::html_escape,
234 archived => $Archived,
238 hole_var => {'&strftime' => \&POSIX::strftime,