- my $showseverity;
- if ($status{severity} eq $config{default_severity}) {
- $showseverity = '';
- } elsif (isstrongseverity($status{severity})) {
- $showseverity = "Severity: <em class=\"severity\">$status{severity}</em>;\n";
- } else {
- $showseverity = "Severity: <em>$status{severity}</em>;\n";
- }
-
- $result .= htmlize_packagelinks($status{"package"}, 1);
-
- my $showversions = '';
- if (@{$status{found_versions}}) {
- my @found = @{$status{found_versions}};
- local $_;
- s{/}{ } foreach @found;
- $showversions .= join ', ', map html_escape($_), @found;
- }
- if (@{$status{fixed_versions}}) {
- $showversions .= '; ' if length $showversions;
- $showversions .= '<strong>fixed</strong>: ';
- my @fixed = @{$status{fixed_versions}};
- $showversions .= join ', ', map {s#/##; html_escape($_)} @fixed;
- }
- $result .= " ($showversions)" if length $showversions;
- $result .= ";\n";
-
- $result .= $showseverity;
- $result .= htmlize_addresslinks("Reported by: ", \&submitterurl,
- $status{originator});
- $result .= ";\nOwned by: " . html_escape($status{owner})
- if length $status{owner};
- $result .= ";\nTags: <strong>"
- . html_escape(join(", ", sort(split(/\s+/, $status{tags}))))
- . "</strong>"
- if (length($status{tags}));
-
- $result .= ";\nMerged with ".
- bug_linklist(', ',
- 'submitter',
- split(/ /,$status{mergedwith}))
- if length $status{mergedwith};
- $result .= ";\nBlocked by ".
- bug_linklist(", ",
- 'submitter',
- split(/ /,$status{blockedby}))
- if length $status{blockedby};
- $result .= ";\nBlocks ".
- bug_linklist(", ",
- 'submitter',
- split(/ /,$status{blocks})
- )
- if length $status{blocks};
-
- my $days = 0;
- if (length($status{done})) {
- $result .= "<br><strong>Done:</strong> " . html_escape($status{done});
- $days = ceil($debbugs::gRemoveAge - -M buglog($status{id}));
- if ($days >= 0) {
- $result .= ";\n<strong>Will be archived" . ( $days == 0 ? " today" : $days == 1 ? " in $days day" : " in $days days" ) . "</strong>";
- } else {
- $result .= ";\n<strong>Archived</strong>";
+=over
+
+=item package -- arrayref or scalar of package(s)
+
+=item submitter -- arrayref or scalar of submitter(s)
+
+=item src -- arrayref or scalar of source(s)
+
+=item maintainer -- arrayref or scalar of maintainer(s)
+
+=item links_only -- return only links, not htmlized links, defaults to
+returning htmlized links.
+
+=item class -- class of the a href, defaults to ''
+
+=back
+
+=cut
+
+our @package_search_key_order = (package => 'in package',
+ tag => 'tagged',
+ severity => 'with severity',
+ src => 'in source package',
+ maint => 'in packages maintained by',
+ submitter => 'submitted by',
+ owner => 'owned by',
+ status => 'with status',
+ affects => 'which affect package',
+ correspondent => 'with mail from',
+ newest => 'newest bugs',
+ bugs => 'in bug',
+ );
+our %package_search_keys = @package_search_key_order;
+our %package_links_invalid_options =
+ map {($_,1)} (keys %package_search_keys,
+ qw(msg att));
+
+sub package_links {
+ state $spec =
+ {(map { ($_,{type => SCALAR|ARRAYREF,
+ optional => 1,
+ });
+ } keys %package_search_keys,
+ ## these are aliases for package
+ ## search keys
+ source => {type => SCALAR|ARRAYREF,
+ optional => 1,
+ },
+ maintainer => {type => SCALAR|ARRAYREF,
+ optional => 1,
+ },
+ ),
+ links_only => {type => BOOLEAN,
+ default => 0,
+ },
+ class => {type => SCALAR,
+ default => '',
+ },
+ separator => {type => SCALAR,
+ default => ', ',
+ },
+ options => {type => HASHREF,
+ default => {},
+ },
+ };
+ my %param = validate_with(params => \@_,
+ spec => $spec,
+ );
+ my %options = %{$param{options}};
+ for (grep {$package_links_invalid_options{$_}} keys %options) {
+ delete $options{$_};
+ }
+ ## remove aliases for source and maintainer
+ if (exists $param{source}) {
+ $param{src} = [exists $param{src}?make_list($param{src}):(),
+ make_list($param{source}),
+ ];
+ delete $param{source};
+ }
+ if (exists $param{maintainer}) {
+ $param{maint} = [exists $param{maint}?make_list($param{maint}):(),
+ make_list($param{maintainer}),
+ ];
+ delete $param{maintainer};
+ }
+ my $has_options = keys %options;
+ my @links = ();
+ for my $type (qw(src package)) {
+ next unless exists $param{$type};
+ for my $target (make_list($param{$type})) {
+ my $t_type = $type;
+ if ($target =~ s/^src://) {
+ $t_type = 'source';
+ } elsif ($t_type eq 'source') {
+ $target = 'src:'.$target;
+ }
+ if ($has_options) {
+ push @links,
+ (munge_url('pkgreport.cgi?',
+ %options,
+ $t_type => $target,
+ ),
+ $target);
+ } else {
+ push @links,
+ ('pkgreport.cgi?'.$t_type.'='.uri_escape_utf8($target),
+ $target);
+ }
+ }
+ }
+ for my $type (qw(maint owner submitter correspondent)) {
+ next unless exists $param{$type};
+ for my $target (make_list($param{$type})) {
+ if ($has_options) {
+ push @links,
+ (munge_url('pkgreport.cgi?',
+ %options,
+ $type => $target),
+ $target);
+ } else {
+ push @links,
+ ('pkgreport.cgi?'.
+ $type.'='.uri_escape_utf8($target),
+ $target);
+ }
+ }
+ }
+ my @return = ();
+ my ($link,$link_name);
+ my $class = '';
+ if (length $param{class}) {
+ $class = q( class=").html_escape($param{class}).q(");
+ }
+ while (($link,$link_name) = splice(@links,0,2)) {
+ if ($param{links_only}) {
+ push @return,$link