require '/etc/debbugs/config';
require '/etc/debbugs/text';
-use vars qw($gPackagePages $gWebDomain);
+use Debbugs::User;
+
+use vars qw($gPackagePages $gWebDomain %gSeverityDisplay @gSeverityList);
if (defined $ENV{REQUEST_METHOD} and $ENV{REQUEST_METHOD} eq 'HEAD') {
print "Content-Type: text/html; charset=utf-8\n\n";
my $archive = ($param{'archive'} || "no") eq "yes";
my $include = $param{'&include'} || $param{'include'} || "";
my $exclude = $param{'&exclude'} || $param{'exclude'} || "";
+
+my $users = $param{'users'} || "";
+
+my $ordering = $param{'ordering'};
my $raw_sort = ($param{'raw'} || "no") eq "yes";
+my $old_view = ($param{'oldview'} || "no") eq "yes";
+unless (defined $ordering) {
+ $ordering = "normal";
+ $ordering = "oldview" if $old_view;
+ $ordering = "raw" if $raw_sort;
+}
+
my $bug_rev = ($param{'bug-rev'} || "no") eq "yes";
my $pend_rev = ($param{'pend-rev'} || "no") eq "yes";
my $sev_rev = ($param{'sev-rev'} || "no") eq "yes";
}
if ($vt eq "bypkg" || $vt eq "bysrc") { $dist = undef; $arch = undef; }
}
- if (defined $param{'ordering'}) {
- my $o = $param{'ordering'};
- if ($o eq "raw") { $raw_sort = 1; $bug_rev = 0; }
- if ($o eq "normal") { $raw_sort = 0; $bug_rev = 0; }
- if ($o eq "reverse") { $raw_sort = 0; $bug_rev = 1; }
- }
if (defined $param{'includesubj'}) {
my $is = $param{'includesubj'};
$include .= "," . join(",", map { "subj:$_" } (split /[\s,]+/, $is));
}
-my ($pkg, $src, $maint, $maintenc, $submitter, $severity, $status, $tag);
+my %hidden = map { $_, 1 } qw(status severity classification);
+my %cats = (
+ "status" => [ {
+ "nam" => "Status",
+ "pri" => [map { "pending=$_" }
+ qw(pending forwarded pending-fixed fixed done absent)],
+ "ttl" => ["Outstanding","Forwarded","Pending Upload",
+ "Fixed in NMU","Resolved","From other Branch"],
+ "def" => "Unknown Pending Status",
+ "ord" => [0,1,2,3,4,5,6],
+ } ],
+ "severity" => [ {
+ "nam" => "Severity",
+ "pri" => [map { "severity=$_" } @debbugs::gSeverityList],
+ "ttl" => [map { $debbugs::gSeverityDisplay{$_} } @debbugs::gSeverityList],
+ "def" => "Unknown Severity",
+ "ord" => [0,1,2,3,4,5,6,7],
+ } ],
+ "classification" => [ {
+ "nam" => "Classification",
+ "pri" => [qw(pending=pending+tag=wontfix
+ pending=pending+tag=moreinfo
+ pending=pending+tag=patch
+ pending=pending+tag=confirmed
+ pending=pending)],
+ "ttl" => ["Will Not Fix","More information needed",
+ "Patch Available","Confirmed"],
+ "def" => "Unclassified",
+ "ord" => [2,3,4,1,0,5],
+ } ],
+ "oldview" => [ qw(status severity) ],
+ "normal" => [ qw(status severity classification) ],
+);
+
+my ($pkg, $src, $maint, $maintenc, $submitter, $severity, $status, $tag, $usertag);
my %which = (
'pkg' => \$pkg,
'submitter' => \$submitter,
'severity' => \$severity,
'tag' => \$tag,
+ 'usertag' => \$usertag,
);
my @allowedEmpty = ( 'maint' );
}
quitcgi("You have to choose something to select by") if (!$found);
+my %bugusertags;
+my %ut;
+for my $user (split /[\s*,]+/, $users) {
+ next unless ($user =~ m/..../);
+ add_user($user);
+}
+
+if (defined $usertag) {
+ my %select_ut = ();
+ my ($u, $t) = split /:/, $usertag, 2;
+ Debbugs::User::read_usertags(\%select_ut, $u);
+ unless (defined $t && $t ne "") {
+ $t = join(",", keys(%select_ut));
+ }
+
+ add_user($u);
+ $tag = $t;
+}
+
my $Archived = $archive ? " Archived" : "";
my $this = "";
set_option("archive", $archive);
set_option("include", $include);
set_option("exclude", $exclude);
-set_option("raw", $raw_sort);
-set_option("bug-rev", $bug_rev);
-set_option("pend-rev", $pend_rev);
-set_option("sev-rev", $sev_rev);
set_option("pend-exc", $pend_exc);
set_option("pend-inc", $pend_inc);
set_option("sev-exc", $sev_exc);
set_option("show_list_header", $show_list_header);
set_option("show_list_footer", $show_list_footer);
+sub add_user {
+ my $ut = \%ut;
+ my $u = shift;
+
+ my $user = Debbugs::User::get_user($u);
+
+ my %vis = map { $_, 1 } @{$user->{"visible_cats"}};
+ for my $c (keys %{$user->{"categories"}}) {
+ $cats{$c} = $user->{"categories"}->{$c};
+ $hidden{$c} = 1 unless defined $vis{$c};
+ }
+
+ for my $t (keys %{$user->{"tags"}}) {
+ $ut->{$t} = [] unless defined $ut->{$t};
+ push @{$ut->{$t}}, @{$user->{"tags"}->{$t}};
+ }
+
+ %bugusertags = ();
+ for my $t (keys %{$ut}) {
+ for my $b (@{$ut->{$t}}) {
+ $bugusertags{$b} = [] unless defined $bugusertags{$b};
+ push @{$bugusertags{$b}}, $t;
+ }
+ }
+ set_option("bugusertags", \%bugusertags);
+}
+
my $title;
my @bugs;
if (defined $pkg) {
$title = "package $pkg";
+ add_user("$pkg\@packages.debian.org");
if (defined $version) {
$title .= " (version $version)";
} elsif (defined $dist) {
return 0;
}, 'package', @pkgs)};
} elsif (defined $src) {
+ add_user("$src\@packages.debian.org");
$title = "source $src";
set_option('arch', 'source');
if (defined $version) {
}, 'package', @pkgs)};
} elsif (defined $maint) {
my %maintainers = %{getmaintainers()};
+ add_user($maint);
$title = "maintainer $maint";
$title .= " in $dist" if defined $dist;
if ($maint eq "") {
return 0;
})};
} elsif (defined $submitter) {
+ add_user($submitter);
$title = "submitter $submitter";
$title .= " in $dist" if defined $dist;
my @submitters = split /,/, $submitter;
$title = "bugs tagged $tag";
$title .= " in $dist" if defined $dist;
my @tags = split /,/, $tag;
+ my %bugs = ();
+ for my $t (@tags) {
+ for my $b (@{$ut{$t}}) {
+ $bugs{$b} = 1;
+ }
+ }
@bugs = @{getbugs(sub {my %d = @_;
+ return 1 if $bugs{$d{"bug"}};
my %tags = map { $_ => 1 } split ' ', $d{"tags"};
return grep(exists $tags{$_}, @tags);
})};
}
+$title = htmlsanit($title);
+
+my @names; my @prior; my @title; my @order;
+determine_ordering();
my $result = pkg_htmlizebugs(\@bugs);
"<TITLE>$debbugs::gProject$Archived $debbugs::gBug report logs: $title</TITLE>\n" .
'<link rel="stylesheet" href="/css/bugs.css" type="text/css">' .
"</HEAD>\n" .
- '<BODY onload="toggle(1);enable(1);">' .
+ '<BODY onload="pagemain();">' .
"\n";
print "<H1>" . "$debbugs::gProject$Archived $debbugs::gBug report logs: $title" .
"</H1>\n";
my $showresult = 1;
if (defined $pkg || defined $src) {
- my $showpkg = (defined $pkg) ? $pkg : "source package $src";
+ my $showpkg = htmlsanit((defined $pkg) ? $pkg : "source package $src");
my %maintainers = %{getmaintainers()};
my $maint = $pkg ? $maintainers{$pkg} : $maintainers{$src} ? $maintainers{$src} : undef;
if (defined $maint) {
print $result if $showresult;
-print pkg_javascript();
+print pkg_javascript() . "\n";
print "<h2 class=\"outstanding\"><a class=\"options\" href=\"javascript:toggle(1)\">Options</a></h2>\n";
print "<div id=\"a_1\">\n";
printf "<form action=\"%s\" method=POST>\n", myurl();
print " <td><input id=\"b_1_2\" name=vt value=bysuite type=radio onchange=\"enable(1);\" $checked_sui>" . pkg_htmlselectsuite(1,2,1) . " for " . pkg_htmlselectarch(1,2,2) . "</td></tr>\n";
if (defined $pkg) {
- my $v = $version || "";
+ my $v = htmlsanit($version) || "";
+ my $pkgsane = htmlsanit($pkg);
print "<tr><td></td>";
- print " <td><input id=\"b_1_3\" name=vt value=bypkg type=radio onchange=\"enable(1);\" $checked_ver>$pkg version <input id=\"b_1_3_1\" name=version value=\"$v\"></td></tr>\n";
+ print " <td><input id=\"b_1_3\" name=vt value=bypkg type=radio onchange=\"enable(1);\" $checked_ver>$pkgsane version <input id=\"b_1_3_1\" name=version value=\"$v\"></td></tr>\n";
} elsif (defined $src) {
- my $v = $version || "";
+ my $v = htmlsanit($version) || "";
+ my $srcsane = htmlsanit($src);
print "<tr><td></td>";
- print " <td><input name=vt value=bysrc type=radio onchange=\"enable(1);\" $checked_ver>$src version <input id=\"b_1_3_1\" name=version value=\"$v\"></td></tr>\n";
+ print " <td><input name=vt value=bysrc type=radio onchange=\"enable(1);\" $checked_ver>$srcsane version <input id=\"b_1_3_1\" name=version value=\"$v\"></td></tr>\n";
}
+print "<tr><td> </td></tr>\n";
-my $sel_rmy = ($repeatmerged ? " selected" : "");
-my $sel_rmn = ($repeatmerged ? "" : " selected");
-my $sel_ordraw = ($raw_sort ? " selected" : "");
-my $sel_ordnor = (!$raw_sort && !$bug_rev ? " selected" : "");
-my $sel_ordrev = (!$raw_sort && $bug_rev ? " selected" : "");
-my $includetags = join(" ", grep { !m/^subj:/i } split /[\s,]+/, $include);
-my $excludetags = join(" ", grep { !m/^subj:/i } split /[\s,]+/, $exclude);
-my $includesubj = join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } split /[\s,]+/, $include);
-my $excludesubj = join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } split /[\s,]+/, $exclude);
+my $includetags = htmlsanit(join(" ", grep { !m/^subj:/i } split /[\s,]+/, $include));
+my $excludetags = htmlsanit(join(" ", grep { !m/^subj:/i } split /[\s,]+/, $exclude));
+my $includesubj = htmlsanit(join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } split /[\s,]+/, $include));
+my $excludesubj = htmlsanit(join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } split /[\s,]+/, $exclude));
my $vismindays = ($mindays == 0 ? "" : $mindays);
my $vismaxdays = ($maxdays == -1 ? "" : $maxdays);
+my $sel_rmy = ($repeatmerged ? " selected" : "");
+my $sel_rmn = ($repeatmerged ? "" : " selected");
+my $sel_ordraw = ($ordering eq "raw" ? " selected" : "");
+my $sel_ordold = ($ordering eq "oldview" ? " selected" : "");
+my $sel_ordnor = ($ordering eq "normal" ? " selected" : "");
+
+my $chk_bugrev = ($bug_rev ? " checked" : "");
+my $chk_pendrev = ($pend_rev ? " checked" : "");
+my $chk_sevrev = ($sev_rev ? " checked" : "");
+
print <<EOF;
-<tr><td>Display merged bugs</td><td>
+<tr><td>Only include bugs tagged with </td><td><input name=include value="$includetags"> or that have <input name=includesubj value="$includesubj"> in their subject</td></tr>
+<tr><td>Exclude bugs tagged with </td><td><input name=exclude value="$excludetags"> or that have <input name=excludesubj value="$excludesubj"> in their subject</td></tr>
+<tr><td>Only show bugs older than</td><td><input name=mindays value="$vismindays" size=5> days, and younger than <input name=maxdays value="$vismaxdays" size=5> days</td></tr>
+
+<tr><td> </td></tr>
+
+</td></tr>
+<tr><td>Merged bugs should be</td><td>
<select name=repeatmerged>
-<option value=yes$sel_rmy>separately</option>
+<option value=yes$sel_rmy>displayed separately</option>
<option value=no$sel_rmn>combined</option>
</select>
-</td></tr>
-<tr><td>Order bugs by</td><td>
+<tr><td>Categorise bugs by</td><td>
<select name=ordering>
-<option value=raw$sel_ordraw>bug number</option>
-<option value=normal$sel_ordnor>section, oldest first</option>
-<option value=reverse$sel_ordrev>section, newest first</option>
-</select>
-</td></tr>
-<tr><td>Only include bugs tagged with </td><td><input name=include value="$includetags"> or that have <input name=includesubj value="$includesubj"> in their subject</td></tr>
-<tr><td>Exclude bugs tagged with </td><td><input name=exclude value="$excludetags"> or that have <input name=excludesubj value="$excludesubj"> in their subject</td></tr>
-<tr><td>Only show bugs older than</td><td><input name=mindays value="$vismindays" size=5> days, and younger than <input name=maxdays value="$vismaxdays" size=5> days</td></tr>
+<option value=raw$sel_ordraw>bug number only</option>
+<option value=old$sel_ordold>status and severity</option>
+<option value=normal$sel_ordnor>status, severity and classification</option>
+EOF
+
+{
+my $any = 0;
+my $o = $param{"ordering"} || "";
+for my $n (keys %cats) {
+ next if ($n eq "normal" || $n eq "oldview");
+ next if defined $hidden{$n};
+ unless ($any) {
+ $any = 1;
+ print "<option disabled>------</option>\n";
+ }
+ my @names = map { ref($_) eq "HASH" ? $_->{"nam"} : $_ } @{$cats{$n}};
+ my $name;
+ if (@names == 1) { $name = $names[0]; }
+ else { $name = " and " . pop(@names); $name = join(", ", @names) . $name; }
+
+ printf "<option value=\"%s\"%s>%s</option>\n",
+ $n, ($o eq $n ? " selected" : ""), $name;
+}
+}
+
+print "</select></td></tr>\n";
+
+printf "<tr><td>Order bugs by</td><td>%s</td></tr>\n",
+ pkg_htmlselectyesno("pend-rev", "outstanding bugs first", "done bugs first", $pend_rev);
+printf "<tr><td></td><td>%s</td></tr>\n",
+ pkg_htmlselectyesno("sev-rev", "highest severity first", "lowest severity first", $sev_rev);
+printf "<tr><td></td><td>%s</td></tr>\n",
+ pkg_htmlselectyesno("bug-rev", "oldest bugs first", "newest bugs first", $bug_rev);
+
+print <<EOF;
+<tr><td> </td></tr>
<tr><td colspan=2><input value="Reload page" type="submit"> with new settings</td></tr>
EOF
. "</strong>"
if (length($status{tags}));
- my @merged= split(/ /,$status{mergedwith});
- my $mseparator= ";\nMerged with ";
- for my $m (@merged) {
- $result .= $mseparator."<A class=\"submitter\" href=\"" . bugurl($m) . "\">#$m</A>";
- $mseparator= ", ";
- }
+ $result .= buglinklist(";\nMerged with ", ", ",
+ split(/ /,$status{mergedwith}));
+ $result .= buglinklist(";\nBlocked by ", ", ",
+ split(/ /,$status{blockedby}));
+ $result .= buglinklist(";\nBlocks ", ", ",
+ split(/ /,$status{blocks}));
my $days = 0;
if (length($status{done})) {
sub pkg_htmlizebugs {
$b = $_[0];
my @bugs = @$b;
- my $anydone = 0;
my @status = ();
my %count;
my $header = '';
my $footer = "<h2 class=\"outstanding\">Summary</h2>\n";
- my @dummy = ($debbugs::gRemoveAge, @debbugs::gSeverityList, @debbugs::gSeverityDisplay); #, $debbugs::gHTMLExpireNote);
+ my @dummy = ($debbugs::gRemoveAge); #, @debbugs::gSeverityList, @debbugs::gSeverityDisplay); #, $debbugs::gHTMLExpireNote);
if (@bugs == 0) {
return "<HR><H2>No reports found!</H2></HR>\n";
}
my %seenmerged;
- my @common_grouping = ( 'severity', 'pending' );
- my %common_grouping_order = (
- 'pending' => [ qw( pending forwarded pending-fixed fixed done absent ) ],
- 'severity' => \@debbugs::gSeverityList,
- );
- my %common_grouping_display = (
- 'pending' => 'Status',
- 'severity' => 'Severity',
- );
- my %common_headers = (
- 'pending' => {
- "pending" => "outstanding",
- "pending-fixed" => "pending upload",
- "fixed" => "fixed in NMU",
- "done" => "resolved",
- "forwarded" => "forwarded to upstream software authors",
- "absent" => "not applicable to this version",
- },
- 'severity' => \%debbugs::gSeverityDisplay,
- );
- my %common_reverse = ( 'pending' => $pend_rev, 'severity' => $sev_rev );
my %common = (
'show_list_header' => 1,
'show_list_footer' => 1,
);
- my $common_raw_sort = $raw_sort;
my %section = ();
my $html = sprintf "<li><a href=\"%s\">#%d: %s</a>\n<br>",
bugurl($bug), $bug, htmlsanit($status{subject});
$html .= pkg_htmlindexentrystatus(\%status) . "\n";
- my $key = join( '_', map( {$status{$_}} @common_grouping ) );
+
+ my $key = "";
+ for my $i (0..$#prior) {
+ my $v = get_bug_order_index($prior[$i], \%status);
+ $count{"g_${i}_${v}"}++;
+ $key .= "_$v";
+ }
$section{$key} .= $html;
$count{"_$key"}++;
- foreach my $grouping ( @common_grouping ) {
- $count{"${grouping}_$status{$grouping}"}++;
- }
- $anydone = 1 if $status{pending} eq 'done';
+
push @status, [ $bug, \%status, $html ];
}
my $result = "";
- if ($common_raw_sort) {
+ if ($ordering eq "raw") {
$result .= "<UL class=\"bugs\">\n" . join("", map( { $_->[ 2 ] } @status ) ) . "</UL>\n";
} else {
- my (@order, @headers);
- for( my $i = 0; $i < @common_grouping; $i++ ) {
- my $grouping_name = $common_grouping[ $i ];
- my @items = @{ $common_grouping_order{ $grouping_name } };
- @items = reverse( @items ) if ( $common_reverse{ $grouping_name } );
- my @neworder = ();
- my @newheaders = ();
- if ( @order ) {
- foreach my $grouping ( @items ) {
- push @neworder, map( { "${_}_$grouping" } @order );
- push @newheaders, map( { "$_ - $common_headers{$grouping_name}{$grouping}" } @headers );
- }
- @order = @neworder;
- @headers = @newheaders;
- } else {
- push @order, @items;
- push @headers, map( { $common_headers{$common_grouping[$i]}{$_} } @items );
- }
- }
- $header .= "<ul>\n<div class=\"msgreceived\">";
- for ( my $i = 0; $i < @order; $i++ ) {
- my $order = $order[ $i ];
+ $header .= "<ul>\n<div class=\"msgreceived\">\n";
+ my @keys_in_order = ("");
+ for my $o (@order) {
+ push @keys_in_order, "X";
+ while ((my $k = shift @keys_in_order) ne "X") {
+ for my $k2 (@{$o}) {
+ push @keys_in_order, "${k}_${k2}";
+ }
+ }
+ }
+ for ( my $i = 0; $i <= $#keys_in_order; $i++ ) {
+ my $order = $keys_in_order[ $i ];
next unless defined $section{$order};
+ my @ttl = split /_/, $order; shift @ttl;
+ my $title = $title[0]->[$ttl[0]] . " bugs";
+ if ($#ttl > 0) {
+ $title .= " -- ";
+ $title .= join("; ", grep {($_ || "") ne ""}
+ map { $title[$_]->[$ttl[$_]] } 1..$#ttl);
+ }
+ $title = htmlsanit($title);
+
my $count = $count{"_$order"};
my $bugs = $count == 1 ? "bug" : "bugs";
- $header .= "<li><a href=\"#$order\">$headers[$i]</a> ($count $bugs)</li>\n";
- }
- $header .= "</ul></div>\n";
- for ( my $i = 0; $i < @order; $i++ ) {
- my $order = $order[ $i ];
- next unless defined $section{$order};
+
+ $header .= "<li><a href=\"#$order\">$title</a> ($count $bugs)</li>\n";
if ($common{show_list_header}) {
my $count = $count{"_$order"};
my $bugs = $count == 1 ? "bug" : "bugs";
- $result .= "<H2 CLASS=\"outstanding\"><a name=\"$order\"></a>$headers[$i] ($count $bugs)</H2>\n";
+ $result .= "<H2 CLASS=\"outstanding\"><a name=\"$order\"></a>$title ($count $bugs)</H2>\n";
} else {
- $result .= "<H2 CLASS=\"outstanding\">$headers[$i]</H2>\n";
+ $result .= "<H2 CLASS=\"outstanding\">$title</H2>\n";
}
$result .= "<div class=\"msgreceived\">\n<UL class=\"bugs\">\n";
+ $result .= "\n\n\n\n";
$result .= $section{$order};
+ $result .= "\n\n\n\n";
$result .= "</UL>\n</div>\n";
}
+ $header .= "</ul></div>\n";
+
$footer .= "<ul>\n<div class=\"msgreceived\">";
- foreach my $grouping ( @common_grouping ) {
+ for my $i (0..$#prior) {
my $local_result = '';
- foreach my $key ( @{$common_grouping_order{ $grouping }} ) {
- my $count = $count{"${grouping}_$key"};
- next if !$count;
- $local_result .= "<li>$count $common_headers{$grouping}{$key}</li>\n";
+ foreach my $key ( @{$order[$i]} ) {
+ my $count = $count{"g_${i}_$key"};
+ next if !$count or !$title[$i]->[$key];
+ $local_result .= "<li>$count $title[$i]->[$key]</li>\n";
}
if ( $local_result ) {
- $footer .= "<li>$common_grouping_display{$grouping}<ul>\n$local_result</ul></li>\n";
+ $footer .= "<li>$names[$i]<ul>\n$local_result</ul></li>\n";
}
}
$footer .= "</div></ul>\n";
}
$result = $header . $result if ( $common{show_list_header} );
- #$result .= "<hr><p>" . $debbugs::gHTMLExpireNote if $debbugs::gRemoveAge and $anydone;
$result .= $footer if ( $common{show_list_footer} );
return $result;
}
return <<EOF ;
<script type="text/javascript">
<!--
+function pagemain() {
+ toggle(1);
+ toggle(2);
+ enable(1);
+}
+
+function setCookie(name, value, expires, path, domain, secure) {
+ var curCookie = name + "=" + escape(value) +
+ ((expires) ? "; expires=" + expires.toGMTString() : "") +
+ ((path) ? "; path=" + path : "") +
+ ((domain) ? "; domain=" + domain : "") +
+ ((secure) ? "; secure" : "");
+ document.cookie = curCookie;
+}
+
+function save_cat_cookies() {
+ var cat = document.categories.categorisation.value;
+ var exp = new Date();
+ exp.setTime(exp.getTime() + 10 * 365 * 24 * 60 * 60 * 1000);
+ var oldexp = new Date();
+ oldexp.setTime(oldexp.getTime() - 1 * 365 * 24 * 60 * 60 * 1000);
+ var lev;
+ var done = 0;
+
+ var u = document.getElementById("users");
+ if (u != null) { u = u.value; }
+ if (u == "") { u = null; }
+ if (u != null) {
+ setCookie("cat" + cat + "_users", u, exp, "/");
+ } else {
+ setCookie("cat" + cat + "_users", "", oldexp, "/");
+ }
+
+ var bits = new Array("nam", "pri", "ttl", "ord");
+ for (var i = 0; i < 4; i++) {
+ for (var j = 0; j < bits.length; j++) {
+ var e = document.getElementById(bits[j] + i);
+ if (e) e = e.value;
+ if (e == null) { e = ""; }
+ if (j == 0 && e == "") { done = 1; }
+ if (done || e == "") {
+ setCookie("cat" + cat + "_" + bits[j] + i, "", oldexp, "/");
+ } else {
+ setCookie("cat" + cat + "_" + bits[j] + i, e, exp, "/");
+ }
+ }
+ }
+}
function toggle(i) {
var a = document.getElementById("a_" + i);
EOF
}
+sub pkg_htmlselectyesno {
+ my ($name, $n, $y, $default) = @_;
+ return sprintf('<select name="%s"><option value=no%s>%s</option><option value=yes%s>%s</option></select>', $name, ($default ? "" : " selected"), $n, ($default ? " selected" : ""), $y);
+}
+
sub pkg_htmlselectsuite {
my $id = sprintf "b_%d_%d_%d", $_[0], $_[1], $_[2];
my @suites = ("stable", "testing", "unstable", "experimental");
return pkg_etc_url($severity, "severity", 0) if defined($severity);
return pkg_etc_url($tag, "tag", 0) if defined($tag);
}
+
+sub make_order_list {
+ my $vfull = shift;
+ my @x = ();
+
+ if ($vfull =~ m/^([^:]+):(.*)$/) {
+ my $v = $1;
+ for my $vv (split /,/, $2) {
+ push @x, "$v=$vv";
+ }
+ } else {
+ for my $v (split /,/, $vfull) {
+ next unless $v =~ m/.=./;
+ push @x, $v;
+ }
+ }
+ push @x, ""; # catch all
+ return @x;
+}
+
+sub get_bug_order_index {
+ my $order = shift;
+ my $status = shift;
+ my $pos = -1;
+
+ my %tags = ();
+ %tags = map { $_, 1 } split / /, $status->{"tags"}
+ if defined $status->{"tags"};
+
+ for my $el (@${order}) {
+ $pos++;
+ my $match = 1;
+ for my $item (split /[+]/, $el) {
+ my ($f, $v) = split /=/, $item, 2;
+ next unless (defined $f and defined $v);
+ my $isokay = 0;
+ $isokay = 1 if (defined $status->{$f} and $v eq $status->{$f});
+ $isokay = 1 if ($f eq "tag" && defined $tags{$v});
+ unless ($isokay) {
+ $match = 0;
+ last;
+ }
+ }
+ if ($match) {
+ return $pos;
+ last;
+ }
+ }
+ return $pos + 1;
+}
+
+sub buglinklist {
+ my ($prefix, $infix, @els) = @_;
+ my $sep = $prefix;
+ my $r = "";
+ for my $e (@els) {
+ $r .= $sep."<A class=\"submitter\" href=\"" . bugurl($e) . "\">#$e</A>";
+ $sep = $infix;
+ }
+ return $r;
+}
+
+
+# sets: my @names; my @prior; my @title; my @order;
+
+sub determine_ordering {
+ $cats{"status"}->{"ord"} = [ reverse @{$cats{"status"}->{"ord"}} ]
+ if ($pend_rev);
+ $cats{"severity"}->{"ord"} = [ reverse @{$cats{"severity"}->{"ord"}} ]
+ if ($sev_rev);
+
+ if (defined $param{"pri0"}) {
+ my @c = ();
+ my $i = 0;
+ while (defined $param{"pri$i"}) {
+ my $h = {};
+
+ my $pri = $param{"pri$i"};
+ if ($pri =~ m/^([^:]*):(.*)$/) {
+ $h->{"nam"} = $1; # overridden later if necesary
+ $h->{"pri"} = [ map { "$1=$_" } (split /,/, $2) ];
+ } else {
+ $h->{"pri"} = [ split /,/, $pri ];
+ }
+
+ $h->{"nam"} = $param{"nam$i"}
+ if (defined $param{"nam$i"});
+ $h->{"ord"} = [ split /,/, $param{"ord$i"} ]
+ if (defined $param{"ord$i"});
+ $h->{"ttl"} = [ split /,/, $param{"ttl$i"} ]
+ if (defined $param{"ttl$i"});
+
+ push @c, $h;
+ $i++;
+ }
+ $cats{"_"} = [@c];
+ $ordering = "_";
+ }
+
+ $ordering = "normal" unless defined $cats{$ordering};
+
+ sub get_ordering {
+ my @res;
+ my $cats = shift;
+ my $o = shift;
+ for my $c (@{$cats->{$o}}) {
+ if (ref($c) eq "HASH") {
+ push @res, $c;
+ } else {
+ push @res, get_ordering($cats, $c);
+ }
+ }
+ return @res;
+ }
+ my @cats = get_ordering(\%cats, $ordering);
+
+ sub toenglish {
+ my $expr = shift;
+ $expr =~ s/[+]/ and /g;
+ $expr =~ s/[a-z]+=//g;
+ return $expr;
+ }
+
+ my $i = 0;
+ for my $c (@cats) {
+ $i++;
+ push @prior, $c->{"pri"};
+ push @names, ($c->{"nam"} || "Bug attribute #" . $i);
+ if (defined $c->{"ord"}) {
+ push @order, $c->{"ord"};
+ } else {
+ push @order, [ 0..$#{$prior[-1]} ];
+ }
+ my @t = @{ $c->{"ttl"} } if defined $c->{ttl};
+ push @t, map { toenglish($prior[-1]->[$_]) } ($#t+1)..($#{$prior[-1]});
+ push @t, $c->{"def"} || "";
+ push @title, [@t];
+ }
+}