]> git.donarmstrong.com Git - debbugs.git/commitdiff
Merge branch 'database'
authorDon Armstrong <don@donarmstrong.com>
Fri, 16 Mar 2018 00:14:56 +0000 (17:14 -0700)
committerDon Armstrong <don@donarmstrong.com>
Fri, 16 Mar 2018 00:14:56 +0000 (17:14 -0700)
118 files changed:
.bzrignore [deleted file]
.travis.yml
.travis/Dockerfile [new file with mode: 0644]
Debbugs/CGI.pm
Debbugs/CGI/Pkgreport.pm
Debbugs/Command.pm [new file with mode: 0644]
Debbugs/Control.pm
Debbugs/Log/Spam.pm
Debbugs/SOAP.pm
Debbugs/Status.pm
Debbugs/Text.pm
Debbugs/Text/XslateBridge.pm [new file with mode: 0644]
Debbugs/UTF8.pm
Makefile
UPGRADE [deleted file]
UPGRADE.md [new file with mode: 0644]
bin/debbugs-spam [new file with mode: 0755]
bin/debbugs-spamscan-log [deleted file]
bin/local-debbugs
debian/changelog
debian/control
debian/copyright
examples/debian/versions/build-versions-db
examples/debian/versions/merge-one-version
future_directions [deleted file]
html/bugs.css
html/logo/.gitignore [new file with mode: 0644]
html/logo/Makefile [new file with mode: 0644]
html/logo/debbugs_logo.svg [new file with mode: 0644]
html/logo/debbugs_logo_orig.svg [new file with mode: 0644]
scripts/process
scripts/service
t/12_merge.t
t/lib/DebbugsTest.pm
templates/en_US/cgi/bugreport.tmpl [deleted file]
templates/en_US/cgi/bugreport.tx [new file with mode: 0644]
templates/en_US/cgi/bugreport_buginfo.tmpl [deleted file]
templates/en_US/cgi/bugreport_buginfo.tx [new file with mode: 0644]
templates/en_US/cgi/bugreport_pkginfo.tmpl [deleted file]
templates/en_US/cgi/bugreport_pkginfo.tx [new file with mode: 0644]
templates/en_US/cgi/no_such_bug.tmpl [deleted file]
templates/en_US/cgi/no_such_bug.tx [new file with mode: 0644]
templates/en_US/cgi/pkgindex.tmpl [deleted file]
templates/en_US/cgi/pkgindex.tx [new file with mode: 0644]
templates/en_US/cgi/pkgreport_javascript.tmpl [deleted file]
templates/en_US/cgi/pkgreport_javascript.tx [new file with mode: 0644]
templates/en_US/cgi/pkgreport_options.tmpl [deleted file]
templates/en_US/cgi/pkgreport_options.tx [new file with mode: 0644]
templates/en_US/cgi/pkgreport_options_include_exclude.tmpl [deleted file]
templates/en_US/cgi/pkgreport_options_include_exclude.tx [new file with mode: 0644]
templates/en_US/cgi/pkgreport_options_include_exclude_key.tmpl [deleted file]
templates/en_US/cgi/pkgreport_options_include_exclude_key.tx [new file with mode: 0644]
templates/en_US/cgi/pkgreport_options_search_key.tmpl [deleted file]
templates/en_US/cgi/pkgreport_options_search_key.tx [new file with mode: 0644]
templates/en_US/cgi/quit.tmpl [deleted file]
templates/en_US/cgi/quit.tx [new file with mode: 0644]
templates/en_US/cgi/short_bug_status.tmpl [deleted file]
templates/en_US/cgi/short_bug_status.tx [new file with mode: 0644]
templates/en_US/html/html_tail.tmpl [deleted file]
templates/en_US/html/html_tail.tx [new file with mode: 0644]
templates/en_US/html/post_title.tmpl [deleted file]
templates/en_US/html/post_title.tx [new file with mode: 0644]
templates/en_US/html/pre_title.tmpl [deleted file]
templates/en_US/html/pre_title.tx [new file with mode: 0644]
templates/en_US/mail/excluded_from_control.tmpl [deleted file]
templates/en_US/mail/excluded_from_control.tx [new file with mode: 0644]
templates/en_US/mail/fake_control_message.tmpl [deleted file]
templates/en_US/mail/fake_control_message.tx [new file with mode: 0644]
templates/en_US/mail/footer.tmpl [deleted file]
templates/en_US/mail/footer.tx [new file with mode: 0644]
templates/en_US/mail/forward_maintonly.tmpl [deleted file]
templates/en_US/mail/forward_maintonly.tx [new file with mode: 0644]
templates/en_US/mail/forward_normal.tmpl [deleted file]
templates/en_US/mail/forward_normal.tx [new file with mode: 0644]
templates/en_US/mail/forward_veryquiet.tmpl [deleted file]
templates/en_US/mail/forward_veryquiet.tx [new file with mode: 0644]
templates/en_US/mail/header.tmpl [deleted file]
templates/en_US/mail/header.tx [new file with mode: 0644]
templates/en_US/mail/invalid_maintainer.tmpl [deleted file]
templates/en_US/mail/invalid_maintainer.tx [new file with mode: 0644]
templates/en_US/mail/invalid_severity.tmpl [deleted file]
templates/en_US/mail/invalid_severity.tx [new file with mode: 0644]
templates/en_US/mail/invalid_user.tmpl [deleted file]
templates/en_US/mail/invalid_user.tx [new file with mode: 0644]
templates/en_US/mail/invalid_version.tmpl [deleted file]
templates/en_US/mail/invalid_version.tx [new file with mode: 0644]
templates/en_US/mail/maintainercc.tmpl [deleted file]
templates/en_US/mail/maintainercc.tx [new file with mode: 0644]
templates/en_US/mail/message_body.tmpl [deleted file]
templates/en_US/mail/message_body.tx [new file with mode: 0644]
templates/en_US/mail/process_ack.tmpl [deleted file]
templates/en_US/mail/process_ack.tx [new file with mode: 0644]
templates/en_US/mail/process_ack_thanks_additional.tmpl [deleted file]
templates/en_US/mail/process_ack_thanks_additional.tx [new file with mode: 0644]
templates/en_US/mail/process_ack_thanks_new.tmpl [deleted file]
templates/en_US/mail/process_ack_thanks_new.tx [new file with mode: 0644]
templates/en_US/mail/process_broken_subject.tmpl [deleted file]
templates/en_US/mail/process_broken_subject.tx [new file with mode: 0644]
templates/en_US/mail/process_default_package_selected.tmpl [deleted file]
templates/en_US/mail/process_default_package_selected.tx [new file with mode: 0644]
templates/en_US/mail/process_mark_as_done.tmpl [deleted file]
templates/en_US/mail/process_mark_as_done.tx [new file with mode: 0644]
templates/en_US/mail/process_mark_as_forwarded.tmpl [deleted file]
templates/en_US/mail/process_mark_as_forwarded.tx [new file with mode: 0644]
templates/en_US/mail/process_no_bug_number.tmpl [deleted file]
templates/en_US/mail/process_no_bug_number.tx [new file with mode: 0644]
templates/en_US/mail/process_no_package.tmpl [deleted file]
templates/en_US/mail/process_no_package.tx [new file with mode: 0644]
templates/en_US/mail/process_unknown_bug_number.tmpl [deleted file]
templates/en_US/mail/process_unknown_bug_number.tx [new file with mode: 0644]
templates/en_US/mail/process_your_bug_done.tmpl [deleted file]
templates/en_US/mail/process_your_bug_done.tx [new file with mode: 0644]
templates/en_US/mail/serious_mail_misconfiguration.tmpl [deleted file]
templates/en_US/mail/serious_mail_misconfiguration.tx [new file with mode: 0644]
templates/en_US/mail/submitter_changed.tmpl [deleted file]
templates/en_US/mail/submitter_changed.tx [new file with mode: 0644]
templates/en_US/mail/xdebbugscc.tmpl [deleted file]
templates/en_US/mail/xdebbugscc.tx [new file with mode: 0644]

diff --git a/.bzrignore b/.bzrignore
deleted file mode 100644 (file)
index 0b9634c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Makefile.perl
-Makefile.perl.old
-build-stamp
-install-stamp
index b6f1be88d0699534d8be5e2e7b4c4fb77a657fca..418ae83f6df9eb9190b38d8f5521f08566697114 100644 (file)
@@ -1,12 +1,11 @@
 dist: trusty
+services:
+  - docker
 sudo: required
 before_install:
-  - sudo apt-get -qq update
-  - sudo apt-get install -y devscripts equivs
-  - dch -r -m ''
-  - mk-build-deps -s sudo -i debian/control
+  - docker build -t debbugs/travis -f .travis/Dockerfile .
 script:
-  - make; make test
+  - docker run debbugs/travis sh -c 'cd /debbugs/; make; make test'
 notifications:
   irc:
     channels:
diff --git a/.travis/Dockerfile b/.travis/Dockerfile
new file mode 100644 (file)
index 0000000..e4bfa95
--- /dev/null
@@ -0,0 +1,15 @@
+FROM debian:stable-slim
+RUN apt-get -qq update; \
+ apt-get install --no-install-recommends -y devscripts equivs; \
+ rm -rf /var/lib/apt/lists/*; \
+ apt-get clean;
+COPY debian/control debian/control
+COPY debian/changelog debian/changelog
+RUN dch -r -m '';
+RUN apt-get -qq update; \
+ mk-build-deps --install \
+ --tool 'apt-get -y -o Debug:pkgProblemResolver=yes --no-install-recommends' \
+ debian/control; \
+ rm -rf /var/lib/apt/lists/*; \
+ apt-get clean;
+COPY . debbugs
\ No newline at end of file
index 0f44943a6bf5c427d44277685f7bc7c08c2321eb..a80397f4ed18524069cbd3c3137e79f964a9d41e 100644 (file)
@@ -34,29 +34,10 @@ use strict;
 use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
 use Exporter qw(import);
 
-use Debbugs::URI;
-use HTML::Entities;
-use Debbugs::Common qw(getparsedaddrs make_list);
-use Params::Validate qw(validate_with :types);
-
-use Debbugs::Config qw(:config);
-use Debbugs::Status qw(splitpackages isstrongseverity);
-use Debbugs::User qw();
-
-use Mail::Address;
-use POSIX qw(ceil);
-use Storable qw(dclone);
-
-use List::AllUtils qw(max);
-use File::stat;
-use Digest::MD5 qw(md5_hex);
-use Carp;
-
-use Debbugs::Text qw(fill_in_template);
+use feature qw(state);
 
 our %URL_PARAMS = ();
 
-
 BEGIN{
      ($VERSION) = q$Revision: 1.3 $ =~ /^Revision:\s+([^\s+])/;
      $DEBUG = 0 unless defined $DEBUG;
@@ -84,6 +65,27 @@ BEGIN{
      $EXPORT_TAGS{all} = [@EXPORT_OK];
 }
 
+use Debbugs::URI;
+use URI::Escape;
+use HTML::Entities;
+use Debbugs::Common qw(getparsedaddrs make_list);
+use Params::Validate qw(validate_with :types);
+
+use Debbugs::Config qw(:config);
+use Debbugs::Status qw(splitpackages isstrongseverity);
+use Debbugs::User qw();
+
+use Mail::Address;
+use POSIX qw(ceil);
+use Storable qw(dclone);
+
+use List::AllUtils qw(max);
+use File::stat;
+use Digest::MD5 qw(md5_hex);
+use Carp;
+
+use Debbugs::Text qw(fill_in_template);
+
 
 
 =head2 set_url_params
@@ -327,65 +329,101 @@ our @package_search_key_order = (package   => 'in package',
                                 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   => {(map { ($_,{type => SCALAR|ARRAYREF,
-                                                     optional => 1,
-                                                    });
-                                           } keys %package_search_keys,
-                                         ),
-                                         links_only => {type => BOOLEAN,
-                                                        default => 0,
-                                                       },
-                                         class => {type => SCALAR,
-                                                   default => '',
-                                                  },
-                                         separator => {type => SCALAR,
-                                                       default => ', ',
-                                                      },
-                                         options => {type => HASHREF,
-                                                     default => {},
-                                                    },
-                                        },
-                              normalize_keys =>
-                              sub {
-                                   my ($key) = @_;
-                                   my %map = (source => 'src',
-                                              maintainer => 'maint',
-                                              pkg        => 'package',
-                                             );
-                                   return $map{$key} if exists $map{$key};
-                                   return $key;
-                              }
+                              spec   => $spec,
                              );
      my %options = %{$param{options}};
-     for ((keys %package_search_keys,qw(msg att))) {
-         delete $options{$_} if exists $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)) {
-         push @links, map {my $t_type = $type;
-                           if ($_ =~ s/^src://) {
-                               $t_type = 'src';
-                           }
-                           (munge_url('pkgreport.cgi?',
-                                      %options,
-                                      $t_type => $_,
-                                     ),
-                            ($t_type eq 'src'?'src:':'').$_);
-                      } make_list($param{$type}) if exists $param{$type};
+        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)) {
-         push @links, map {my $addr = getparsedaddrs($_);
-                           $addr = defined $addr?$addr->address:'';
-                           (munge_url('pkgreport.cgi?',
-                                      %options,
-                                      $type => $addr,
-                                     ),
-                            $_);
-                      } make_list($param{$type}) if exists $param{$type};
+        next unless exists $param{$type};
+        for my $target (make_list($param{$type})) {
+            my $addr = getparsedaddrs($target);
+            $addr = defined $addr?$addr->address:'';
+            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);
@@ -455,13 +493,20 @@ sub bug_links {
      for (qw(bug)) {
          delete $options{$_} if exists $options{$_};
      }
+     my $has_options = keys %options;
      my @links;
-     push @links, map {(munge_url('bugreport.cgi?',
-                                 %options,
-                                 bug => $_,
-                                ),
-                       $_);
-                 } make_list($param{bug}) if exists $param{bug};
+     if ($has_options) {
+        push @links, map {(munge_url('bugreport.cgi?',
+                                     %options,
+                                     bug => $_,
+                                    ),
+                           $_);
+                      } make_list($param{bug}) if exists $param{bug};
+     } else {
+        push @links, map {('bugreport.cgi?bug='.uri_escape_utf8($_),
+                           $_)}
+            make_list($param{bug}) if exists $param{bug};
+     }
      my @return;
      my ($link,$link_name);
      my $class = '';
@@ -576,7 +621,7 @@ sub emailfromrfc822{
      return $addr;
 }
 
-sub mainturl { package_links(maint => $_[0], links_only => 1); }
+sub mainturl { package_links(maintainer => $_[0], links_only => 1); }
 sub submitterurl { package_links(submitter => $_[0], links_only => 1); }
 sub htmlize_maintlinks {
     my ($prefixfunc, $maints) = @_;
@@ -821,23 +866,6 @@ sub option_form{
          # we'll add extra comands here once I figure out what they
          # should be
      }
-     # add in a few utility routines
-     $variables->{output_select_options} = sub {
-         my ($options,$value) = @_;
-         my @options = @{$options};
-         my $output = '';
-         while (my ($o_value,$name) = splice @options,0,2) {
-              my $selected = '';
-              if (defined $value and $o_value eq $value) {
-                   $selected = ' selected';
-              }
-              $output .= q(<option value=").html_escape($o_value).qq("$selected>).
-                  html_escape($name).qq(</option>\n);
-         }
-         return $output;
-     };
-     $variables->{make_list} = sub { make_list(@_);
-     };
      # now at this point, we're ready to create the template
      return Debbugs::Text::fill_in_template(template=>$param{template},
                                            (exists $param{language}?(language=>$param{language}):()),
index 078fecaa69844f0fe3fbcd5ea803d14be7eb2c2c..060e980a9088cec144ef3fdb1e00d8c90550d67f 100644 (file)
@@ -103,7 +103,7 @@ sub generate_package_info{
          print {$output} '<p>';
          print {$output} (($maint =~ /,/)? "Maintainer for $showpkg is "
                           : "Maintainers for $showpkg are ") .
-                               package_links(maint => $maint);
+                               package_links(maintainer => $maint);
          print {$output} ".</p>\n";
      }
      else {
@@ -353,12 +353,14 @@ sub pkg_htmlizebugs {
          push @{$exclude{$key}}, split /\s*,\s*/, $value;
      }
 
+     my $binary_to_source_cache = {};
      foreach my $bug (@bugs) {
         my %status = %{get_bug_status(bug=>$bug,
                                       (map {exists $param{$_}?($_,$param{$_}):()}
                                        qw(dist version schema bugusertags)
                                       ),
                                        (exists $param{arch}?(arch => $param{arch}):(arch => $config{default_architectures})),
+                                       binary_to_source_cache => $binary_to_source_cache,
                                       )};
          next unless %status;
          next if bug_filter(bug => $bug,
diff --git a/Debbugs/Command.pm b/Debbugs/Command.pm
new file mode 100644 (file)
index 0000000..c68dd70
--- /dev/null
@@ -0,0 +1,101 @@
+# This module is part of debbugs, and is released under the terms of
+# the GPL version 3, or any later version (at your option). See the
+# file README and COPYING for more information.
+# Copyright 2017 by Don Armstrong <don@donarmstrong.com>.
+
+package Debbugs::Command;
+
+=head1 NAME
+
+Debbugs::Command -- Handle multiple subcommand-style commands
+
+=head1 SYNOPSIS
+
+ use Debbugs::Command;
+
+=head1 DESCRIPTION
+
+
+=head1 BUGS
+
+None known.
+
+=cut
+
+use warnings;
+use strict;
+use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
+use base qw(Exporter);
+
+BEGIN{
+     $VERSION = '0.1';
+     $DEBUG = 0 unless defined $DEBUG;
+
+     @EXPORT = ();
+     %EXPORT_TAGS = (commands    => [qw(handle_main_arguments),
+                                     qw(handle_subcommand_arguments)
+                                    ],
+                   );
+     @EXPORT_OK = ();
+     Exporter::export_ok_tags(keys %EXPORT_TAGS);
+     $EXPORT_TAGS{all} = [@EXPORT_OK];
+
+}
+
+use Getopt::Long qw(:config no_ignore_case);
+use Pod::Usage qw(pod2usage);
+
+=head1 Command processing (:commands)
+
+Functions which parse arguments for commands (exportable with
+C<:commands>)
+
+=over
+
+=item handle_main_arguments(
+
+=cut 
+
+sub handle_main_arguments {
+    my ($options,@args) = @_;
+    Getopt::Long::Configure('pass_through');
+    GetOptions($options,@args);
+    Getopt::Long::Configure('default');
+    return $options;
+}
+
+
+
+sub handle_subcommand_arguments {
+    my ($argv,$args,$subopt) = @_;
+    $subopt //= {};
+    Getopt::Long::GetOptionsFromArray($argv,
+                                      $subopt,
+                                      keys %{$args},
+                                     );
+    my @usage_errors;
+    for my $arg  (keys %{$args}) {
+        next unless $args->{$arg};
+        my $r_arg = $arg; # real argument name
+        $r_arg =~ s/[=\|].+//g;
+        if (not defined $subopt->{$r_arg}) {
+            push @usage_errors, "You must give a $r_arg option";
+        }
+    }
+    pod2usage(join("\n",@usage_errors)) if @usage_errors;
+    return $subopt;
+}
+
+=back
+
+=cut
+
+
+1;
+
+
+__END__
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
index ab6038426da841bd8bd20f0db31728d9a4f75b9b..1f8b3aac60d3cb98fe5264795fc7806e795c4bac 100644 (file)
@@ -364,7 +364,7 @@ sub set_blocks {
        next if $ok_blockers{$blocker} or $bad_blockers{$blocker};
        my $data = read_bug(bug=>$blocker,
                           );
-       if (defined $data and not $data->{archive}) {
+       if (defined $data and not $data->{archived}) {
            $data = split_status_fields($data);
            $ok_blockers{$blocker} = 1;
            my @merged_bugs;
@@ -379,15 +379,17 @@ sub set_blocks {
     # throw an error if we are setting the blockers and there is a bad
     # blocker
     if (keys %bad_blockers and $mode eq 'set') {
-       croak "Unknown blocking bug(s):".join(', ',keys %bad_blockers).
-           keys %ok_blockers?'':" and no known blocking bug(s)";
+       __end_control(%info);
+       croak "Unknown/archived blocking bug(s):".join(', ',keys %bad_blockers).
+           keys %ok_blockers?'':" and no good blocking bug(s)";
     }
     # if there are no ok blockers and we are not setting the blockers,
     # there's an error.
     if (not keys %ok_blockers and $mode ne 'set') {
        print {$transcript} "No valid blocking bug(s) given; not doing anything\n";
        if (keys %bad_blockers) {
-           croak "Unknown blocking bug(s):".join(', ',keys %bad_blockers);
+           __end_control(%info);
+           croak "Unknown/archived blocking bug(s):".join(', ',keys %bad_blockers);
        }
        __end_control(%info);
        return;
@@ -410,6 +412,7 @@ sub set_blocks {
     @bugs{@bugs} = (1) x @bugs;
     for my $blocker (@change_blockers) {
        if ($bugs{$blocker}) {
+           __end_control(%info);
            croak "It is nonsensical for a bug to block itself (or a merged partner): $blocker";
        }
     }
@@ -2070,9 +2073,11 @@ sub set_merged {
                print {$transcript} "$change->{field} of #$change->{bug} is '$change->{text_orig_value}' not '$change->{text_value}'\n";
            }
            if ($attempts > 0) {
+               __end_control(%info);
                croak "Some bugs were altered while attempting to merge";
            }
            else {
+               __end_control(%info);
                croak "Did not alter merged bugs";
            }
        }
@@ -2084,6 +2089,7 @@ sub set_merged {
                $param{show_bug_info} and not __internal_request(1);
            $bug_info_shown{$change_bug} = 1;
            __allow_relocking($param{locks},[keys %data]);
+           eval {
            for my $change (@{$changes->{$change_bug}}) {
                if ($change->{field} eq 'blockedby' or $change->{field} eq 'blocks') {
                    my %target_blockedby;
@@ -2120,6 +2126,12 @@ sub set_merged {
                                         );
                }
            }
+       };
+           if ($@) {
+               __disallow_relocking($param{locks});
+               __end_control(%info);
+               croak "Failure while trying to adjust bugs, please report this as a bug: $@";
+           }
            __disallow_relocking($param{locks});
            my ($data,$n_locks) =
                __lock_and_load_merged_bugs(bugs_to_load => [keys %merging],
@@ -2286,13 +2298,22 @@ sub __calculate_merge_status{
            $merged_bugs{$data->{bug_num}} = 1;
            $bugs_to_merge = 1;
        }
+    }
+    for my $data (@{$data_a}) {
        # the master_bug is the bug that every other bug is made to
        # look like. However, if merge is set, tags, fixed and found
        # are merged.
        if ($data->{bug_num} == $master_bug) {
-           for (qw(package forwarded severity blocks blockedby done owner summary outlook affects)) {
+           for (qw(package forwarded severity done owner summary outlook affects)) {
                $merge_status{$_} = $data->{$_}
            }
+           # bugs which are in the newly merged set and are also
+           # blocks/blockedby must be removed before merging
+           for (qw(blocks blockedby)) {
+               $merge_status{$_} =
+                   join(' ',grep {not exists $merged_bugs{$_}}
+                        split / /,$data->{$_});
+           }
        }
        if (defined $merge_status) {
            next unless $data->{bug_num} == $master_bug;
@@ -2770,7 +2791,8 @@ sub _summary {
                                 \#|reopen|close|(?:not|)(?:fixed|found)|clone|
                                 debug|(?:not|)forwarded|priority|
                                 (?:un|)block|limit|(?:un|)archive|
-                                reassign|retitle|affects|wrongpackage
+                                reassign|retitle|affects|package|
+                                outlook|
                                 (?:un|force|)merge|user(?:category|tags?|)
                             )\s+\S}xis) {
                   if (not length $paragraph) {
@@ -3224,6 +3246,15 @@ sub bug_unarchive {
      my @bugs = @{$info{bugs}};
      my $action = "$config{bug} unarchived.";
      my @files_to_remove;
+     ## error out if we're unarchiving unarchived bugs
+     for my $data (@{$info{data}}) {
+        if (not defined $data->{archived} or
+            not $data->{archived}
+           ) {
+            __end_control(%info);
+            croak("Bug $data->{bug_num} was not archived; not unarchiving it.");
+        }
+     }
      for my $bug (@bugs) {
          print {$debug} "$param{bug} removing $bug\n";
          my $dir = get_hashname($bug);
index a2fe44cdc47bc88af76241d2026ffe20a953767d..e5ed18f1c8f4441890f62b8a134797807313a315 100644 (file)
@@ -122,7 +122,11 @@ sub _init {
         binmode($fh,':encoding(UTF-8)');
         while (<$fh>) {
             chomp;
-            $self->{spam}{$_} = 1;
+            if (s/\sham$//) {
+                $self->{spam}{$_} = '0';
+            } else {
+                $self->{spam}{$_} = '1';
+            }
         }
         close ($fh) or
             croak "Unable to close bug log filehandle: $!";
@@ -132,7 +136,10 @@ sub _init {
             croak "Unable to open bug log spamdir '$self->{name}.d' for reading: $!";
         for my $dir (readdir($d)) {
             next unless $dir =~ m/([^\.].*)_(\w+)$/;
-            $self->{spam}{$1} = 1;
+            # .spam overrides .spam.d
+            next if exists $self->{spam}{$1};
+            # set the spam HASH to $dir so we know where this value was set from
+            $self->{spam}{$1} = $dir;
         }
         closedir($d) or
             croak "Unable to close bug log spamdir: $!";
@@ -142,7 +149,7 @@ sub _init {
 
 =item save
 
-$self->save();
+C<$spam_log->save();>
 
 Saves changes to the bug log spam file.
 
@@ -156,7 +163,16 @@ sub save {
         croak "Unable to open bug log spam '$self->{name}.tmp' for writing: $!";
     binmode($fh,':encoding(UTF-8)');
     for my $msgid (keys %{$self->{spam}}) {
-        print {$fh} $msgid."\n";
+        # was this message set to spam/ham by .d? If so, don't save it
+        if ($self->{spam}{$msgid} ne '0' and
+            $self->{spam}{$msgid} ne '1') {
+            next;
+        }
+        print {$fh} $msgid;
+        if ($self->{spam}{$msgid} eq '0') {
+            print {$fh} ' ham';
+        }
+        print {$fh} "\n";
     }
     close($fh) or croak "Unable to write to '$self->{name}.tmp': $!";
     rename($self->{name}.'.tmp',$self->{name});
@@ -165,11 +181,11 @@ sub save {
 
 =item is_spam
 
-    next if ($spam_log->is_spam('12456@exmaple.com'));
+C<next if ($spam_log->is_spam('12456@exmaple.com'));>
 
 Returns 1 if this message id confirms that the message is spam
 
-Returns 0 if this message is not spam
+Returns 0 if this message is not known to be spam
 
 =cut
 sub is_spam {
@@ -177,29 +193,78 @@ sub is_spam {
     return 0 if not defined $msgid or not length $msgid;
     $msgid =~ s/^<|>$//;
     if (exists $self->{spam}{$msgid} and
-        $self->{spam}{$msgid}
+        $self->{spam}{$msgid} ne '0'
+       ) {
+        return 1;
+    }
+    return 0;
+}
+
+=item is_ham
+
+    next if ($spam_log->is_ham('12456@exmaple.com'));
+
+Returns 1 if this message id confirms that the message is ham
+
+Returns 0 if this message is not known to be ham
+
+=cut
+sub is_ham {
+    my ($self,$msgid) = @_;
+    return 0 if not defined $msgid or not length $msgid;
+    $msgid =~ s/^<|>$//;
+    if (exists $self->{spam}{$msgid} and
+        $self->{spam}{$msgid} eq '0'
        ) {
         return 1;
     }
     return 0;
 }
 
+
 =item add_spam
 
     $spam_log->add_spam('123456@example.com');
 
 Add a message id to the spam listing.
 
-You must call C<$self->save()> if you wish the changes to be written out to disk.
+You must call C<$spam_log->save()> if you wish the changes to be written out to disk.
 
 =cut
 
 sub add_spam {
     my ($self,$msgid) = @_;
     $msgid =~ s/^<|>$//;
-    $self->{spam}{$msgid} = 1;
+    $self->{spam}{$msgid} = '1';
 }
 
+=item add_ham
+
+    $spam_log->add_ham('123456@example.com');
+
+Add a message id to the ham listing.
+
+You must call C<$spam_log->save()> if you wish the changes to be written out to disk.
+
+=cut
+
+sub add_ham {
+    my ($self,$msgid) = @_;
+    $msgid =~ s/^<|>$//;
+    $self->{spam}{$msgid} = '0';
+}
+
+=item remove_message
+
+     $spam_log->remove_message('123456@example.com');
+
+Remove a message from the spam/ham listing.
+
+You must call C<$spam_log->save()> if you wish the changes to be written out to disk.
+
+=cut
+
+
 1;
 
 =back
index 9ed0249b863731504e1975eb105edd90a34abfe3..a0c3cbf2190d06ea3f5b04dfb9d9278039929990 100644 (file)
@@ -127,6 +127,7 @@ sub get_status {
              @bugs = @{$bugs[0]};
      }
      my %status;
+     my %binary_to_source_cache;
      for my $bug (@bugs) {
          my $bug_status;
          if (ref($bug)) {
@@ -134,11 +135,14 @@ sub get_status {
               next unless defined $param{bug};
               $bug = $param{bug};
               $bug_status = get_bug_status(map {(exists $param{$_})?($_,$param{$_}):()}
-                                           qw(bug dist arch bugusertags sourceversions version indicatesource)
+                                           qw(bug dist arch bugusertags sourceversions version indicatesource),
+                                           binary_to_source_cache => \%binary_to_source_cache,
                                           );
          }
          else {
-              $bug_status = get_bug_status(bug => $bug);
+             $bug_status = get_bug_status(bug => $bug,
+                                          binary_to_source_cache => \%binary_to_source_cache,
+                                         );
          }
          if (defined $bug_status and keys %{$bug_status} > 0) {
               $status{$bug}  = $bug_status;
index 7af7fcf1dfd057dd5a5fa3311c8a0f0216bb6c4c..9d047a40b053a6867d4b10b24d0486c88e6c8a1e 100644 (file)
@@ -33,6 +33,8 @@ status of a particular bug
 use warnings;
 use strict;
 
+use feature 'state';
+
 use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
 use Exporter qw(import);
 
@@ -165,27 +167,27 @@ sub read_bug{
     if (@_ == 1) {
         unshift @_, 'bug';
     }
+    state $spec =
+       {bug => {type => SCALAR,
+               optional => 1,
+               # something really stupid passes negative bugnumbers
+               regex    => qr/^-?\d+/,
+              },
+       location => {type => SCALAR|UNDEF,
+                    optional => 1,
+                   },
+       summary  => {type => SCALAR,
+                    optional => 1,
+                   },
+       lock     => {type => BOOLEAN,
+                    optional => 1,
+                   },
+       locks    => {type => HASHREF,
+                    optional => 1,
+                   },
+       };
     my %param = validate_with(params => \@_,
-                             spec   => {bug => {type => SCALAR,
-                                                optional => 1,
-                                                # something really
-                                                # stupid passes
-                                                # negative bugnumbers
-                                                regex    => qr/^-?\d+/,
-                                               },
-                                        location => {type => SCALAR|UNDEF,
-                                                     optional => 1,
-                                                    },
-                                        summary  => {type => SCALAR,
-                                                     optional => 1,
-                                                    },
-                                        lock     => {type => BOOLEAN,
-                                                     optional => 1,
-                                                    },
-                                        locks    => {type => HASHREF,
-                                                     optional => 1,
-                                                    },
-                                       },
+                             spec   => $spec,
                             );
     die "One of bug or summary must be passed to read_bug"
         if not exists $param{bug} and not exists $param{summary};
@@ -230,15 +232,19 @@ sub read_bug{
 
     my %data;
     my @lines;
-    my $version = 2;
+    my $version;
     local $_;
 
     while (<$status_fh>) {
         chomp;
         push @lines, $_;
-        $version = $1 if /^Format-Version: ([0-9]+)/i;
+       if (not defined $version and
+           /^Format-Version: ([0-9]+)/i
+          ) {
+           $version = $1;
+       }
     }
-
+    $version = 2 if not defined $version;
     # Version 3 is the latest format version currently supported.
     if ($version > 3) {
         warn "Unsupported status version '$version'";
@@ -248,7 +254,7 @@ sub read_bug{
         return undef;
     }
 
-    my %namemap = reverse %fields;
+    state $namemap = {reverse %fields};
     for my $line (@lines) {
         if ($line =~ /(\S+?): (.*)/) {
             my ($name, $value) = (lc $1, $2);
@@ -256,7 +262,7 @@ sub read_bug{
            # or \n in the fields of status. Kill them off here.
            # [Eventually, this should be superfluous.]
            $value =~ s/[\r\n]//g;
-           $data{$namemap{$name}} = $value if exists $namemap{$name};
+           $data{$namemap->{$name}} = $value if exists $namemap->{$name};
         }
     }
     for my $field (keys %fields) {
@@ -1221,38 +1227,43 @@ sub get_bug_status {
      if (@_ == 1) {
          unshift @_, 'bug';
      }
+     state $spec =
+       {bug       => {type => SCALAR,
+                      regex => qr/^\d+$/,
+                     },
+        status    => {type => HASHREF,
+                      optional => 1,
+                     },
+        bug_index => {type => OBJECT,
+                      optional => 1,
+                     },
+        version   => {type => SCALAR|ARRAYREF,
+                      optional => 1,
+                     },
+        dist       => {type => SCALAR|ARRAYREF,
+                       optional => 1,
+                      },
+        arch       => {type => SCALAR|ARRAYREF,
+                       optional => 1,
+                      },
+        bugusertags   => {type => HASHREF,
+                          optional => 1,
+                         },
+        sourceversions => {type => ARRAYREF,
+                           optional => 1,
+                          },
+        indicatesource => {type => BOOLEAN,
+                           default => 1,
+                          },
+        binary_to_source_cache => {type => HASHREF,
+                                   optional => 1,
+                                  },
+        schema => {type => OBJECT,
+                   optional => 1,
+                  },
+       };
      my %param = validate_with(params => \@_,
-                              spec   => {bug       => {type => SCALAR,
-                                                       regex => qr/^\d+$/,
-                                                      },
-                                         status    => {type => HASHREF,
-                                                       optional => 1,
-                                                      },
-                                         bug_index => {type => OBJECT,
-                                                       optional => 1,
-                                                      },
-                                         version   => {type => SCALAR|ARRAYREF,
-                                                       optional => 1,
-                                                      },
-                                         dist       => {type => SCALAR|ARRAYREF,
-                                                        optional => 1,
-                                                       },
-                                         arch       => {type => SCALAR|ARRAYREF,
-                                                        optional => 1,
-                                                       },
-                                         bugusertags   => {type => HASHREF,
-                                                           optional => 1,
-                                                          },
-                                         sourceversions => {type => ARRAYREF,
-                                                            optional => 1,
-                                                           },
-                                         indicatesource => {type => BOOLEAN,
-                                                            default => 1,
-                                                           },
-                                         schema => {type => OBJECT,
-                                                     optional => 1,
-                                                   },
-                                        },
+                              spec   => $spec,
                              );
      my %status;
 
@@ -1343,6 +1354,8 @@ sub get_bug_status {
 
      $status{source} = binary_to_source(binary=>[split /\s*,\s*/, $status{package}],
                                        source_only => 1,
+                                       exists $param{binary_to_source_cache}?
+                                       (cache =>$param{binary_to_source_cache}):(),
                                       );
 
      $status{"package"} = 'unknown' if ($status{"package"} eq '');
index 1edb17477fcfdb45a9b7181a580c331d3f72acf8..53ecf04c47fb60019ec09445355e07700eec46cc 100644 (file)
@@ -47,7 +47,7 @@ BEGIN {
      $EXPORT_TAGS{all} = [@EXPORT_OK];
 }
 
-use Text::Template;
+use Text::Xslate qw(html_builder);
 
 use Storable qw(dclone);
 
@@ -58,34 +58,84 @@ use Carp;
 use IO::File;
 use Data::Dumper;
 
+### for %text_xslate_functions
+use POSIX;
+use Debbugs::CGI qw(html_escape);
+use Scalar::Util;
+use Debbugs::Common qw(make_list);
+use Debbugs::Status;
+
 our %tt_templates;
 our %filled_templates;
 our $language;
 
-# This function is what is called when someone does include('foo/bar')
-# {include('foo/bar')}
-
-sub include {
-     my $template = shift;
-     $filled_templates{$template}++;
-     print STDERR "include template $template language $language\n" if $DEBUG;
-     # Die if we're in a template loop
-     die "Template loop with $template" if $filled_templates{$template} > 10;
-     my $filled_tmpl = '';
-     eval {
-         $filled_tmpl = fill_in_template(template  => $template,
-                                         variables => {},
-                                         language  => $language,
-                                        );
-     };
-     if ($@) {
-         print STDERR "failed to fill template $template: $@";
-     }
-     print STDERR "failed to fill template $template\n" if $filled_tmpl eq '' and $DEBUG;
-     print STDERR "template $template '$filled_tmpl'\n" if $DEBUG;
-     $filled_templates{$template}--;
-     return $filled_tmpl;
-};
+
+sub __output_select_options {
+    my ($options,$value) = @_;
+    my @options = @{$options};
+    my $output = '';
+    while (@options) {
+       my ($o_value) = shift @options;
+       if (ref($o_value)) {
+           for (@{$o_value}) {
+               unshift @options,
+                   ($_,$_);
+           }
+           next;
+       }
+       my $name = shift @options;
+       my $selected = '';
+       if (defined $value and $o_value eq $value) {
+           $selected = ' selected';
+       }
+       $output .= q(<option value=").html_escape($o_value).qq("$selected>).
+           html_escape($name).qq(</option>\n);
+    }
+    return $output;
+}
+
+sub __text_xslate_functions {
+    return
+       {gm_strftime => sub {POSIX::strftime($_[0],gmtime)},
+        package_links => html_builder(\&Debbugs::CGI::package_links),
+        bug_links => html_builder(\&Debbugs::CGI::bug_links),
+        looks_like_number => \&Scalar::Util::looks_like_number,
+        isstrongseverity => \&Debbugs::Status::isstrongseverity,
+        secs_to_english => \&Debbugs::Common::secs_to_english,
+        maybelink => \&Debbugs::CGI::maybelink,
+        # add in a few utility routines
+        duplicate_array =>  sub {
+            my @r = map {($_,$_)} make_list(@{$_[0]});
+            return @r;
+        },
+        output_select_options => html_builder(\&__output_select_options),
+        make_list => \&make_list,
+       };
+}
+sub __text_xslate_functions_text {
+    return
+       {bugurl =>
+       sub{
+           return "$_[0]: ".
+               $config{cgi_domain}.'/'.
+               Debbugs::CGI::bug_links(bug=>$_[0],
+                                       links_only => 1,
+                                      );
+       },
+       };
+}
+
+
+
+### this function removes leading spaces from line-start code strings and spaces
+### before <:- and spaces after -:>
+sub __html_template_prefilter {
+    my $text = shift;
+    $text =~ s/^\s+:/:/mg;
+    $text =~ s/((?:^:[^\n]*\n)?)\s*(<:-)/$1$2/mg;
+    $text =~ s/(-:>)\s+(^:|)/$1.(length($2)?"\n$2":'')/emg;
+    return $text;
+}
 
 
 =head2 fill_in_template
@@ -95,15 +145,14 @@ sub include {
                             language  => '..'
                            );
 
-Reads a template from disk (if it hasn't already been read in) and
-fills the template in.
+Reads a template from disk (if it hasn't already been read in) andf
+ills the template in.
 
 =cut
 
-
 sub fill_in_template{
      my %param = validate_with(params => \@_,
-                              spec   => {template => SCALAR|HANDLE|SCALARREF,
+                              spec   => {template => SCALAR,
                                          variables => {type => HASHREF,
                                                        default => {},
                                                       },
@@ -113,106 +162,59 @@ sub fill_in_template{
                                          output    => {type => HANDLE,
                                                        optional => 1,
                                                       },
-                                         safe      => {type => OBJECT|UNDEF,
-                                                       optional => 1,
-                                                      },
                                          hole_var  => {type => HASHREF,
                                                        optional => 1,
                                                       },
+                                         output_type => {type => SCALAR,
+                                                         default => 'html',
+                                                        },
                                         },
                              );
-     if ($DEBUG) {
-         print STDERR "fill_in_template ";
-         print STDERR join(" ",map {exists $param{$_}?"$_:$param{$_}":()} keys %param);
-         print STDERR "\n";
-     }
-
      # Get the text
-     my $tt_type = '';
-     my $tt_source;
-     if (ref($param{template}) eq 'GLOB' or
-        ref(\$param{template}) eq 'GLOB') {
-         $tt_type = 'FILE_HANDLE';
-         $tt_source = $param{template};
-         binmode($tt_source,":encoding(UTF-8)");
-     }
-     elsif (ref($param{template}) eq 'SCALAR') {
-         $tt_type = 'STRING';
-         $tt_source = ${$param{template}};
-     }
-     else {
-         $tt_type = 'FILE';
-         $tt_source = _locate_text($param{template},$param{language});
-     }
-     if (not defined $tt_source) {
-         die "Unable to find template $param{template} with language $param{language}";
-     }
-
-     $language = $param{language};
+     my $output_type = $param{output_type};
+     my $language = $param{language};
+     my $template = $param{template};
+     $template .= '.tx' unless $template =~ /\.tx$/;
      my $tt;
-     if ($tt_type eq 'FILE' and
-        defined $tt_templates{$tt_source} and
-        ($tt_templates{$tt_source}{mtime} + 60) < time and
-        (stat $tt_source)[9] <= $tt_templates{$tt_source}{mtime}
+     if (not exists $tt_templates{$output_type}{$language} or
+        not defined $tt_templates{$output_type}{$language}
        ) {
-         $tt = $tt_templates{$tt_source}{template};
-     }
-     else {
-        my $passed_source = $tt_source;
-        my $passed_type = $tt_type;
-         if ($tt_type eq 'FILE') {
-              $tt_templates{$tt_source}{mtime} =
-                   (stat $tt_source)[9];
-              $passed_source = IO::File->new($tt_source,'r');
-              binmode($passed_source,":encoding(UTF-8)");
-              $passed_type = 'FILEHANDLE';
-         }
-         $tt = Text::Template->new(TYPE => $passed_type,
-                                   SOURCE => $passed_source,
-                                   UNTAINT => 1,
-                                  );
-         if ($tt_type eq 'FILE') {
-              $tt_templates{$tt_source}{template} = $tt;
-         }
+        $tt_templates{$output_type}{$language} =
+            Text::Xslate->new(# cache in template_cache or temp directory
+                              cache_dir => $config{template_cache} //
+                              File::Temp::tempdir(CLEANUP => 1),
+                              # default to the language, but fallback to en_US
+                              path => [$config{template_dir}.'/'.$language.'/',
+                                       $config{template_dir}.'/en_US/',
+                                      ],
+                              suffix => '.tx',
+                              ## use html or text specific functions
+                              function =>
+                              ($output_type eq 'html' ? __text_xslate_functions() :
+                               __text_xslate_functions_text()),
+                              syntax => 'Kolon',
+                              module => ['Text::Xslate::Bridge::Star',
+                                         'Debbugs::Text::XslateBridge',
+                                        ],
+                              type   => $output_type,
+                              ## use the html-specific pre_process_handler
+                              $output_type eq 'html'?
+                              (pre_process_handler => \&__html_template_prefilter):(),
+                             )
+                or die "Unable to create Text::Xslate";
      }
-     if (not defined $tt) {
-         die "Unable to create Text::Template for $tt_type:$tt_source";
+     $tt = $tt_templates{$output_type}{$language};
+     my $ret =
+        $tt->render($template,
+                   {time => time,
+                    %{$param{variables}//{}},
+                    config  => \%config,
+                   });
+     if (exists $param{output}) {
+        print {$param{output}} $ret;
+        return '';
      }
-     my $ret = $tt->fill_in(PACKAGE => 'DTT',
-                           HASH => {%{$param{variables}//{}},
-                                    (map {my $t = $_; $t =~ s/^\&//; ($t => $param{hole_var}{$_})}
-                                     keys %{$param{hole_var}//{}}),
-                                    include => \&Debbugs::Text::include,
-                                    config  => \%config,
-                                   },
-                           defined $param{output}?(OUTPUT=>$param{output}):(),
-                          );
-     if (not defined $ret) {
-         print STDERR $Text::Template::ERROR;
-         return '';
-     }
-     if ($DEBUG) {
-         no strict 'refs';
-         no warnings 'uninitialized';
-         print STDERR "Variables for $param{template}\n";
-     }
-
      return $ret;
 }
 
-sub _locate_text{
-     my ($template,$language) = @_;
-     $template =~ s/\.tmpl$//g;
-     # if a language doesn't exist, use the en_US template
-     if (not -e $config{template_dir}.'/'.$language.'/'.$template.'.tmpl') {
-         $language = 'en_US';
-     }
-     my $loc = $config{template_dir}.'/'.$language.'/'.$template.'.tmpl';
-     if (not -e $loc) {
-         print STDERR "Unable to locate template $loc\n";
-         return undef;
-     }
-     return $loc;
-}
-
 1;
diff --git a/Debbugs/Text/XslateBridge.pm b/Debbugs/Text/XslateBridge.pm
new file mode 100644 (file)
index 0000000..14652c2
--- /dev/null
@@ -0,0 +1,51 @@
+# This module is part of debbugs, and is released
+# under the terms of the GPL version 2, or any later
+# version at your option.
+# See the file README and COPYING for more information.
+#
+# Copyright 2018 by Don Armstrong <don@donarmstrong.com>.
+
+package Debbugs::Text::XslateBridge;
+
+use warnings;
+use strict;
+
+use base qw(Text::Xslate::Bridge);
+
+=head1 NAME
+
+Debbugs::Text::XslateBridge -- bridge for Xslate to add in useful functions
+
+=head1 DESCRIPTION
+
+This module provides bridge functionality to load functions into
+Text::Xslate. It's loosely modeled after
+Text::Xslate::Bridge::TT2Like, but with fewer functions.
+
+=head1 BUGS
+
+None known.
+
+=cut
+
+
+use vars qw($VERSION);
+
+BEGIN {
+     $VERSION = 1.00;
+}
+
+use Text::Xslate;
+
+__PACKAGE__->
+    bridge(scalar => {length => \&__length,
+                     },
+           function => {length => \&__length,}
+          );
+
+sub __length {
+    length $_[0];
+}
+
+
+1;
index 230ab79136fcc92f4c4bda9cf8c393a7aeb95fa6..01351f3668f04e2e33704eb672300006bf656579 100644 (file)
@@ -154,6 +154,10 @@ sub convert_to_utf8 {
     if ($charset eq 'RAW') {
         croak("Charset must not be raw when calling convert_to_utf8");
     }
+    ## if the charset is unknown or unknown 8 bit, assume that it's UTF-8.
+    if ($charset =~ /unknown/i) {
+       $charset = 'UTF-8'
+    }
     my $iconv_converter;
     eval {
         $iconv_converter = Text::Iconv->new($charset,"UTF-8") or
@@ -200,6 +204,10 @@ sub __fallback_convert_to_utf8 {
      }
      # lets assume everything that doesn't have a charset is utf8
      $charset //= 'utf8';
+     ## if the charset is unknown, assume it's UTF-8
+     if ($charset =~ /unknown/i) {
+        $charset = 'utf8';
+     }
      my $result;
      eval {
         $result = decode($charset,$data,0);
index 8114d0bc4baea08251e7b0285ea1cc1972827727..a279aeb83e6fb1228aacb465c598057eb818f1c0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,6 @@ sbin_dir        := $(DESTDIR)/usr/sbin
 etc_dir                := $(DESTDIR)/etc/debbugs
 var_dir                := $(DESTDIR)/var/lib/debbugs
 scripts_dir    := $(DESTDIR)/usr/lib/debbugs
-perl_dir       := $(DESTDIR)/usr/share/perl5/Debbugs
 doc_dir                := $(DESTDIR)/usr/share/doc/debbugs
 templates_dir  := $(DESTDIR)/usr/share/debbugs/templates
 man_dir                := $(DESTDIR)/usr/share/man
@@ -14,11 +13,7 @@ examples_dir := $(doc_dir)/examples
 
 scripts_in     = $(foreach script, $(filter-out scripts/config% scripts/errorlib scripts/text, $(wildcard scripts/*)),$(patsubst scripts/%,%,$(script)))
 htmls_in       := $(wildcard html/*.html.in)
-cgis           := $(wildcard cgi/*.cgi cgi/*.pl)
-
-# We use the Makefile.PL to install these; not totally decided if we
-# should switch entirely to this model.
-#perls         := $(shell find Debbugs -type f -iname '*.pm')
+cgis           := $(wildcard cgi/*.cgi)
 
 install_exec   := install -m755 -p
 install_data   := install -m644 -p
@@ -32,6 +27,7 @@ all: build
 build:
        $(PERL) Makefile.PL
        $(MAKE) -f Makefile.perl
+       $(MAKE) -C html/logo
 
 test:
        LC_ALL=$(UTF8_LOCALE) $(PERL) -MTest::Harness -I. -e 'runtests(glob(q(t/*.t)))'
@@ -49,7 +45,7 @@ clean:
 
 install: install_mostfiles
        # install basic debbugs documentation
-       $(install_data) COPYING UPGRADE README.md debian/README.mail $(doc_dir)
+       $(install_data) COPYING UPGRADE.md README.md debian/README.mail $(doc_dir)
        $(MAKE) -f Makefile.perl install DESTDIR=$(DESTDIR)
 
 install_mostfiles:
@@ -60,12 +56,6 @@ $(var_dir)/www/css \
 $(var_dir)/spool/lock $(var_dir)/spool/archive $(var_dir)/spool/incoming \
 $(var_dir)/spool/db-h $(scripts_dir) $(examples_dir) $(man8_dir); \
           do test -d $$dir || $(install_exec) -d $$dir; done
-# we shouldn't ship db-h spool directories
-       # make db-h spool dirs if they don't exist
-#      cd $(var_dir)/spool/db-h; \
-#        for dir in $(shell seq -w 00 99); \
-#          do test -d $$dir || $(install_exec) -d $$dir; done
-
 
        # install the scripts
        $(foreach script,$(scripts_in), $(install_exec) scripts/$(script) $(scripts_dir);)
@@ -84,15 +74,10 @@ $(var_dir)/spool/db-h $(scripts_dir) $(examples_dir) $(man8_dir); \
        $(foreach html, $(htmls_in), $(install_data) $(html) $(etc_dir)/html;)
        $(install_data) html/htaccess $(var_dir)/www/db/.htaccess
        $(install_data) html/bugs.css $(var_dir)/www/css/bugs.css
+       $(install_data) html/logo/debbugs_logo_icon.png $(var_dir)/www/favicon.png
 
        # install the CGIs
        for cgi in $(cgis); do $(install_exec) $$cgi $(var_dir)/www/cgi; done
-       $(install_exec) cgi/bugs-fetch2.pl $(var_dir)/www/cgi/bugs-fetch2.pl
-
-#      # install Perl modules
-#      for perl in $(perls); do $(install_data) $$perl $(perl_dir); done
-       # Make documentation for the perl modules
-
 
        # install debbugsconfig
        $(install_exec) debian/debbugsconfig $(sbin_dir)
diff --git a/UPGRADE b/UPGRADE
deleted file mode 100644 (file)
index b4ab626..0000000
--- a/UPGRADE
+++ /dev/null
@@ -1,170 +0,0 @@
-
-                            Debbugs upgrade notes
-                           +=====================+
-
-From 2.4.1 to 2.4.2
--------------------
-
-The file format used to store the status of a bug (package, severity, etc.)
-has changed; it is now in an RFC822-like format in order to be more
-extensible, and is written to .summary files rather than the old .status
-files. Before accepting any mail with the new version of debbugs, you must
-run the 'debbugs-upgradestatus' program over your bug spool. The old .status
-files will be left intact, and will continue to be written in sync with the
-.summary files for compatibility with external tools.
-
-There is a new standalone spam-scanning script called spamscan, which uses
-the SpamAssassin modules. To use it, set the $gSpamScan variable in
-/etc/debbugs/config to a true value and $gSpamMailbox to an mbox file to
-which detected spam should be appended, add /usr/lib/debbugs/spamscan to
-your crontab as per the example, and optionally set $gSpamRulesDir and
-$gSpamLocalTestsOnly as desired.
-
-From 2.4 to 2.4.1
------------------
-
-Add the following variables to the /etc/debbugs/config file:
-
-$gHTMLSuffix = ".html";
-
-The use of $gCGIDomain has been cleaned up; formerly, it needed to begin
-with "http://", which was confusingly inconsistent with all the other domain
-variables. If you worked around this in your configuration, you will need to
-recheck it.
-
-From 2.3 to 2.4
----------------
-
-Add the following variables to the /etc/debbugs/config file:
-
-$gWebHost = "localhost";                               # e.g. www.debian.org
-$gWebHostBugDir = "Bugs";                              # e.g. Bugs
-# For now, don't change this one manually!
-$gWebDomain = "$gWebHost/$gWebHostBugDir";
-$gCGIDomain = "$gWebDomain/Bugs/cgi";                  # e.g. cgi.debian.org
-$gPackagePages = "packages.debian.org";                 # e.g. packages.debian.org
-$gSubscriptionDomain = "packages.something";           # e.g. packages.qa.debian.org
-$gMaintainerFileOverride = "$gConfigDir/Maintainers.override";
-$gUnknownMaintainerEmail = "$gMaintainerEmail";
-$gPackageSource = "$gConfigDir/indices/sources";
-
-$gWebDomain will probably exist already; change it as shown above.
-
-$gSubscriptionDomain is optional.
-
-$gMaintainerFileOverride is the name of a file used to manually override the
-Maintainers file (which is often automatically generated).
-
-$gUnknownMaintainerEmail is the address to mail when a bug report arrives
-for a package with no maintainer in $gMaintainerFile or
-$gMaintainerFileOverride.
-
-$gPackageSource is a file containing three tab-separated columns: package
-name, component (e.g. main, contrib, non-free), and the corresponding source
-package name.
-
-Add the following variable to the /etc/debbugs/text file:
-
-############################################################################
-# Description of the tags
-############################################################################
-$gHTMLTagDesc = "
-<dt><code>patch</code>
-  <dd>A patch or some other easy procedure for fixing the $gBug is included in
-  the $gBug logs. If there\'s a patch, but it doesn\'t resolve the $gBug
-  adequately or causes some other problems, this tag should not be used.
-
-<dt><code>wontfix</code>
-  <dd>This $gBug won\'t be fixed. Possibly because this is a choice between two
-  arbitrary ways of doing things and the maintainer and submitter prefer
-  different ways of doing things, possibly because changing the behaviour
-  will cause other, worse, problems for others, or possibly for other
-  reasons.
-
-<dt><code>moreinfo</code>
-  <dd>This $gBug can\'t be addressed until more information is provided by the
-  submitter. The $gBug will be closed if the submitter doesn\'t provide ore
-  information in a reasonable (few months) timeframe. This is for $gBugs like
-  \"It doesn\'t work\". What doesn\'t work?
-
-<dt><code>unreproducible</code>
-  <dd>This $gBug can\'t be reproduced on the maintainer\'s system.  Assistance
-  from third parties is needed in diagnosing the cause of the problem.
-
-<dt><code>fixed</code>
-  <dd>This $gBug is fixed or worked around, but there\'s still an issue that
-  needs to be resolved. (This will eventually replace the \"fixed\" severity)
-
-<dt><code>stable</code>
-  <dd>This $gBug affects the stable distribution in particular.  This is only
-  intended to be used for ease in identifying release critical $gBugs that
-  affect the stable distribution.  It\'ll be replaced eventually with
-  something a little more flexible, probably.
-";
-
-The bug database is now stored in a hashed directory format (db-h).  You
-will need to migrate your database to this new format.  The
-/usr/sbin/debbugs-dbhash program is provided to help you perform this
-migration.
-
-From 2.2 to 2.3
----------------
-
-There are three new scripts that have to be installed in CGI and the front
-page (or any other search you have set up) needs to be changed to use these
-scripts.  They are:
-       * bugreport.cgi
-       * common.pl
-       * pkgreport.cgi
-
-Add the following variables to the /etc/debbugs/config file:
-(the /usr/share/doc/debbugs/examples/config file can be used as a
-reference)
-
-$gSummaryList = "summary.list";         #debian-bugs-report@lists
-$gSaveOldBugs = 1;
-
-Make sure you do not have a double ,, as shown here if you're using the
-default severities.  Also, 'fixed' was added to the default severities:
--                                       'normal',"Normal $gBugs",,
-+                                       'normal',"Normal $gBugs",
-+                                                      'fixed',"NMU Fixed $gBugs",
-These have been added to the /etc/debbugs/text file:
-+############################################################################
-+#  Here is a blurb to point people to ftp archive of directions.  It is
-+#  used by the receive script when bouncing a badly formatted email
-+#
-+# $gTextInstructions = "$gBadEmailPrefix
-+# $gBadEmailPrefix Instructions are available from ftp.debian.org in /debian
-+# $gBadEmailPrefix and at all Debian mirror sites, in the files:
-+# $gBadEmailPrefix  doc/bug-reporting.txt
-+# $gBadEmailPrefix  doc/bug-log-access.txt
-+# $gBadEmailPrefix  doc/bug-maint-info.txt
-+# $gBadEmailPrefix";
-+############################################################################
-+$gTextInstructions = "$gBadEmailPrefix";
-+
-+
-$gHTMLStart = "<BODY TEXT=#0F0F0F>";   #this is used by HTML generation to create the "uniform look"
-The following code was added to /etc/debbugs/text if you use the new fixed
-severity
-
-       <DT><CODE>wishlist</CODE>
--      <DD>for any feature request, and also for any $gBugs that are very difficult
--      to fix due to major design considerations.";
-+      <DD>for any feature request, and also for any $gBugs that are very 
-+      difficult to fix due to major design considerations.";
-+
-+      <DT><CODE>fixed</CODE>
-+      <DD>fixed in the current version in the unstable archive but the fix has
-+      not been fixed by the person responsible.
-  
- In All such entries in /etc/debbugs/text, if you replace <BODY> with
- $gHTMLStart, all html pages will have the same look (as specified in
- $gHTMLStart):
-
- $gSummaryIndex = "<HTML><HEAD><TITLE>$gProject $gBug report logs - summary index</TITLE>
- $gPackageLog = "<HTML><HEAD><TITLE>$gProject $gBug report logs - index by package</TITLE>
diff --git a/UPGRADE.md b/UPGRADE.md
new file mode 100644 (file)
index 0000000..62a7bd4
--- /dev/null
@@ -0,0 +1,184 @@
+# Debbugs upgrade notes #
+
+## From 2.4.2 to 2.6 ##
+
+Debbugs configuration file now sets default values for all configuration file
+options, so if you're upgrading from earlier versions, you do not need to
+specify values for the new configuration files.
+
+### Templates ###
+
+Debbugs now uses Text::Template for templates, and any of the existing templates
+can be overridden by creating a new directory and setting `$gTemplateDir` to the
+new directory.
+
+## From 2.4.1 to 2.4.2 ##
+
+The file format used to store the status of a bug (package, severity, etc.)
+has changed; it is now in an RFC822-like format in order to be more
+extensible, and is written to .summary files rather than the old .status
+files. Before accepting any mail with the new version of debbugs, you must
+run the 'debbugs-upgradestatus' program over your bug spool. The old .status
+files will be left intact, and will continue to be written in sync with the
+.summary files for compatibility with external tools.
+
+There is a new standalone spam-scanning script called spamscan, which uses
+the SpamAssassin modules. To use it, set the `$gSpamScan` variable in
+`/etc/debbugs/config` to a true value and `$gSpamMailbox` to an mbox file to
+which detected spam should be appended, add /usr/lib/debbugs/spamscan to
+your crontab as per the example, and optionally set `$gSpamRulesDir` and
+`$gSpamLocalTestsOnly` as desired.
+
+## From 2.4 to 2.4.1 ##
+
+Add the following variables to the /etc/debbugs/config file:
+
+`$gHTMLSuffix = ".html";`
+
+The use of `$gCGIDomain` has been cleaned up; formerly, it needed to begin
+with "http://", which was confusingly inconsistent with all the other domain
+variables. If you worked around this in your configuration, you will need to
+recheck it.
+
+## From 2.3 to 2.4 ##
+
+Add the following variables to the /etc/debbugs/config file:
+
+```perl
+$gWebHost = "localhost";                               # e.g. www.debian.org
+$gWebHostBugDir = "Bugs";                              # e.g. Bugs
+# For now, don't change this one manually!
+$gWebDomain = "$gWebHost/$gWebHostBugDir";
+$gCGIDomain = "$gWebDomain/Bugs/cgi";                  # e.g. cgi.debian.org
+$gPackagePages = "packages.debian.org";                 # e.g. packages.debian.org
+$gSubscriptionDomain = "packages.something";           # e.g. packages.qa.debian.org
+$gMaintainerFileOverride = "$gConfigDir/Maintainers.override";
+$gUnknownMaintainerEmail = "$gMaintainerEmail";
+$gPackageSource = "$gConfigDir/indices/sources";
+```
+
+`$gWebDomain` will probably exist already; change it as shown above.
+
+`$gSubscriptionDomain` is optional.
+
+`$gMaintainerFileOverride is the name of a file used to manually override the
+Maintainers file (which is often automatically generated).
+
+`$gUnknownMaintainerEmail` is the address to mail when a bug report arrives
+for a package with no maintainer in `$gMaintainerFile` or
+`$gMaintainerFileOverride`.
+
+`$gPackageSource` is a file containing three tab-separated columns: package
+name, component (e.g. main, contrib, non-free), and the corresponding source
+package name.
+
+Add the following variable to the `/etc/debbugs/text` file:
+
+```
+############################################################################
+# Description of the tags
+############################################################################
+`$gHTMLTagDesc = "
+<dt><code>patch</code>
+  <dd>A patch or some other easy procedure for fixing the `$gBug is included in
+  the `$gBug logs. If there\'s a patch, but it doesn\'t resolve the `$gBug
+  adequately or causes some other problems, this tag should not be used.
+
+<dt><code>wontfix</code>
+  <dd>This `$gBug won\'t be fixed. Possibly because this is a choice between two
+  arbitrary ways of doing things and the maintainer and submitter prefer
+  different ways of doing things, possibly because changing the behaviour
+  will cause other, worse, problems for others, or possibly for other
+  reasons.
+
+<dt><code>moreinfo</code>
+  <dd>This `$gBug can\'t be addressed until more information is provided by the
+  submitter. The `$gBug will be closed if the submitter doesn\'t provide ore
+  information in a reasonable (few months) timeframe. This is for `$gBugs like
+  \"It doesn\'t work\". What doesn\'t work?
+
+<dt><code>unreproducible</code>
+  <dd>This `$gBug can\'t be reproduced on the maintainer\'s system.  Assistance
+  from third parties is needed in diagnosing the cause of the problem.
+
+<dt><code>fixed</code>
+  <dd>This `$gBug is fixed or worked around, but there\'s still an issue that
+  needs to be resolved. (This will eventually replace the \"fixed\" severity)
+
+<dt><code>stable</code>
+  <dd>This `$gBug affects the stable distribution in particular.  This is only
+  intended to be used for ease in identifying release critical `$gBugs that
+  affect the stable distribution.  It\'ll be replaced eventually with
+  something a little more flexible, probably.
+";
+```
+
+The bug database is now stored in a hashed directory format (db-h).  You
+will need to migrate your database to this new format.  The
+`/usr/sbin/debbugs-dbhash` program is provided to help you perform this
+migration.
+
+## From 2.2 to 2.3 ##
+
+There are three new scripts that have to be installed in CGI and the front
+page (or any other search you have set up) needs to be changed to use these
+scripts.  They are:
+       * bugreport.cgi
+       * common.pl
+       * pkgreport.cgi
+
+Add the following variables to the /etc/debbugs/config file:
+(the /usr/share/doc/debbugs/examples/config file can be used as a
+reference)
+
+```perl
+`$gSummaryList = "summary.list";         #debian-bugs-report@lists
+`$gSaveOldBugs = 1;
+```
+
+Make sure you do not have a double ,, as shown here if you're using the
+default severities.  Also, 'fixed' was added to the default severities:
+-                                       'normal',"Normal `$gBugs",,
++                                       'normal',"Normal `$gBugs",
++                                                      'fixed',"NMU Fixed $gBugs",
+These have been added to the /etc/debbugs/text file:
+```
++############################################################################
++#  Here is a blurb to point people to ftp archive of directions.  It is
++#  used by the receive script when bouncing a badly formatted email
++#
++# $gTextInstructions = "$gBadEmailPrefix
++# $gBadEmailPrefix Instructions are available from ftp.debian.org in /debian
++# $gBadEmailPrefix and at all Debian mirror sites, in the files:
++# $gBadEmailPrefix  doc/bug-reporting.txt
++# $gBadEmailPrefix  doc/bug-log-access.txt
++# $gBadEmailPrefix  doc/bug-maint-info.txt
++# $gBadEmailPrefix";
++############################################################################
++$gTextInstructions = "$gBadEmailPrefix";
++
++
+```
+
+`$gHTMLStart = "<BODY TEXT=#0F0F0F>";  #this is used by HTML generation to create the "uniform look"`
+The following code was added to /etc/debbugs/text if you use the new fixed
+severity
+```
+       <DT><CODE>wishlist</CODE>
+-      <DD>for any feature request, and also for any $gBugs that are very difficult
+-      to fix due to major design considerations.";
++      <DD>for any feature request, and also for any $gBugs that are very 
++      difficult to fix due to major design considerations.";
++
++      <DT><CODE>fixed</CODE>
++      <DD>fixed in the current version in the unstable archive but the fix has
++      not been fixed by the person responsible.
+```
+ In All such entries in /etc/debbugs/text, if you replace <BODY> with
+ `$gHTMLStart`, all html pages will have the same look (as specified in
+ `$gHTMLStart`):
+
+ `$gSummaryIndex = "<HTML><HEAD><TITLE>$gProject $gBug report logs - summary index</TITLE>`
+ `$gPackageLog = "<HTML><HEAD><TITLE>$gProject $gBug report logs - index by package</TITLE>`
diff --git a/bin/debbugs-spam b/bin/debbugs-spam
new file mode 100755 (executable)
index 0000000..09077e0
--- /dev/null
@@ -0,0 +1,430 @@
+#! /usr/bin/perl
+# debbugs-spam is part of debbugs, and is released
+# under the terms of the GPL version 2, or any later version, at your
+# option. See the file README and COPYING for more information.
+# Copyright 2012 by Don Armstrong <don@donarmstrong.com>.
+
+
+use warnings;
+use strict;
+
+use Getopt::Long qw(:config no_ignore_case);
+use Pod::Usage;
+
+=head1 NAME
+
+debbugs-spam -- Scan log files for spam and populate nnn.log.spam
+
+=head1 SYNOPSIS
+
+debbugs-spam [options] bugnumber [[bugnumber2]..]
+
+ Options:
+  --spool-dir debbugs spool directory
+  --debug, -d debugging level (Default 0)
+  --help, -h display this help
+  --man, -m display manual
+
+=head1 OPTIONS
+
+=over
+
+=item B<--spool-dir>
+
+Debbugs spool directory; defaults to the value configured in the
+debbugs configuration file.
+
+=item B<--debug, -d>
+
+Debug verbosity.
+
+=item B<--help, -h>
+
+Display brief useage information.
+
+=item B<--man, -m>
+
+Display this manual.
+
+=back
+
+=head1 SUBCOMMANDS
+
+=over
+
+=item B<auto-scan>
+
+Automatically scan messages using spamassassin and mark messages as
+spam which hit the threshold, and those that are highly negative as
+ham.
+
+=item B<score>
+
+Output the score of all of the messages in a bug
+
+=over
+
+=item B<--skip-seen> Skip messages which have previously been classified
+
+=back
+
+=item B<mark-spam>
+
+Mark messages as spam if there is a regex match to subject or message
+id
+
+=item B<mark-ham>
+
+Mark messages as ham if there is a regex match to subject or message
+id
+
+=item B<learn>
+
+Learn from messages which are ham/spam
+
+=back
+
+
+=head1 EXAMPLES
+
+Start spamd:
+
+  /usr/sbin/spamd --socketpath=/home/debbugs/spamd_socket \
+      --nouser-config --cf='include /home/debbugs/.spamassassin/user_prefs' \
+      --cf='allow_user_rules 1' --allow-tell;
+
+Then score bugs:
+
+  debbugs-spam --spamc-opts '-U' --spamc-opts '/home/debbugs/spamd_socket' \
+      score 859123;
+
+=cut
+
+
+use vars qw($DEBUG);
+
+use Debbugs::Log qw(record_regex);
+use Debbugs::Log::Spam;
+use Debbugs::Config qw(:config);
+use Debbugs::Command qw(:all);
+use IPC::Open3 qw(open3);
+use Carp;
+
+my %options =
+    (debug   => 0,
+     help    => 0,
+     man     => 0,
+     verbose => 0,
+     quiet   => 0,
+     quick   => 0,
+     spamc   => 'spamc',
+     spamc_opts => [],
+    );
+
+handle_main_arguments(\%options,
+                      'quick|q',
+                      'service|s',
+                      'sysconfdir|c',
+                      'spamc=s' => 0,
+                      'spamc_opts|spamc-opts=s@' => 0,
+                      'spool_dir|spool-dir=s',
+                      'debug|d+','help|h|?','man|m');
+
+my %subcommands =
+    ('auto-scan' => {function => \&auto_spamscan,
+                     arguments => {'ham_threshold|ham-threshold=s' => 0,
+                                  },
+                     defaults => {ham_threshold => -5},
+                    },
+     'score' => {function => \&score_bug,
+                 arguments => {'skip_seen|skip-seen!' => 0
+                              },
+                },
+     'mark-spam' => {function => \&mark_spam,
+                    },
+     'mark-ham' => {function => \&mark_ham,
+                   },
+     'learn' => {function => \&learn,
+                },
+     'help' => {function => sub {pod2usage({verbose => 2});}}
+    );
+
+pod2usage() if $options{help};
+pod2usage({verbose=>2}) if $options{man};
+
+$DEBUG = $options{debug};
+
+my @USAGE_ERRORS;
+$options{verbose} = $options{verbose} - $options{quiet};
+
+pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
+
+my ($subcommand) = shift @ARGV;
+if (not defined $subcommand) {
+    $subcommand = 'help';
+    print STDERR "You must provide a subcommand; displaying usage.\n";
+    pod2usage();
+} elsif (not exists $subcommands{$subcommand}) {
+    print STDERR "$subcommand is not a valid subcommand; displaying usage.\n";
+    pod2usage();
+}
+
+if (exists $options{spool_dir} and defined $options{spool_dir}) {
+    $config{spool_dir} = $options{spool_dir};
+}
+if ($subcommand ne 'help') {
+    chdir($config{spool_dir}) or die "chdir $config{spool_dir} failed: $!";
+}
+my $opts =
+    handle_subcommand_arguments(\@ARGV,
+                                $subcommands{$subcommand}{arguments},
+                                $subcommands{$subcommand}{defaults},
+                               );
+$subcommands{$subcommand}{function}->(\%options,$opts,\%config,\@ARGV);
+
+
+sub mark_ham {
+    mark_it('ham',@_);
+}
+
+sub mark_spam {
+    mark_it('spam',@_);
+}
+
+sub mark_it {
+    my ($spam_ham,$options,$opts,$config,$argv) = @_;
+    my $regex = shift @{$argv};
+    for my $bug_num (@{$argv}) {
+        my $spam = Debbugs::Log::Spam->new(bug_num => $bug_num) or
+            die "Unable to open bug log spam for $bug_num";
+        foreachmsg(sub {
+                       my ($bn,$rec,$mid) = @_;
+                       my $body = $rec->{text};
+                       my ($subject) = $body =~ /^Subject: *(.+)$/mi;
+                       my $is_match = 0;
+                       if ($subject =~ /$regex/) {
+                           $is_match = 1;
+                       }
+                       if ($mid =~ /$regex/) {
+                           $is_match = 1;
+                       }
+                       if ($is_match) {
+                           print STDERR "it's a match" if $DEBUG;
+                           if ($spam_ham eq 'spam') {
+                               $spam->add_spam($mid);
+                           } else {
+                               $spam->add_ham($mid);
+                           }
+                       }
+                   },
+                   $bug_num
+                  );
+        $spam->save();
+    }
+}
+
+sub learn {
+    my ($options,$opts,$config,$argv) = @_;
+    for my $bug_num (@{$argv}) {
+        my $spam = Debbugs::Log::Spam->new(bug_num => $bug_num) or
+            die "Unable to open bug log spam for $bug_num";
+        foreachmsg(sub {
+                       my ($bn,$rec,$mid) = @_;
+                       my $score;
+                       if ($spam->is_spam($mid)) {
+                           $score //=
+                               spam_score($rec,$options->{spamc},
+                                          [@{$options->{spamc_opts}},
+                                           '-L','spam'
+                                          ]
+                                         );
+                           print STDERR "learning spam" if $DEBUG;
+                       } elsif ($spam->is_ham($mid)) {
+                           $score //=
+                               spam_score($rec,$options->{spamc},
+                                          [@{$options->{spamc_opts}},
+                                           '-L','ham'
+                                          ]
+                                         );
+                           print STDERR "learning ham" if $DEBUG;
+                       } else {
+                           print STDERR "not learning" if $DEBUG;
+                       }
+                       print STDERR " from $mid" if $DEBUG;
+                   },
+                   $bug_num
+                  );
+    }
+}
+
+
+sub score_bug {
+    my ($options,$opts,$config,$argv) = @_;
+    for my $bug_num (@{$argv}) {
+        my @bug_score =
+            spam_score_bug($bug_num,
+                           $options->{spamc},
+                           $options->{spamc_opts},
+                           $opts->{skip_seen},
+                          );
+        print "$_->{score} $_->{message_id} $_->{subject}\n"
+            foreach @bug_score;
+    }
+}
+
+sub auto_spamscan {
+    my ($options,$opts,$config,$argv) = @_;
+
+    for my $bug_num (@{$argv}) {
+        my $spam = Debbugs::Log::Spam->new(bug_num => $bug_num) or
+            die "Unable to open bug log spam for $bug_num";
+        foreachmsg(sub {
+                       my ($bn,$rec,$mid) = @_;
+                       if ($spam->is_spam($mid)) {
+                           print STDERR "already spam\n" if $DEBUG;
+                           return;
+                       }
+                       if ($spam->is_ham($mid)) {
+                           print STDERR "already ham\n" if $DEBUG;
+                           return;
+                       }
+                       my ($score,$is_spam,$report,$threshold) =
+                           spam_score($rec,
+                                      $options->{spamc},
+                                      $options->{spamc_opts},
+                                     );
+                       if ($is_spam) {
+                           print STDERR "it's spam ($score)\n" if $DEBUG;
+                           $spam->add_spam($mid);
+                       } elsif ($score < $opts->{ham_threshold}) {
+                           print STDERR "it's really ham ($score)\n" if $DEBUG;
+                           $spam->add_ham($mid);
+                       }
+                       else {
+                           print STDERR "it's ham ($score)\n" if $DEBUG;
+                       }
+                   },
+                   $bug_num,
+                  );
+        $spam->save();
+    }
+}
+
+sub spam_score_bug {
+    my ($bug,$spamc,$spamc_opts,$skip_seen) = @_;
+
+    my $spam;
+    if ($skip_seen) {
+        $spam = Debbugs::Log::Spam->new(bug_num => $bug) or
+            die "Unable to open bug log spam for $bug";
+    }
+    my @records;
+    foreachmsg(sub {
+                   my ($bn,$rec,$mid) = @_;
+                   my $score;
+                   if ($skip_seen) {
+                       if ($spam->is_spam($mid)) {
+                           $score = 999;
+                       } elsif ($spam->is_ham($mid)) {
+                           $score = -999;
+                       }
+                   }
+                   $score //=
+                       spam_score($rec,$spamc,$spamc_opts);
+                   my ($subject) = $rec->{text} =~ /^Subject: *(.+)$/mi;
+                   push @records,
+                      {message_id => $mid,
+                       score => $score,
+                       subject => $subject,
+                      };
+               },
+               $bug
+              );
+    return @records;
+}
+
+sub spam_score {
+    my ($record,$spamc,$spamc_opts) = @_;
+    my ($score,$threshold,$report);
+    my $is_spam = 0;
+    eval {
+        $report = '';
+        $score = 0;
+        $threshold = 5;
+        my ($spamc_in,$spamc_out);
+        my $old_sig = $SIG{"PIPE"};
+        $SIG{"PIPE"} = sub {
+            die "SIGPIPE in child for some reason";
+        };
+        my $childpid =
+            open3($spamc_in,$spamc_out,0,
+                  $spamc,'-E','--headers',@{$spamc_opts}) or
+                      die "Unable to fork spamc: $!";
+        if (not $childpid) {
+            die "Unable to fork spamc";
+        }
+        print {$spamc_in} $record->{text};
+        close($spamc_in) or die "Unable to close spamc_in: $!";
+        waitpid($childpid,0);
+        my $exit_code = $? >> 8;
+        if ($exit_code) {
+            $is_spam = 1;
+        }
+        while (<$spamc_out>) {
+            if (/^X-Spam/) {
+                $report .= $_;
+                if (/^X-Spam-Status: (Yes|No), score=(-?[\d\.]+) required=(-?[\d\.]+)/) {
+                    $threshold = $3;
+                    $score = $2;
+                }
+            }
+            if (/^\s*$/) {
+                last;
+            }
+        }
+        if ($DEBUG) {
+            print STDERR "[$exit_code] [$score/$threshold]\n$report\n";
+        }
+        close($spamc_out);
+        $SIG{"PIPE"} = $old_sig;
+    };
+    if ($@) {
+        carp "processing of message failed [$@]\n";
+        return undef;
+    }
+    return wantarray?($score,$is_spam,$report):$score;
+}
+
+sub foreachmsg {
+    my ($sub,$bug_num) = @_;
+    my $log = Debbugs::Log->new(bug_num => $bug_num) or
+        die "Unable to open bug log for $bug_num";
+    my %seen_msgids;
+    while (my $record = $log->read_record()) {
+        next if $record->{type} eq 'html';
+        next if $record->{type} eq 'autocheck';
+        my ($msg_id) = record_regex($record,
+                                    qr/^Message-Id:\s+<(.+)>/mi);
+        next unless defined $msg_id;
+        print STDERR "examining $msg_id: " if $DEBUG;
+        if ($msg_id =~ /$config{email_domain}$/) {
+            print STDERR "skipping\n" if $DEBUG;
+            next;
+        }
+        if ($seen_msgids{$msg_id}) {
+            print STDERR "already seen\n" if $DEBUG;
+            next;
+        }
+        $seen_msgids{$msg_id}=1;
+        $sub->($bug_num,$record,$msg_id);
+        print STDERR "\n" if $DEBUG;
+    }
+}
+
+
+__END__
+
+# Local Variables:
+# cperl-indent-level: 4
+# indent-tabs-mode: nil
+# End:
diff --git a/bin/debbugs-spamscan-log b/bin/debbugs-spamscan-log
deleted file mode 100755 (executable)
index 08e7526..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-#! /usr/bin/perl
-# debbugs-spamscan-log is part of debbugs, and is released
-# under the terms of the GPL version 2, or any later version, at your
-# option. See the file README and COPYING for more information.
-# Copyright 2012 by Don Armstrong <don@donarmstrong.com>.
-
-
-use warnings;
-use strict;
-
-use Getopt::Long qw(:config no_ignore_case);
-use Pod::Usage;
-
-=head1 NAME
-
-debbugs-spamscan-log -- Scan log files for spam and populate nnn.log.spam
-
-=head1 SYNOPSIS
-
-debbugs-spamscan-log [options] bugnumber [[bugnumber2]..]
-
- Options:
-  --spool-dir debbugs spool directory
-  --debug, -d debugging level (Default 0)
-  --help, -h display this help
-  --man, -m display manual
-
-=head1 OPTIONS
-
-=over
-
-=item B<--spool-dir>
-
-Debbugs spool directory; defaults to the value configured in the
-debbugs configuration file.
-
-=item B<--debug, -d>
-
-Debug verbosity.
-
-=item B<--help, -h>
-
-Display brief useage information.
-
-=item B<--man, -m>
-
-Display this manual.
-
-=back
-
-=head1 EXAMPLES
-
-Rebuild the index.db for db-h.
-
- debbugs-spamscan-log;
-
-Rebuild the index.db for archive
-
- debbugs-spamscan-log archive;
-
-
-=cut
-
-
-use vars qw($DEBUG);
-
-use Debbugs::Log qw(record_regex);
-use Debbugs::Log::Spam;
-use Debbugs::Config qw(:config);
-use IPC::Open3 qw(open3);
-
-my %options =
-    (debug   => 0,
-     help    => 0,
-     man     => 0,
-     verbose => 0,
-     quiet   => 0,
-     quick   => 0,
-     spamc   => 'spamc',
-     spamc_opts => [],
-    );
-
-
-GetOptions(\%options,
-           'quick|q',
-           'service|s',
-           'sysconfdir|c',
-           'spool_dir|spool-dir=s',
-           'spamc=s',
-           'spamc_opts|spamc-opts=s@',
-           'debug|d+','help|h|?','man|m');
-
-pod2usage() if $options{help};
-pod2usage({verbose=>2}) if $options{man};
-
-$DEBUG = $options{debug};
-
-my @USAGE_ERRORS;
-$options{verbose} = $options{verbose} - $options{quiet};
-
-if (not @ARGV) {
-    push @USAGE_ERRORS,
-        "You must provide a bug number to examine\n";
-}
-
-pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
-
-if (exists $options{spool_dir} and defined $options{spool_dir}) {
-    $config{spool_dir} = $options{spool_dir};
-}
-chdir($config{spool_dir}) or die "chdir $config{spool_dir} failed: $!";
-
-for my $bug_num (@ARGV) {
-    my $log = Debbugs::Log->new(bug_num => $bug_num) or
-        die "Unable to open bug log for $bug_num";
-    my $spam = Debbugs::Log::Spam->new(bug_num => $bug_num) or
-        die "Unable to open bug log spam for $bug_num";
-
-    my %seen_msgids;
-    while (my $record = $log->read_record()) {
-        next if $record->{type} eq 'html';
-        next if $record->{type} eq 'autocheck';
-        my ($msg_id) = record_regex($record,
-                                    qr/^Message-Id:\s+<(.+)>/mi);
-        next unless defined $msg_id;
-        if ($msg_id =~ /$config{email_domain}$/) {
-            print STDERR "skipping $msg_id\n" if $DEBUG;
-            next;
-        }
-        print STDERR "examining $msg_id: " if $DEBUG;
-        if ($seen_msgids{$msg_id}) {
-            print STDERR "already seen\n" if $DEBUG;
-            next;
-        }
-        $seen_msgids{$msg_id}=1;
-        if ($spam->is_spam($msg_id)) {
-            print STDERR "already spam\n" if $DEBUG;
-            next;
-        }
-        my $is_spam;
-        eval {
-            my ($spamc,$child_out);
-            my $old_sig = $SIG{"PIPE"};
-            $SIG{"PIPE"} = sub {
-                die "SIGPIPE in child for some reason";
-            };
-            my $childpid =
-                open3($spamc,$child_out,0,
-                      $options{spamc},'-E',@{$options{spamc_opts}}) or
-                          die "Unable to fork spamc: $!";
-            if (not $childpid) {
-                die "Unable to fork spamc";
-            }
-            print {$spamc} $record->{text};
-            close($spamc) or die "Unable to close spamc: $!";
-            waitpid($childpid,0);
-            if ($DEBUG) {
-                print STDERR "[$?;".($? >> 8)."] ";
-                print STDERR map {s/\n//; $_ } <$child_out>;
-                print STDERR " ";
-            }
-            close($child_out);
-            $SIG{"PIPE"} = $old_sig;
-            if ($? >> 8) {
-                $is_spam = 1;
-            }
-        };
-        if ($@) {
-            print STDERR "processing of $msg_id failed [$@]\n";
-        } else {
-            if ($is_spam) {
-                print STDERR "it's spam\n" if $DEBUG;
-                $spam->add_spam($msg_id);
-            }
-            else {
-                print STDERR "it's ham\n" if $DEBUG;
-            }
-        }
-    }
-    $spam->save();
-}
-
-
-__END__
-
-# Local Variables:
-# cperl-indent-level: 4
-# indent-tabs-mode: nil
-# End:
index 482592344c5b21503af0a7f6185cc07c10eef777..3e397f38999b8b9126b83e3d6e1e723ccd7cf0ef 100755 (executable)
@@ -204,12 +204,12 @@ if ($options{daemon}) {
 \$gSpoolDir = "$options{mirror_location}";
 \$gTemplateDir = "$options{template_dir}";
 \$gWebHost = 'localhost:$options{port}';
-\$gPackageSource = '';
+\$gPackageSource = '$options{mirror_location}/sources';
 \$gPseudoDescFile = '';
 \$gPseudoMaintFile = '';
-\$gMaintainerFile = '';
+\$gMaintainerFile = '$options{mirror_location}/Maintainers';
 \$gMaintainerFileOverride = '';
-\$config{source_maintainer_file} = '';
+\$config{source_maintainer_file} = '$options{mirror_location}/Source_maintainers';
 \$config{source_maintainer_file_override} = '';
 \$gProject = 'Local Debbugs';
 1;
index ab0d792bab18c64031124fe5063adeefdd460e23..4fcec4d4c6b0b4b70e759d26fda8361fa49a7d93 100644 (file)
@@ -1,4 +1,11 @@
-debbugs (2.6.0~exp1) UNRELEASED; urgency=low
+debbugs (3.0.0~alpha.1) unstable; urgency=medium
+
+  * Use Text::Xslate instead of Text::Template; Text::Xslate is significantly
+    faster.
+
+ -- Don Armstrong <don@debian.org>  Fri, 09 Mar 2018 11:17:10 -0800
+
+debbugs (2.6.0) unstable; urgency=medium
 
   [ Don Armstrong ]
   * Hack around elinks css bug (closes: #593804)
@@ -61,6 +68,15 @@ debbugs (2.6.0~exp1) UNRELEASED; urgency=low
     Thanks to Julien Cristau
   * Use pass-through for rewrites of URLs to hide implementation (Closes:
     #871784) Thanks to Ridier 'OdyX' Raboud
+  * Use foo <bar@baz.com> instead of bar@baz.com (foo) for From: (Closes:
+    #881903). Thanks to Michael Stapelberg.
+  * Add rel="canonical" links to bug pages (Closes: #890338). Thanks to Chris
+    Lamb.
+  * Fix blocks/blockedby of archived bugs (Closes: #892060). Thanks to Laurent Bigonville.
+  * Provide informative error message when unarchive fails because the bug is
+    not archived. (Closes: #892135). Thanks to Dan Jacobson.
+  * Update standards version to 4.1.3; add Testsuite, fix Homepage and git repos
+    links, update priority.
 
   [ Niels Thykier ]
   * quitcgi() now returns 400/500 status codes instead of 200 (Closes: #584922)
index 772915351d2d347d01d198f62b5594c97c864a0a..0226f703ca7f17b40413d66c03ea31b6c0c4b796 100644 (file)
@@ -1,24 +1,26 @@
 Source: debbugs
 Section: misc
-Priority: extra
+Priority: optional
 Maintainer: Debbugs developers <debian-debbugs@lists.debian.org>
 Uploaders: Colin Watson <cjwatson@debian.org>, Don Armstrong <don@debian.org>
-Standards-Version: 3.9.4
-Vcs-Browser: http://bugs.debian.org/debbugs-source/mainline
-Vcs-Git: http://bugs.debian.org/debbugs-source/debbugs.git
+Standards-Version: 4.1.3
+Vcs-Browser: https://salsa.debian.org/debbugs-team/debbugs
+Vcs-Git: https://salsa.debian.org/debbugs-team/debbugs.git
 Build-Depends: debhelper (>= 9)
 Build-Depends-Indep: libparams-validate-perl,
  libmailtools-perl, libmime-tools-perl, libio-stringy-perl, libmldbm-perl,
  liburi-perl, libsoap-lite-perl, libcgi-simple-perl,
  libhttp-server-simple-perl, libtest-www-mechanize-perl,
- libmail-rfc822-address-perl, libsafe-hole-perl, libuser-perl,
+ libmail-rfc822-address-perl, libuser-perl,
  libconfig-simple-perl, libtest-pod-perl, liblist-allutils-perl,
  libfile-libmagic-perl, libgravatar-url-perl, libwww-perl, imagemagick,
- libdbix-class-perl, libdatetime-format-pg-perl,
+ libdbix-class-perl, libdatetime-format-pg-perl, libtest-postgresql-perl,
  libdatetime-format-mail-perl,
- libtext-template-perl, graphviz, libtext-iconv-perl, libnet-server-perl,
- libtest-postgresql-perl
-Homepage: http://wiki.debian.org/Teams/Debbugs
+ libtext-xslate-perl, graphviz, libtext-iconv-perl, libnet-server-perl,
+# used to make the logo
+ inkscape
+Homepage: https://salsa.debian.org/debbugs-team
+Testsuite: autopkgtest-pkg-perl
 
 Package: debbugs
 Architecture: all
@@ -45,12 +47,11 @@ Architecture: all
 Depends:
  ${misc:Depends}, ${perl:Depends}, libmailtools-perl, ed, libmime-tools-perl,
  libio-stringy-perl, libmldbm-perl, liburi-perl, libsoap-lite-perl,
- libcgi-simple-perl, libparams-validate-perl, libtext-template-perl,
- libsafe-hole-perl, libmail-rfc822-address-perl, liblist-moreutils-perl,
- libtext-template-perl,
- # used by Debbugs::Libravatar and libravatar.cgi
- libfile-libmagic-perl,
- libgravatar-url-perl, libwww-perl, imagemagick,
+ libcgi-simple-perl, libparams-validate-perl, libtext-xslate-perl,
+ libmail-rfc822-address-perl, liblist-allutils-perl,
+ graphviz, libtext-iconv-perl, libuser-perl,
+# used by Debbugs::Libravatar and libravatar.cgi
+ libfile-libmagic-perl, libgravatar-url-perl, libwww-perl, imagemagick
  # used by the database
  libdatetime-format-mail-perl, libdbix-class-perl, libdatetime-format-pg-perl
 Section: perl
index 7ba75071af081e76353ab644102d1e09d5b0cf89..56f304b93a8998121a5b83761ad2e1c6dfcd4acc 100644 (file)
@@ -14,7 +14,7 @@ Former developers have been:
        Darren Benham <gecko@debian.org>
 
 The sources can be obtained by:
-       bzr get http://bugs.debian.org/debbugs-source/mainline
+       git clone https://salsa.debian.org/debbugs-team/debbugs.git
 
 Copyright 1994-1997 Ian Jackson
 Copyright 1997,2003 nCipher Corporation Limited
index 30985872c1a05145ea9bd066c56aae9d4bd23ebf..6d2269605afc03b799d6c039ed6863e322f29dbc 100755 (executable)
@@ -187,26 +187,37 @@ for my $suite (@{$suites}) {
     my $suitedir = "$toplevel/$suite";
 
     for my $component ('main', 'main/debian-installer',
-                      'contrib', 'non-free') {
+                      'contrib', 'contrib/debian-installer',
+                      'non-free', 'non-free/debian-installer',
+                     ) {
        my $componentdir = "$suitedir/$component";
-       next unless -d $componentdir;
+       if (not -d $componentdir) {
+           print STDERR "No directory $suitedir/$component\n" if $DEBUG;
+           next;
+       }
        my $COMPONENT;
        opendir $COMPONENT, $componentdir or die "opendir $componentdir: $!";
 
        # debian-installer is really a section rather than a component
        # (ugh).
-       (my $viscomponent = $component) =~ s[/.*][];
-
-       my $sources = (grep { -f $_ } glob "$suitedir/$component/source/Sources.*")[0];
-       next unless defined $sources;
-       read_packages($db,$db2,$sources, $viscomponent,'source',$suite);
-
+       my $viscomponent = $component;
+       $viscomponent =~ s[/.*][];
+
+       my $sources = (grep { -f $_ } glob "$componentdir/source/Sources.*")[0];
+       if (not defined $sources) {
+           print STDERR "No sources matching $componentdir/source/Sources.*\n" if $DEBUG;
+       } else {
+           read_packages($db,$db2,$sources, $viscomponent,'source',$suite);
+       }
        for my $arch (readdir $COMPONENT) {
            next unless $arch =~ s/^binary-//;
            my $archdir = "$componentdir/binary-$arch";
 
            my $packages = (grep { -f $_ } glob("$archdir/Packages.*"))[0];
-           next unless defined $packages;
+           if (not defined $packages) {
+               print STDERR "No binary packages matching $archdir/Packages.*\n" if $DEBUG;
+               next;
+           }
            read_packages($db,$db2,$packages, $viscomponent,$arch,$suite);
        }
 
index 7be6f38a198ac2c3305667d86ef51c00c0ec7d09..ac4a54a968e6047437a5ad9d0e9ee0ec824e32f0 100755 (executable)
@@ -1,12 +1,14 @@
 #! /usr/bin/perl -w
 
-use vars qw($gVersionPackagesDir);
-require '/etc/debbugs/config';
-my $root = $gVersionPackagesDir;
 
+use warnings;
 use strict;
+
+use Debbugs::Config qw(:config);
 use Debbugs::Versions;
 use Debbugs::Versions::Dpkg;
+my $root = $config{version_packages_dir};
+
 
 unless (-d $root) {
     mkdir $root or die "can't mkdir $root: $!\n";
diff --git a/future_directions b/future_directions
deleted file mode 100644 (file)
index 2aad806..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-Here are outlined some of the future directions for the debbugs
-codebase and things that should be done.
-
-PACKAGE CLEANUP
-
-* Stop doing the .in -> foo translation
-  - We no longer do this
-* Use ExtUtils::Makemaker instead of a custom makefile
-  - We use Makemaker for the easy perl bits
-* More testing of modules so it's not so easy to break things
-
-
-GENERAL ORGANIZATIONAL CLEANUP
-
-* Modularization
-  * use of strict and warnings everywhere
-  * Split out errorlib and common.pl; stop requiring stuff
-  * Use CGI::Simple, URI, and Params::Validate instead of our own
-    versions
-
-* Configuration Module
-  * Allow for multiple debbugs configurations; easy overriding of values
-  * Possibly implemented using Config::General (maybe Config::Simple?)
-    with hack to allow for backwards compatibility
-    - The backwards compatibility hack is now fully implemented, a
-      decision on a configuration system just needs to be made.
-
-* Separation of Output forms from the code
-  * Use Text::Template to do this; it's simple, we don't lose
-    flexibility if we need it
-
-* Bring back all of the helper scripts into the bzr repository and
-  document the setup of Debian's bts
-
-FEATURES
-
-* Full text searching -- using Hyper Estraier (in progress on merkel)
-  * See Debbugs::Estraier
-
-* CGI Options enable/disable forms
-
-* Better display of bugs in bug lists
-  - Display subsidiary bugs: merged bugs, block bugs, etc.
-
-* Archiving [display of applicable bugs even if they are archived]
-
-BUG FIXING
-
-* ... 
\ No newline at end of file
index 1fb01986dae2e2565acb8571555cb896204cb5a0..7bddb101ded04d265c34427a374ebf0f96c4d53a 100644 (file)
@@ -53,25 +53,12 @@ a:link:hover, a:visited:hover {
     color: #d81e1e;
 }
 
-.link {
+.link, .link abbr, .link abbr:hover {
     color: #1b56ce;
     font-weight: bold;
     text-decoration: underline;
 }
 
-.link abbr {
-    color: #1b56ce;
-    font-weight: bold;
-    text-decoration: underline;
-}
-
-.link abbr:hover {
-    color: #1b56ce;
-    font-weight: bold;
-    text-decoration: underline;
-}
-
-
 .link span:hover {
     color: #d81e1e;
 }
@@ -138,16 +125,7 @@ div.headers {
     overflow: auto;
  }
 
-div.header {
-    font-family: sans-serif;
-    font-size: 95%;
-    color: #3c3c3c;
-    padding: 0px;
-    line-height: 120%;
-    margin: 0px;
-}
-
-div.headers p {
+div.header, div.headers p {
     font-family: sans-serif;
     font-size: 95%;
     color: #3c3c3c;
@@ -186,17 +164,12 @@ pre.mime {
     color: #686868;
 }
 
-.msgreceived p {
+.msgreceived p, p.msgreceived {
     width: 120ch;
     margin-top: 0px;
     margin-bottom: 0px;
 }
 
-p.msgreceived {
-    width: 120ch;
-    margin-top: 0px;
-    margin-bottom: 0px;
-}
 
 .buginfo p
 { 
diff --git a/html/logo/.gitignore b/html/logo/.gitignore
new file mode 100644 (file)
index 0000000..5cde14c
--- /dev/null
@@ -0,0 +1 @@
+debbugs_logo_icon.png
diff --git a/html/logo/Makefile b/html/logo/Makefile
new file mode 100644 (file)
index 0000000..82ceaab
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/make -f
+
+all: debbugs_logo.svg debbugs_logo_icon.png
+
+## if you want to modify debbugs_logo.svg do the modifications to
+## debbugs_logo_orig.svg, and then run make update_debbugs_logo and check the
+## changes in.
+update_debbugs_logo: debbugs_logo_orig.svg
+       inkscape --without-gui \
+       --export-text-to-path --export-plain-svg debbugs_logo.svg $<;
+
+debbugs_logo_icon.png: debbugs_logo.svg
+       inkscape --without-gui \
+       --export-width 32 --export-height 32 \
+       --export-background=white \
+       --export-png $@ $<
diff --git a/html/logo/debbugs_logo.svg b/html/logo/debbugs_logo.svg
new file mode 100644 (file)
index 0000000..022165a
--- /dev/null
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:ns2="http://ns.adobe.com/AdobeIllustrator/10.0/"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   id="svg8"
+   version="1.1"
+   viewBox="0 0 40 40.000001"
+   height="40mm"
+   width="40mm">
+  <defs
+     id="defs2" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     transform="translate(-63.88401,-92.795649)"
+     id="layer1">
+    <g
+       transform="translate(3.1750001,-0.52916667)"
+       id="g3789">
+      <g
+         style="overflow:visible"
+         id="g97"
+         transform="matrix(0.26458333,0,0,0.26458333,63.905735,94.420958)">
+        <g
+           ns2:rgbTrio="#4F008000FFFF"
+           ns2:dimmedPercent="50"
+           ns2:layer="yes"
+           id="Layer_1">
+          <g
+             id="g74">
+            <path
+               id="path50"
+               d="m 51.986,57.297 c -1.797,0.025 0.34,0.926 2.686,1.287 0.648,-0.506 1.236,-1.018 1.76,-1.516 -1.461,0.358 -2.948,0.366 -4.446,0.229"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path52"
+               d="m 61.631,54.893 c 1.07,-1.477 1.85,-3.094 2.125,-4.766 -0.24,1.192 -0.887,2.221 -1.496,3.307 -3.359,2.115 -0.316,-1.256 -0.002,-2.537 -3.612,4.546 -0.496,2.726 -0.627,3.996"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path54"
+               d="m 65.191,45.629 c 0.217,-3.236 -0.637,-2.213 -0.924,-0.978 0.335,0.174 0.6,2.281 0.924,0.978"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path56"
+               d="m 45.172,1.399 c 0.959,0.172 2.072,0.304 1.916,0.533 1.049,-0.23 1.287,-0.442 -1.916,-0.533"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path58"
+               d="M 47.088,1.932 46.41,2.072 47.041,2.016 47.088,1.932"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path60"
+               d="m 76.992,46.856 c 0.107,2.906 -0.85,4.316 -1.713,6.812 l -1.553,0.776 c -1.271,2.468 0.123,1.567 -0.787,3.53 -1.984,1.764 -6.021,5.52 -7.313,5.863 -0.943,-0.021 0.639,-1.113 0.846,-1.541 -2.656,1.824 -2.131,2.738 -6.193,3.846 L 60.16,65.878 C 50.142,70.591 36.226,61.251 36.409,48.507 c -0.107,0.809 -0.304,0.607 -0.526,0.934 -0.517,-6.557 3.028,-13.143 9.007,-15.832 5.848,-2.895 12.704,-1.707 16.893,2.197 -2.301,-3.014 -6.881,-6.209 -12.309,-5.91 -5.317,0.084 -10.291,3.463 -11.951,7.131 -2.724,1.715 -3.04,6.611 -4.227,7.507 -1.597,11.737 3.004,16.808 10.787,22.773 1.225,0.826 0.345,0.951 0.511,1.58 -2.586,-1.211 -4.954,-3.039 -6.901,-5.277 1.033,1.512 2.148,2.982 3.589,4.137 -2.438,-0.826 -5.695,-5.908 -6.646,-6.115 4.203,7.525 17.052,13.197 23.78,10.383 -3.113,0.115 -7.068,0.064 -10.566,-1.229 -1.469,-0.756 -3.467,-2.322 -3.11,-2.615 9.182,3.43 18.667,2.598 26.612,-3.771 2.021,-1.574 4.229,-4.252 4.867,-4.289 -0.961,1.445 0.164,0.695 -0.574,1.971 2.014,-3.248 -0.875,-1.322 2.082,-5.609 l 1.092,1.504 c -0.406,-2.696 3.348,-5.97 2.967,-10.234 0.861,-1.304 0.961,1.403 0.047,4.403 1.268,-3.328 0.334,-3.863 0.66,-6.609 0.352,0.923 0.814,1.904 1.051,2.878 -0.826,-3.216 0.848,-5.416 1.262,-7.285 -0.408,-0.181 -1.275,1.422 -1.473,-2.377 0.029,-1.65 0.459,-0.865 0.625,-1.271 -0.324,-0.186 -1.174,-1.451 -1.691,-3.877 0.375,-0.57 1.002,1.478 1.512,1.562 -0.328,-1.929 -0.893,-3.4 -0.916,-4.88 -1.49,-3.114 -0.527,0.415 -1.736,-1.337 -1.586,-4.947 1.316,-1.148 1.512,-3.396 2.404,3.483 3.775,8.881 4.404,11.117 -0.48,-2.726 -1.256,-5.367 -2.203,-7.922 0.73,0.307 -1.176,-5.609 0.949,-1.691 C 83.519,18.706 76.074,10.902 69.225,7.24 70.063,8.007 71.121,8.97 70.741,9.121 67.335,7.093 67.934,6.935 67.446,6.078 64.671,4.949 64.489,6.169 62.651,6.08 57.421,3.306 56.413,3.601 51.6,1.863 l 0.219,1.023 c -3.465,-1.154 -4.037,0.438 -7.782,0.004 -0.228,-0.178 1.2,-0.644 2.375,-0.815 -3.35,0.442 -3.193,-0.66 -6.471,0.122 0.808,-0.567 1.662,-0.942 2.524,-1.424 -2.732,0.166 -6.522,1.59 -5.352,0.295 -4.456,1.988 -12.37,4.779 -16.811,8.943 l -0.14,-0.933 c -2.035,2.443 -8.874,7.296 -9.419,10.46 l -0.544,0.127 c -1.059,1.793 -1.744,3.825 -2.584,5.67 -1.385,2.36 -2.03,0.908 -1.833,1.278 -2.724,5.523 -4.077,10.164 -5.246,13.97 0.833,1.245 0.02,7.495 0.335,12.497 -1.368,24.704 17.338,48.69 37.785,54.228 2.997,1.072 7.454,1.031 11.245,1.141 -4.473,-1.279 -5.051,-0.678 -9.408,-2.197 -3.143,-1.48 -3.832,-3.17 -6.058,-5.102 l 0.881,1.557 c -4.366,-1.545 -2.539,-1.912 -6.091,-3.037 l 0.941,-1.229 C 28.751,98.334 26.418,96.056 25.78,94.795 l -1.548,0.061 c -1.86,-2.295 -2.851,-3.949 -2.779,-5.23 l -0.5,0.891 c -0.567,-0.973 -6.843,-8.607 -3.587,-6.83 -0.605,-0.553 -1.409,-0.9 -2.281,-2.484 l 0.663,-0.758 c -1.567,-2.016 -2.884,-4.6 -2.784,-5.461 0.836,1.129 1.416,1.34 1.99,1.533 -3.957,-9.818 -4.179,-0.541 -7.176,-9.994 L 8.412,66.472 C 7.926,65.74 7.631,64.945 7.24,64.165 l 0.276,-2.75 C 4.667,58.121 6.719,47.409 7.13,41.534 7.415,39.145 9.508,36.602 11.1,32.614 l -0.97,-0.167 c 1.854,-3.234 10.586,-12.988 14.63,-12.486 1.959,-2.461 -0.389,-0.009 -0.772,-0.629 4.303,-4.453 5.656,-3.146 8.56,-3.947 3.132,-1.859 -2.688,0.725 -1.203,-0.709 5.414,-1.383 3.837,-3.144 10.9,-3.846 0.745,0.424 -1.729,0.655 -2.35,1.205 4.511,-2.207 14.275,-1.705 20.617,1.225 7.359,3.439 15.627,13.605 15.953,23.17 l 0.371,0.1 c -0.188,3.802 0.582,8.199 -0.752,12.238 l 0.908,-1.912"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path62"
+               d="m 32.372,59.764 -0.252,1.26 c 1.181,1.604 2.118,3.342 3.626,4.596 -1.085,-2.118 -1.891,-2.993 -3.374,-5.856"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path64"
+               d="m 35.164,59.654 c -0.625,-0.691 -0.995,-1.523 -1.409,-2.352 0.396,1.457 1.207,2.709 1.962,3.982 l -0.553,-1.63"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path66"
+               d="m 84.568,48.916 -0.264,0.662 c -0.484,3.438 -1.529,6.84 -3.131,9.994 1.77,-3.328 2.915,-6.968 3.395,-10.656"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path68"
+               d="M 45.527,0.537 C 46.742,0.092 48.514,0.293 49.803,0 48.123,0.141 46.451,0.225 44.8,0.438 l 0.727,0.099"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path70"
+               d="m 2.872,23.219 c 0.28,2.592 -1.95,3.598 0.494,1.889 1.31,-2.951 -0.512,-0.815 -0.494,-1.889"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+            <path
+               id="path72"
+               d="M 0,35.215 C 0.563,33.487 0.665,32.449 0.88,31.449 -0.676,33.438 0.164,33.862 0,35.215"
+               ns2:knockout="Off"
+               style="fill:#a80030" />
+          </g>
+        </g>
+      </g>
+      <g
+         id="text101"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;line-height:125%;font-family:Prociono;-inkscape-font-specification:Prociono;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         aria-label="Debbugs">
+        <path
+           id="path28"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 66.013394,131.06845 c 0.2286,-0.0169 0.728133,-0.0339 1.176866,-0.0339 0.5842,0 1.312334,0.0847 1.769534,0.0847 h 0.1778 c 1.1938,0 2.853266,-0.8636 2.853266,-3.51367 0,-1.97273 -0.8128,-2.83633 -2.650066,-2.83633 h -0.1778 c -0.567267,0 -0.5842,0.0847 -1.972734,0.0847 -0.448733,0 -0.948266,-0.0169 -1.176866,-0.0339 v 0.31327 l 0.118533,0.008 c 0.397933,0.0254 0.575733,0.0593 0.5842,0.3302 0.0508,1.68487 0.05927,4.826 0.05927,4.89374 0,0.32173 -0.338667,0.36406 -0.762,0.38946 z m 1.583266,-1.18533 c 0,-0.44874 0.03387,-3.6068 0.06773,-4.50427 l 0.09313,-0.0931 c 0.1778,-0.0593 0.550333,-0.0931 1.0922,-0.0931 1.566333,0 2.269066,0.8382 2.269066,2.68394 0,0.80433 -0.143933,1.38853 -0.338666,1.73566 -0.338667,0.6096 -0.6096,0.98214 -1.507067,0.98214 -1.3462,0 -1.6764,-0.14394 -1.6764,-0.7112 z" />
+        <path
+           id="path30"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 72.586834,128.98565 c 0,1.00753 0.321734,2.2098 1.744133,2.2098 0.7366,0 1.210734,-0.5588 1.7018,-1.05833 l -0.186266,-0.19474 c -0.414867,0.4064 -0.829734,0.60114 -1.3462,0.60114 -1.0922,0 -1.100667,-0.84667 -1.100667,-1.68487 h 1.735667 c 0.3556,0 0.668866,-0.0339 0.889,-0.16933 -0.0085,-0.5842 0.09313,-2.04894 -1.634067,-2.04894 -0.651933,0 -1.456266,0.6858 -1.617133,1.04987 -0.06773,0.16087 -0.186267,0.69427 -0.186267,1.2954 z m 0.829734,-0.508 c 0,-0.889 0.127,-1.28693 0.939799,-1.28693 0.762,0 0.880534,0.74506 0.880534,1.13453 -0.2032,0.14393 -0.643467,0.1524 -1.337734,0.1524 z" />
+        <path
+           id="path32"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 76.369714,124.52372 0.01693,0.2794 c 0.618066,0 0.550333,0 0.592666,0.762 0.04233,0.762 0.01693,2.29446 0.03387,5.1054 0.237066,0.3302 1.032933,0.52493 1.413933,0.52493 0.296333,0 0.592667,-0.0254 0.821267,-0.127 0.4572,-0.2032 0.931333,-0.72813 0.982133,-0.79587 0.2794,-0.42333 0.364067,-0.95673 0.364067,-1.69333 0,-1.12607 -0.220134,-1.97273 -1.540934,-1.97273 -0.169333,0 -0.389466,0.0508 -1.303866,0.55033 l 0.03387,-2.34527 v -0.36406 c 0,-0.0931 -0.0762,-0.127 -0.143933,-0.127 -0.09313,0 -0.440267,0.127 -1.27,0.2032 z m 1.363133,4.74133 c 0,-0.28787 0,-0.67733 0.0085,-1.18533 v -0.5588 c 0.6096,-0.32174 0.753533,-0.3302 0.9398,-0.3302 0.4572,0 1.159933,0.2286 1.159933,1.45626 0,0.0593 -0.03387,1.03294 -0.143933,1.38854 -0.160867,0.52493 -0.414867,0.57573 -0.804333,0.57573 -0.440267,0 -0.948267,-0.21167 -1.075267,-0.37253 -0.06773,-0.0677 -0.08467,-0.23707 -0.08467,-0.97367 z" />
+        <path
+           id="path34"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 80.900703,124.52372 0.01693,0.2794 c 0.618067,0 0.550334,0 0.592667,0.762 0.04233,0.762 0.01693,2.29446 0.03387,5.1054 0.237066,0.3302 1.032933,0.52493 1.413933,0.52493 0.296333,0 0.592666,-0.0254 0.821266,-0.127 0.4572,-0.2032 0.931334,-0.72813 0.982134,-0.79587 0.2794,-0.42333 0.364066,-0.95673 0.364066,-1.69333 0,-1.12607 -0.220133,-1.97273 -1.540933,-1.97273 -0.169333,0 -0.389467,0.0508 -1.303867,0.55033 l 0.03387,-2.34527 v -0.36406 c 0,-0.0931 -0.0762,-0.127 -0.143933,-0.127 -0.09313,0 -0.440267,0.127 -1.27,0.2032 z m 1.363133,4.74133 c 0,-0.28787 0,-0.67733 0.0085,-1.18533 v -0.5588 c 0.6096,-0.32174 0.753533,-0.3302 0.9398,-0.3302 0.4572,0 1.159933,0.2286 1.159933,1.45626 0,0.0593 -0.03387,1.03294 -0.143933,1.38854 -0.160867,0.52493 -0.414867,0.57573 -0.804334,0.57573 -0.440266,0 -0.948266,-0.21167 -1.075266,-0.37253 -0.06773,-0.0677 -0.08467,-0.23707 -0.08467,-0.97367 z" />
+        <path
+           id="path36"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 85.533293,126.85205 0.01693,0.28787 c 0.508,0.008 0.550333,-0.0254 0.550333,1.2954 v 0.80433 c 0,0.3556 0.04233,0.9144 0.08467,1.04987 0.127,0.49953 0.567266,0.85513 0.9652,0.85513 0.160866,0 0.7874,-0.0847 1.566333,-0.635 0.0508,0.1016 0.169333,0.6096 0.3556,0.6096 0.05927,0 0.651933,-0.19473 0.651933,-0.19473 0.05927,-0.0169 0.0762,-0.0339 0.0762,-0.0677 0,-0.1524 -0.381,-0.49953 -0.381,-0.8636 0,-0.61806 0.06773,-1.40546 0.06773,-3.24273 0,-0.1016 -0.08467,-0.127 -0.1524,-0.127 -0.09313,0 -0.4318,0.11853 -1.27,0.2032 l 0.01693,0.2794 h 0.270933 c 0.270934,0 0.321734,0 0.321734,0.70273 0,0.39794 -0.01693,1.02447 -0.01693,2.0066 0,0.26247 -0.01693,0.3048 -0.347133,0.47414 -0.160867,0.0847 -0.626533,0.18626 -0.8636,0.18626 -0.160867,0 -0.423333,-0.14393 -0.508,-0.38946 -0.06773,-0.18627 -0.08467,-0.4826 -0.08467,-0.8636 0,-0.52494 0.03387,-1.5494 0.03387,-2.47227 0,-0.1016 -0.08467,-0.127 -0.1524,-0.127 -0.09313,0 -0.4572,0.14393 -1.202267,0.2286 z" />
+        <path
+           id="path38"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 90.144582,131.77118 c 0,0.82127 1.083733,1.02447 1.735667,1.02447 1.651,0 2.201333,-0.84667 2.201333,-1.41393 0,-0.44027 -0.372533,-0.80434 -0.6096,-0.89747 -0.169333,-0.0677 -0.728133,-0.0847 -0.770467,-0.0847 h -1.007533 c -0.211667,0 -0.364067,-0.127 -0.364067,-0.28786 0,-0.21167 0.2286,-0.36407 0.694267,-0.4826 0.440267,-0.0931 0.762,-0.21167 1.0668,-0.38947 0.3556,-0.3302 0.491067,-0.635 0.491067,-1.10913 0,-0.26247 -0.0762,-0.72814 -0.169334,-0.8636 h 0.668867 v -0.3556 l -0.0508,-0.0508 c -0.254,0.0593 -0.601133,0.1016 -0.821267,0.11006 -0.372533,-0.31326 -0.728133,-0.33866 -0.9144,-0.33866 -0.889,0 -1.617133,0.7366 -1.727199,0.9652 -0.110067,0.24553 -0.143934,0.56726 -0.143934,0.77893 0,0.0677 0,0.127 0.0085,0.16087 0.1016,0.55033 0.313267,0.77893 0.880533,1.03293 -0.728133,0.22013 -0.753533,0.4826 -0.753533,0.6096 0,0.24553 0.245533,0.39793 0.668866,0.4572 -1.015999,0.4318 -1.083733,0.8636 -1.083733,1.13453 z m 0.728133,-0.24553 c 0,-0.54187 0.575734,-0.7112 1.405467,-0.7112 0.762,0 0.9906,0.31327 0.9906,0.64347 0,0.56726 -0.372533,1.00753 -1.2446,1.00753 -0.508,0 -1.151467,-0.39793 -1.151467,-0.9398 z m 0.3302,-3.2004 c 0,-0.93133 0.245534,-1.17687 0.626534,-1.17687 0.03387,0 0.0762,0 0.118533,0.008 0.643467,0.0762 0.829733,0.24553 0.829733,0.99907 0,0.8128 -0.169333,1.04986 -0.719666,1.04986 -0.575734,0 -0.855134,-0.38946 -0.855134,-0.88053 z" />
+        <path
+           id="path40"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           d="m 94.459276,128.03738 c 0,1.51554 2.091266,0.95674 2.091266,1.99814 0,0.39793 -0.296333,0.635 -0.795866,0.635 -0.389467,0 -0.592667,-0.11854 -0.702734,-0.27094 -0.237066,-0.32173 -0.05927,-0.77893 -0.347133,-0.77893 -0.2032,0 -0.2286,0.0762 -0.2286,0.99907 0,0.127 0.0254,0.22013 0.06773,0.28786 0.08467,0.14394 0.389467,0.3048 1.083734,0.3048 0.127,0 0.6096,-0.0677 0.804333,-0.21166 0.270933,-0.21167 0.372533,-0.33867 0.541867,-0.6096 0.110066,-0.18627 0.127,-0.42334 0.127,-0.6604 0,-1.5748 -2.074334,-1.05834 -2.074334,-2.04894 0,-0.1524 0.06773,-0.5588 0.7112,-0.5588 0.254,0 0.508,0.0593 0.635,0.24554 0.110067,0.16086 0.2032,0.52493 0.211667,0.64346 h 0.313267 c 0,-0.49953 0.0254,-0.74506 0.0254,-0.82973 0,-0.3048 -0.160867,-0.36407 -0.287867,-0.41487 -0.220133,-0.0931 -0.465667,-0.14393 -0.651933,-0.14393 -0.694267,0 -0.9652,0.11853 -1.380067,0.7874 -0.110067,0.16933 -0.143933,0.39793 -0.143933,0.62653 z" />
+      </g>
+      <g
+         id="text3723-71"
+         style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         aria-label="🐜
+🐛🐞">
+        <path
+           id="path43"
+           style="text-align:end;text-anchor:end;stroke-width:0.26458332px"
+           d="m 97.013367,105.46749 q 0,0.0568 -0.06718,0.0982 -0.434082,0.0103 -0.950846,0.14987 -0.144694,0.0413 -0.382406,0.25838 -0.237711,0.21704 -0.37207,0.26355 -0.444417,0.031 -1.131714,0.093 -0.37207,0.0517 -0.594279,0.16019 -0.04134,0.0465 -0.139526,0.12403 -0.149862,0.093 -0.346232,0.093 -0.04134,0 -0.124024,-0.0103 -0.07751,-0.0155 -0.118855,-0.0155 -0.108521,0 -0.139527,0.10336 0.129191,0.0258 0.253215,0.0568 0.129191,0.031 0.217041,0.1447 0.01033,0.10335 0.04134,0.14986 0.134359,-0.0879 0.273885,-0.1757 0.124023,-0.0672 0.310059,-0.0672 0.304891,0 0.444417,0.0517 0.06201,0.0207 0.361735,0.26872 0.578776,0.47543 0.578776,0.95602 0,0.16019 -0.144694,0.49092 -0.139526,0.33073 -0.253215,0.43408 -0.134358,0.11886 -0.418579,0.23255 -0.279052,0.11369 -0.454752,0.11369 -0.356568,0 -0.707967,-0.28422 -0.299724,-0.24288 -0.496094,-0.59428 -0.06201,-0.11369 -0.06201,-0.56328 0,-0.12919 0.237712,-0.53226 -0.325562,-0.0568 -0.356568,-0.5116 -0.08268,0.0258 -0.08268,0.30489 0,0.27905 -0.08785,0.42892 -0.05684,0.0517 -0.144694,0.1757 -0.1757,0.42374 -0.1757,1.18339 0,0.33072 -0.05684,0.50126 -0.180867,0.21704 -0.423746,0.52193 -0.124024,0.1912 -0.217041,0.76998 -0.01034,0.13436 -0.02584,0.27388 -0.02584,0.21188 -0.08785,0.21188 -0.05168,0 -0.10852,-0.062 0,-0.55293 0.160197,-1.04386 0.118856,-0.23254 0.310058,-0.71313 0.01034,-0.13436 0.05168,-0.39791 0.02067,-0.0724 0.253214,-0.71314 0.196371,-0.53743 0.196371,-0.65112 0,-0.0413 -0.01033,-0.11369 -0.01034,-0.0775 -0.01034,-0.11885 0,-0.26872 0.180868,-0.40825 v -0.093 q -0.02584,-0.0155 -0.113688,-0.0155 -0.05684,0 -0.07235,0.005 -0.03617,0.0465 -0.372071,0.53743 -0.258382,0.38241 -0.382405,0.46509 -0.03101,0.0207 -0.160197,0.031 -0.196371,0.27905 -0.392741,0.5581 -0.227376,0.30489 -0.490926,0.48576 -0.02067,0.3204 -0.04651,0.64596 -0.03101,0.46508 -0.103353,0.56844 -0.10852,-0.005 -0.10852,-0.20671 0,-0.0413 0.0155,-0.12402 0.02067,-0.0775 0.02067,-0.11886 v -0.93017 q 0,-0.15503 0.45992,-0.54261 0.501262,-0.41857 0.5271,-0.47542 0,0 0,-0.093 0,-0.11368 0.335897,-0.39791 0.222208,-0.18603 0.444417,-0.37207 -0.04134,0 -0.124023,0.0155 -0.08268,0.0103 -0.124024,0.0103 -0.206706,0 -0.558105,-0.34623 -0.346232,-0.3514 -0.552938,-0.3514 0.03101,0 -0.434082,0.0362 l -0.868164,0.0672 q -0.02584,0 -0.08268,-0.0413 -0.05684,-0.0413 -0.08268,-0.0413 -0.06718,0 -0.465088,0.20671 -0.39274,0.20154 -0.485758,0.27388 -0.124023,0.093 -0.19637,0.37207 -0.07235,0.27389 -0.124024,0.29973 -0.129191,-0.0465 -0.129191,-0.0878 0,-0.0258 0.05684,-0.1602 0.06718,-0.15503 0.07235,-0.18087 0.0155,-0.1602 0.05684,-0.48059 0.26355,-0.13436 0.81132,-0.3514 0.118856,-0.005 0.335897,-0.0517 0.04651,-0.0207 0.09302,-0.0878 0.03101,-0.0465 0.129191,-0.0465 0.702799,0 1.235066,0.10335 0.165365,0.031 0.625285,0.29455 0.418579,0.23772 0.573608,0.23772 -0.279052,-0.30489 -0.346232,-0.38241 -0.211873,-0.25321 -0.28422,-0.41858 -0.01033,-0.14986 -0.03617,-0.41341 -0.227377,0.20154 -0.465088,0.20154 -0.08268,0 -0.180868,-0.0568 -0.160197,-0.093 -0.170532,-0.0982 -0.0052,-0.005 -0.124024,-0.0207 -0.05684,-0.005 -0.09302,-0.093 -0.0052,-0.0103 -0.0052,-0.0982 0,-0.11886 -0.253214,-0.47026 l -1.788005,0.894 q -0.04134,-0.0465 -0.139526,-0.10335 -0.05168,-0.34623 -0.232544,-1.49862 -0.04651,-0.24288 -0.108521,-0.72863 l 0.02584,-0.0517 q 0.02067,-0.0103 0.04651,-0.0103 0.04134,0 0.05684,0.0362 0,0.005 0.118855,0.67179 l 0.248047,1.41077 0.03101,0.0362 1.674316,-0.86816 q -0.01033,-0.13953 -0.06718,-0.40825 -0.01033,-0.0258 -0.149862,-0.16019 v -0.1292 q 0.206706,0.0775 0.186036,0.0775 0.03617,0 0.149861,-0.10852 0.118856,-0.11369 0.118856,-0.14986 0,-0.0517 -0.07752,-0.12403 v -0.0723 h 0.134359 q 0.04134,0.0568 0.155029,0.14986 0.139527,0.0155 0.413412,0.0672 l 0.868164,-1.67432 -2.185913,-0.43925 q 0.06718,-0.0724 0.118856,-0.0724 0.02584,0 0.707967,0.10336 l 1.46761,0.22221 q 0.08268,0.0723 0.108521,0.14986 l -0.873332,1.77767 q 0.377238,0.25321 0.506429,0.25321 0.04651,0 0.06201,0.005 0.103353,0.0362 0.103353,0.1757 0,0.0362 0.07751,0.14986 0.08268,0.11369 0.08268,0.26872 0,0.2067 -0.201538,0.43408 0.144694,-0.0103 0.413411,0.0413 0.294556,0.13436 0.769979,0.64596 l 0.01034,-0.0258 q 0,-0.15503 -0.248047,-0.59428 -0.258382,-0.46509 -0.28422,-0.65629 -0.08268,-0.57361 -0.08268,-1.14205 0,-0.10852 0.05684,-0.15503 0.06201,-0.0465 0.07751,-0.0982 0,0 0,-0.16537 0,-0.0568 0.387574,-0.96118 0.07235,-0.0517 0.237711,-0.062 0.222209,-0.005 0.26355,-0.0155 0.04134,-0.0103 0.139526,-0.0672 0.07235,-0.0465 0.1757,-0.0465 0.05684,0 0.108521,0.11368 l -0.08268,0.0775 q -0.28422,0.062 -0.315226,0.0724 -0.155029,0.0517 -0.273885,0.17053 -0.04651,0.0465 -0.26355,0.47025 -0.211873,0.41858 -0.211873,0.46509 0,0.0258 0.03617,0.0827 0.04134,0.0517 0.04134,0.0775 l -0.09819,1.33325 q 0,0.19637 0.346232,0.55811 0.346233,0.36173 0.346233,0.49609 0,0.0517 -0.0155,0.14986 -0.01034,0.0982 -0.01034,0.1447 0.299724,-0.38241 0.330729,-0.41342 0.222209,-0.26355 0.377238,-0.3514 0.05684,0 0.160197,-0.0155 0.0155,-0.005 0.449585,-0.50643 0.413412,-0.48059 0.568441,-0.48059 h 0.945679 q 0.03617,0 0.103353,-0.0207 0.07235,-0.0207 0.10852,-0.0207 0.155029,0 0.217041,0.0878 -0.0155,0.0879 -0.165364,0.10335 -0.3514,0.0207 -1.049032,0.0724 -0.124023,0.23254 -0.475423,0.48576 -0.284221,0.19637 -0.568441,0.39791 0,0 0,0.0672 0,0.13436 -0.403076,0.3979 -0.108521,0.0724 -0.651123,0.45993 0.02584,0.0568 0.02067,0.16019 l 0.0155,0.0103 q 0.04134,0 0.227377,-0.0879 0.186035,-0.0878 0.320394,-0.0878 0.03101,0 0.08785,0.0103 0.06201,0.005 0.09302,0.005 0.06718,0 0.645955,-0.20154 0.645956,-0.21704 0.738973,-0.24288 0.129191,-0.005 0.377238,-0.0517 0.222209,-0.10336 0.676962,-0.28939 0.48059,-0.16537 1.100708,-0.16537 0.04134,0.0672 0.04134,0.0775 z" />
+        <path
+           id="path45"
+           style="text-align:end;text-anchor:end;stroke-width:0.26458332px"
+           d="m 86.48171,118.01574 q -0.02067,0.0258 -0.07752,0.0258 0.01034,0 -0.37207,-0.12919 -0.444417,-0.14986 -0.997355,-0.14986 -0.10852,0 -0.191203,0.0517 0.465088,0.45992 0.470256,0.47025 0.242879,0.27389 0.341064,0.56844 0.06718,0.19638 0.06718,0.3204 0,0.23254 -0.170533,0.40824 -0.06201,-0.0827 -0.08268,-0.22221 -0.0155,-0.12402 -0.03101,-0.24288 -0.08785,-0.40824 -0.578776,-0.82165 -0.485758,-0.41341 -0.89917,-0.41341 -0.04134,0 -0.07751,0.0155 0.03101,0.0879 0.124023,0.1912 0.299723,0.3359 0.604614,0.89401 0.3514,0.64078 0.3514,0.99218 0,0.0775 -0.08268,0.20671 h -0.07235 q -0.03101,-0.11369 -0.09302,-0.34623 -0.09819,-0.35657 -0.630452,-1.12655 -0.578776,-0.84233 -0.842326,-0.84233 -0.118856,0 -0.118856,0.0775 0,-0.005 0.07235,0.20671 0.09302,0.27388 0.661458,1.29707 0.170533,0.29456 0.335897,0.58911 0.222209,0.39791 0.253215,0.59945 l -0.04651,0.0465 q -0.149862,-0.0155 -0.909505,-1.10071 -0.630453,-0.9095 -0.8785,-1.33842 -0.30489,0.23771 -0.30489,0.40825 0,0.18603 0.521931,0.85783 0.341065,0.43924 0.687297,0.87849 0.258382,0.38241 0.346232,0.66663 l -0.02584,0.0879 -1.720825,-1.757 q -0.191203,0.16537 -0.191203,0.64079 0,0.0724 0.857829,0.76481 0.862996,0.69246 0.862996,0.8785 v 0.0879 q 0,0.0207 -0.05168,0.0258 -0.07751,0 -0.186036,-0.0879 -0.06718,-0.062 -0.19637,-0.18604 -0.248047,-0.22737 -0.645955,-0.48576 -0.490926,-0.31522 -0.7028,-0.32039 -0.08268,0.38757 -0.08268,0.65112 0,0.0413 0.02067,0.0724 0.07751,0.11369 0.346232,0.33073 0.253214,0.21187 0.39274,0.28422 0.3514,0.18604 0.800985,0.26355 v 0.0724 q -0.08785,0.10852 -0.248047,0.10852 -0.294555,0 -0.878499,-0.3204 -0.578776,-0.32039 -0.661458,-0.32039 -0.07235,0 -0.180868,0.13953 -0.10852,0.13952 -0.10852,0.21704 0,0.13436 0.496093,0.52193 0.0052,0.005 0.418579,0.27388 0.346233,0.22738 0.346233,0.25839 0,0.10852 -0.258383,0.10852 -0.661458,0 -1.410766,-0.75965 -0.268718,0.19121 -0.268718,0.23772 0,0.005 0.07235,0.2067 0.108521,0.31006 0.356568,0.61495 0.237711,0.26355 0.470255,0.53227 -0.08268,0.0672 -0.191203,0.0672 -0.377237,0 -0.775146,-0.57361 -0.397908,-0.56844 -0.485758,-0.56844 -0.227377,0 -0.227377,0.58394 0,0.23771 0.15503,0.56844 0.134358,0.26872 0.263549,0.53744 v 0.0723 h -0.129191 q -0.10852,0 -0.28422,-0.2222 -0.356567,-0.45476 -0.465088,-1.26091 -0.06718,-0.0155 -0.04134,-0.0155 0.02067,0 -0.165365,0.0517 -0.04651,0.0155 -0.439249,0.031 -0.237712,0.28939 -0.237712,0.73381 0,0.24804 0.04651,0.38757 0.03617,0.10852 0.03617,0.10335 v 0.18604 q -0.0155,0.0258 -0.06201,0.0258 -0.118856,0 -0.227377,-0.31522 -0.09302,-0.26872 -0.09302,-0.42375 0,-0.18087 0.04651,-0.39274 0.01033,-0.0362 0.07751,-0.25321 0.05684,-0.18604 0.05684,-0.22738 0,-0.0672 -0.05168,-0.10335 -0.0052,-0.005 -0.387573,-0.1602 -0.589112,-0.24288 -0.894003,-0.60978 -0.242879,-0.29456 -0.263549,-0.44959 0.0155,-0.0258 0.05684,-0.0258 0.02067,0 0.54777,0.42374 0.532267,0.41858 0.83199,0.41858 0.07752,0 0.129191,-0.0724 0.05168,-0.0723 0.09819,-0.13952 0.03617,-0.0413 0.19637,-0.13953 -0.217041,-0.15503 -0.640788,-0.47542 -0.10852,-0.0879 -0.294555,-0.32556 -0.206706,-0.26872 -0.206706,-0.36174 v -0.0827 q 0.0155,-0.0258 0.06201,-0.0258 0.08785,0 0.325561,0.21704 0.155029,0.14986 0.310059,0.29973 0.382405,0.32556 0.956014,0.60461 l 0.02584,-0.0103 q -0.397909,-0.42374 -0.795817,-0.84232 -0.563273,-0.64596 -0.563273,-0.90951 0,0.0724 0.02067,-0.13436 0.06718,-0.0258 0.07751,-0.0258 0.05168,0 0.09302,0.0672 0.356567,0.56327 1.049031,1.21439 0.149862,0.1447 0.294556,0.28422 0.191203,0.15503 0.366902,0.15503 0.149862,0 0.258383,-0.0878 -0.992188,-0.72347 -1.436605,-1.85518 l 0.03101,-0.0103 q 0.124023,0.005 0.800984,0.76998 0.676962,0.76481 0.925009,0.76481 0.08785,0 0.180867,-0.11369 0.09302,-0.11368 0.09819,-0.2067 -0.397908,-0.31523 -1.131714,-1.02319 -0.160197,-0.18604 -0.341064,-0.53227 -0.206706,-0.39274 -0.206706,-0.58395 0,-0.0723 0.02584,-0.11885 0.05168,0.005 0.08268,0.0413 0.07235,0.16536 0.253214,0.48059 0.07235,0.0775 0.206706,0.24288 0.563273,0.8785 1.255737,1.0542 0.237712,-0.36174 0.237712,-0.7183 v -0.031 q -0.454753,-0.27388 -1.049032,-0.84749 -0.713134,-0.69763 -0.713134,-1.04387 0,-0.0672 0.04651,-0.15503 h 0.04134 q 0.630453,0.63046 0.852662,0.82166 0.614949,0.5426 0.945678,0.61495 0.04651,-0.0879 0.139527,-0.48059 0.09302,-0.39274 0.09302,-0.49093 0,-0.24805 -0.909505,-0.8785 -0.909505,-0.63045 -0.909505,-0.7028 0,-0.10852 0.129191,-0.10852 0.242879,0 0.956014,0.50126 0.718302,0.4961 0.852661,0.4961 0.217041,0 0.521932,-0.54777 -0.583944,-0.6718 -0.925008,-1.03353 -0.08785,-0.093 -0.532267,-0.48059 0.01034,-0.11369 0.165364,-0.11369 0.325562,0 0.971517,0.64079 0.645955,0.63562 0.780314,0.63562 0.361735,0 0.361735,-0.3359 0,-0.41858 -0.320394,-0.81132 -0.289388,-0.35657 -0.702799,-0.53743 0.09819,-0.0724 0.191203,-0.0724 0.356567,0 0.72347,0.42891 0.294555,0.3359 0.465088,0.74931 0.05168,0.12919 0.103352,0.34623 0.05684,0.21188 0.356568,0.21188 0.361735,0 0.361735,-0.34623 0,-0.51677 -0.7028,-1.10588 -0.134358,-0.0827 -0.335896,-0.29972 l 0.08785,-0.0258 q 0.465088,0.20154 0.909506,0.72864 0.48059,0.56844 0.48059,1.02836 0,0.0723 -0.02067,0.14986 0.08268,0.0724 0.341064,0.0724 0.06201,0 0.191203,-0.22221 0.118856,-0.20154 0.139526,-0.28939 0.03101,-0.12919 0.03101,-0.21704 0,-0.22738 -0.118855,-0.41858 l 0.02067,-0.17053 q 0.139526,0.0362 0.253215,0.32556 0.103353,0.24804 0.103353,0.42374 0,0.10853 -0.05684,0.26872 -0.07235,0.19637 -0.08268,0.26872 0.103353,0.0465 0.310059,0.15503 0.0052,0.0207 0.0052,0.062 0,0.0879 -0.03617,0.1602 0.09819,0.0465 0.542602,0.12919 0.304891,0.0568 0.496094,0.29455 z" />
+        <path
+           id="path47"
+           style="text-align:end;text-anchor:end;stroke-width:0.26458332px"
+           d="m 97.02887,119.24564 q 0,0.0775 -0.108521,0.21187 -0.02067,0.0258 -0.387573,0.2067 -0.108521,0.0879 -0.356567,0.20671 -0.103353,0.0258 -0.341065,0.0258 -0.299723,0 -0.578776,-0.1602 0,0.49093 -0.06201,0.83716 -0.05684,0.18603 -0.165364,0.55294 -0.07752,0.29972 -0.149862,0.60461 -0.103353,0.38241 -0.237711,0.55811 -0.180868,0.24288 -1.751831,0.60978 -0.26355,0.062 -0.651123,0.062 -0.06201,0 -0.186036,-0.0207 0.04651,0.093 0.113689,0.28422 0.0155,0.062 0.0155,0.5271 0,0.12402 -0.165364,0.44959 -0.160197,0.32556 -0.26355,0.42891 -0.103353,0.10335 -0.232544,0.10335 -0.268717,0 -0.382405,-0.18087 -0.124024,-0.20153 -0.124024,-0.37207 0,-0.13952 0.180868,-0.22737 0.05168,-0.0258 0.232544,-0.031 0.134358,-0.16536 0.134358,-0.22221 0,-0.093 -0.129191,-0.42891 -0.129191,-0.33073 -0.191203,-0.40824 -0.02584,-0.031 -0.475423,-0.24288 -0.449585,-0.21704 -0.733805,-0.42892 -0.01033,-0.0103 -0.310059,-0.31006 l -0.02584,0.0362 q -0.06718,0.36173 -0.542602,0.5426 -0.134359,0.0517 -0.139527,0.0517 -0.124023,0 -0.258382,-0.20154 -0.08268,-0.12403 -0.08268,-0.27905 0,-0.11886 0.139526,-0.20154 0.07235,-0.0155 0.217041,-0.0672 0.139527,-0.0775 0.232544,-0.40308 -0.170532,-0.11885 -0.268717,-0.28939 -0.1757,-0.29455 -0.196371,-0.32039 -0.04134,0.005 -0.113688,0.005 -0.315226,0 -0.790649,-0.23771 -0.108521,-0.0568 -0.325562,-0.26355 -0.237711,-0.22221 -0.237711,-0.31006 0,-0.19637 0.113688,-0.3359 0.113688,-0.14469 0.304891,-0.14469 0.05684,0 0.242879,0.10335 0.07752,0.29455 0.170532,0.3669 0.01034,0.0103 0.356567,0.18087 0.0052,-0.0827 0.02067,-0.24805 0.08268,-0.16019 0.170532,-0.49092 -0.330729,-0.34624 -0.330729,-0.89401 0,-0.3979 0.253215,-0.72347 0,-0.0362 -0.03101,-0.0672 -0.160197,0.031 -0.372071,0.25839 -0.07235,-0.0465 -0.382405,-0.29973 v -0.26871 q 0.294556,-0.23772 0.273885,-0.23772 0.05168,0 0.149862,0.0414 0.103352,0.0362 0.155029,0.0362 0.07235,0 0.139526,-0.093 0.320394,-0.45475 0.583944,-0.66146 0.139526,-0.0672 0.341064,-0.26355 0.02067,-0.0465 0.02067,-0.093 0,-0.062 -0.03101,-0.16537 -0.03101,-0.10852 -0.03617,-0.14986 0.206705,-0.24805 0.273885,-0.24805 0.206705,0 0.315226,0.11886 0.103353,0.13436 0.211873,0.26872 -0.09819,0.0879 -0.253214,0.33073 l 0.0052,0.0103 q 0.124024,-0.0103 0.382406,-0.10335 0.237712,-0.093 0.387573,-0.093 0.377238,0 0.594279,0.10852 0.02584,0.0155 0.170532,0.12402 0.129191,0.10336 0.149862,0.10336 0.03617,0 0.232544,-0.0775 0.217041,-0.0827 0.268717,-0.093 0.07752,-0.005 0.227377,-0.0207 -0.05684,-0.16536 -0.273885,-0.43408 -0.03101,-0.0207 -0.294556,-0.0672 -0.08268,-0.29455 -0.08268,-0.26355 0,-0.42374 0.454752,-0.42374 0.113688,0 0.3514,0.24288 0.217041,0.22737 0.268717,0.35656 0.201539,0.5116 0.206706,0.863 0.165365,0.10335 0.330729,0.20671 0.165365,0.0982 0.289388,0.28422 0.335897,-0.093 0.392741,-0.25322 0.0052,-0.0517 0.03101,-0.15503 0.02067,-0.0465 0.113688,-0.11369 0.09302,-0.0723 0.139527,-0.0723 0.134358,0 0.248046,0.0672 0.222209,0.12919 0.222209,0.24804 0,0.1447 -0.160197,0.36174 -0.155029,0.21187 -0.294555,0.28422 -0.06201,0.0207 -0.1757,0.0724 0.330729,0.29455 0.702799,0.96118 0.08268,0.22737 0.26355,0.54777 0.118856,0.11369 0.423747,0.17053 0.206705,0.0103 0.625284,0.0413 0.0155,-0.0775 0.05684,-0.22738 0.08785,-0.2067 0.222208,-0.2067 0.155029,0 0.377238,0.12919 0.180868,0.10335 0.180868,0.40308 z m -5.937622,-2.6045 q -0.196371,-0.2067 -0.325562,-0.2067 -0.103353,0 -0.361735,0.12402 -0.279053,0.12919 -0.279053,0.21187 0,0.15503 0.217042,0.15503 0.37207,0 0.625284,-0.14469 0.07752,-0.0465 0.124024,-0.13953 z m -1.35909,0.0465 v -0.093 q -0.04134,-0.062 -0.08785,-0.062 -0.118856,0 -0.428915,0.31523 -0.310058,0.31523 -0.310058,0.43408 0,0.0982 0.09819,0.0982 0.02067,0 0.155029,-0.1602 0.15503,-0.18604 0.160197,-0.1912 0.222209,-0.22221 0.413412,-0.34107 z m 5.033284,3.10059 q 0,-0.47026 -0.08785,-0.85266 -0.08268,-0.38758 -0.516764,-0.98186 -0.413412,-0.55293 -0.775147,-0.82165 -0.449585,-0.33073 -0.883667,-0.5116 -0.160197,-0.0672 -0.263549,-0.0672 -0.237712,0 -0.454753,0.12403 -0.160197,0.093 -0.273885,0.28938 -0.09819,0.1757 -0.191203,0.35657 -0.315226,0.52193 -1.25057,1.34876 -0.206705,0.18086 -0.387573,0.28939 -0.180867,0.10335 -0.361735,0.19637 -0.19637,0.11368 -0.289388,0.28938 -0.124023,0.23772 -0.124023,0.43925 0,0.10336 0.351399,0.73381 0.08785,0.16536 0.289388,0.47025 0.506429,0.62012 1.353923,1.03353 0.113688,0.0724 0.356567,0.18604 0.289388,0.10335 0.873332,0.10335 0.966349,0 1.746663,-0.34623 0.113689,-0.0465 0.320394,-0.1757 0.284221,-0.24288 0.444418,-0.98702 0.124023,-0.57878 0.124023,-1.11621 z m -5.482869,-1.79317 q 0,-0.22221 -0.160197,-0.22221 -0.07752,0 -0.196371,0.24804 -0.118855,0.24805 -0.118855,0.34107 0,0.3514 0.217041,0.3514 0.08785,0 0.180867,-0.31523 0.07752,-0.26872 0.07752,-0.40307 z m 4.718058,0.73897 q 0,0.32556 -0.191203,0.53227 -0.186035,0.2067 -0.506429,0.2067 -0.237712,0 -0.5271,-0.49092 -0.268717,-0.45476 -0.268717,-0.71831 0,-0.11368 0.02584,-0.1757 0.02067,-0.0465 0.1757,-0.1912 0.155029,-0.14986 0.217041,-0.18087 0.06718,-0.031 0.273885,-0.031 0.155029,0 0.26355,0.0362 0.248047,0.0827 0.403076,0.42375 0.134359,0.28939 0.134359,0.58911 z m 0.1757,2.15491 q 0,0.41341 -0.04651,0.49092 -0.165365,0.1757 -0.330729,0.34623 h -0.511597 q -0.02067,0 -0.144694,-0.0723 -0.656291,-0.38758 -0.656291,-1.00253 0,-0.0672 0.08268,-0.22737 0.08785,-0.1602 0.144694,-0.20671 0.191202,-0.16536 0.361735,-0.16536 0.294555,0 0.682129,0.27388 0.418579,0.28939 0.418579,0.56328 z M 91.933574,118.517 q 0,0.24288 -0.387574,0.64595 -0.387573,0.39791 -0.630452,0.39791 -0.217041,0 -0.366903,-0.18603 -0.144694,-0.17054 -0.144694,-0.39274 0,-0.3204 0.320394,-0.63562 0.320394,-0.3204 0.640788,-0.3204 0.217041,0 0.392741,0.13953 0.1757,0.13952 0.1757,0.3514 z m -0.134359,2.39262 q 0,0.23254 -0.165365,0.43925 -0.144694,0.18086 -0.552938,0.18086 -0.387573,0 -0.682128,-0.15503 -0.372071,-0.18603 -0.372071,-0.53743 0,-0.34106 0.08268,-0.44442 0.149861,-0.16019 0.294555,-0.32039 0.07235,-0.0103 0.118856,-0.0103 0.341064,0 0.785482,0.25839 0.490926,0.28422 0.490926,0.58911 z" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/html/logo/debbugs_logo_orig.svg b/html/logo/debbugs_logo_orig.svg
new file mode 100644 (file)
index 0000000..4b34e9e
--- /dev/null
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:ns2="http://ns.adobe.com/AdobeIllustrator/10.0/"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="40mm"
+   height="40mm"
+   viewBox="0 0 40 40.000001"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="debbugs_logo.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="63.189674"
+     inkscape:cy="-194.55359"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1076"
+     inkscape:window-height="1869"
+     inkscape:window-x="1050"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-63.88401,-92.795649)">
+    <g
+       id="g3789"
+       transform="translate(3.1750001,-0.52916667)">
+      <g
+         transform="matrix(0.26458333,0,0,0.26458333,63.905735,94.420958)"
+         id="g97"
+         style="overflow:visible">
+        <g
+           id="Layer_1"
+           ns2:layer="yes"
+           ns2:dimmedPercent="50"
+           ns2:rgbTrio="#4F008000FFFF">
+          <g
+             id="g74">
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 51.986,57.297 c -1.797,0.025 0.34,0.926 2.686,1.287 0.648,-0.506 1.236,-1.018 1.76,-1.516 -1.461,0.358 -2.948,0.366 -4.446,0.229"
+               id="path50" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 61.631,54.893 c 1.07,-1.477 1.85,-3.094 2.125,-4.766 -0.24,1.192 -0.887,2.221 -1.496,3.307 -3.359,2.115 -0.316,-1.256 -0.002,-2.537 -3.612,4.546 -0.496,2.726 -0.627,3.996"
+               id="path52" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 65.191,45.629 c 0.217,-3.236 -0.637,-2.213 -0.924,-0.978 0.335,0.174 0.6,2.281 0.924,0.978"
+               id="path54" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 45.172,1.399 c 0.959,0.172 2.072,0.304 1.916,0.533 1.049,-0.23 1.287,-0.442 -1.916,-0.533"
+               id="path56" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="M 47.088,1.932 46.41,2.072 47.041,2.016 47.088,1.932"
+               id="path58" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 76.992,46.856 c 0.107,2.906 -0.85,4.316 -1.713,6.812 l -1.553,0.776 c -1.271,2.468 0.123,1.567 -0.787,3.53 -1.984,1.764 -6.021,5.52 -7.313,5.863 -0.943,-0.021 0.639,-1.113 0.846,-1.541 -2.656,1.824 -2.131,2.738 -6.193,3.846 L 60.16,65.878 C 50.142,70.591 36.226,61.251 36.409,48.507 c -0.107,0.809 -0.304,0.607 -0.526,0.934 -0.517,-6.557 3.028,-13.143 9.007,-15.832 5.848,-2.895 12.704,-1.707 16.893,2.197 -2.301,-3.014 -6.881,-6.209 -12.309,-5.91 -5.317,0.084 -10.291,3.463 -11.951,7.131 -2.724,1.715 -3.04,6.611 -4.227,7.507 -1.597,11.737 3.004,16.808 10.787,22.773 1.225,0.826 0.345,0.951 0.511,1.58 -2.586,-1.211 -4.954,-3.039 -6.901,-5.277 1.033,1.512 2.148,2.982 3.589,4.137 -2.438,-0.826 -5.695,-5.908 -6.646,-6.115 4.203,7.525 17.052,13.197 23.78,10.383 -3.113,0.115 -7.068,0.064 -10.566,-1.229 -1.469,-0.756 -3.467,-2.322 -3.11,-2.615 9.182,3.43 18.667,2.598 26.612,-3.771 2.021,-1.574 4.229,-4.252 4.867,-4.289 -0.961,1.445 0.164,0.695 -0.574,1.971 2.014,-3.248 -0.875,-1.322 2.082,-5.609 l 1.092,1.504 c -0.406,-2.696 3.348,-5.97 2.967,-10.234 0.861,-1.304 0.961,1.403 0.047,4.403 1.268,-3.328 0.334,-3.863 0.66,-6.609 0.352,0.923 0.814,1.904 1.051,2.878 -0.826,-3.216 0.848,-5.416 1.262,-7.285 -0.408,-0.181 -1.275,1.422 -1.473,-2.377 0.029,-1.65 0.459,-0.865 0.625,-1.271 -0.324,-0.186 -1.174,-1.451 -1.691,-3.877 0.375,-0.57 1.002,1.478 1.512,1.562 -0.328,-1.929 -0.893,-3.4 -0.916,-4.88 -1.49,-3.114 -0.527,0.415 -1.736,-1.337 -1.586,-4.947 1.316,-1.148 1.512,-3.396 2.404,3.483 3.775,8.881 4.404,11.117 -0.48,-2.726 -1.256,-5.367 -2.203,-7.922 0.73,0.307 -1.176,-5.609 0.949,-1.691 C 83.519,18.706 76.074,10.902 69.225,7.24 70.063,8.007 71.121,8.97 70.741,9.121 67.335,7.093 67.934,6.935 67.446,6.078 64.671,4.949 64.489,6.169 62.651,6.08 57.421,3.306 56.413,3.601 51.6,1.863 l 0.219,1.023 c -3.465,-1.154 -4.037,0.438 -7.782,0.004 -0.228,-0.178 1.2,-0.644 2.375,-0.815 -3.35,0.442 -3.193,-0.66 -6.471,0.122 0.808,-0.567 1.662,-0.942 2.524,-1.424 -2.732,0.166 -6.522,1.59 -5.352,0.295 -4.456,1.988 -12.37,4.779 -16.811,8.943 l -0.14,-0.933 c -2.035,2.443 -8.874,7.296 -9.419,10.46 l -0.544,0.127 c -1.059,1.793 -1.744,3.825 -2.584,5.67 -1.385,2.36 -2.03,0.908 -1.833,1.278 -2.724,5.523 -4.077,10.164 -5.246,13.97 0.833,1.245 0.02,7.495 0.335,12.497 -1.368,24.704 17.338,48.69 37.785,54.228 2.997,1.072 7.454,1.031 11.245,1.141 -4.473,-1.279 -5.051,-0.678 -9.408,-2.197 -3.143,-1.48 -3.832,-3.17 -6.058,-5.102 l 0.881,1.557 c -4.366,-1.545 -2.539,-1.912 -6.091,-3.037 l 0.941,-1.229 C 28.751,98.334 26.418,96.056 25.78,94.795 l -1.548,0.061 c -1.86,-2.295 -2.851,-3.949 -2.779,-5.23 l -0.5,0.891 c -0.567,-0.973 -6.843,-8.607 -3.587,-6.83 -0.605,-0.553 -1.409,-0.9 -2.281,-2.484 l 0.663,-0.758 c -1.567,-2.016 -2.884,-4.6 -2.784,-5.461 0.836,1.129 1.416,1.34 1.99,1.533 -3.957,-9.818 -4.179,-0.541 -7.176,-9.994 L 8.412,66.472 C 7.926,65.74 7.631,64.945 7.24,64.165 l 0.276,-2.75 C 4.667,58.121 6.719,47.409 7.13,41.534 7.415,39.145 9.508,36.602 11.1,32.614 l -0.97,-0.167 c 1.854,-3.234 10.586,-12.988 14.63,-12.486 1.959,-2.461 -0.389,-0.009 -0.772,-0.629 4.303,-4.453 5.656,-3.146 8.56,-3.947 3.132,-1.859 -2.688,0.725 -1.203,-0.709 5.414,-1.383 3.837,-3.144 10.9,-3.846 0.745,0.424 -1.729,0.655 -2.35,1.205 4.511,-2.207 14.275,-1.705 20.617,1.225 7.359,3.439 15.627,13.605 15.953,23.17 l 0.371,0.1 c -0.188,3.802 0.582,8.199 -0.752,12.238 l 0.908,-1.912"
+               id="path60" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 32.372,59.764 -0.252,1.26 c 1.181,1.604 2.118,3.342 3.626,4.596 -1.085,-2.118 -1.891,-2.993 -3.374,-5.856"
+               id="path62" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 35.164,59.654 c -0.625,-0.691 -0.995,-1.523 -1.409,-2.352 0.396,1.457 1.207,2.709 1.962,3.982 l -0.553,-1.63"
+               id="path64" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 84.568,48.916 -0.264,0.662 c -0.484,3.438 -1.529,6.84 -3.131,9.994 1.77,-3.328 2.915,-6.968 3.395,-10.656"
+               id="path66" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="M 45.527,0.537 C 46.742,0.092 48.514,0.293 49.803,0 48.123,0.141 46.451,0.225 44.8,0.438 l 0.727,0.099"
+               id="path68" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="m 2.872,23.219 c 0.28,2.592 -1.95,3.598 0.494,1.889 1.31,-2.951 -0.512,-0.815 -0.494,-1.889"
+               id="path70" />
+            <path
+               style="fill:#a80030"
+               inkscape:connector-curvature="0"
+               ns2:knockout="Off"
+               d="M 0,35.215 C 0.563,33.487 0.665,32.449 0.88,31.449 -0.676,33.438 0.164,33.862 0,35.215"
+               id="path72" />
+          </g>
+        </g>
+      </g>
+      <text
+         id="text101"
+         y="131.06845"
+         x="65.76786"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;line-height:125%;font-family:Prociono;-inkscape-font-specification:Prociono;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Prociono;-inkscape-font-specification:Prociono;stroke-width:0.26458332px"
+           y="131.06845"
+           x="65.76786"
+           id="tspan99"
+           sodipodi:role="line">Debbugs</tspan></text>
+      <text
+         id="text3723-71"
+         y="109.51892"
+         x="97.447449"
+         style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         xml:space="preserve"><tspan
+           style="text-align:end;text-anchor:end;stroke-width:0.26458332px"
+           y="109.51892"
+           x="97.447449"
+           id="tspan3721-5"
+           sodipodi:role="line">🐜</tspan><tspan
+           id="tspan3767"
+           style="text-align:end;text-anchor:end;stroke-width:0.26458332px"
+           y="123.05936"
+           x="97.447449"
+           sodipodi:role="line">🐛🐞</tspan></text>
+    </g>
+  </g>
+</svg>
index 3eba1fce2ca4b3a5baa33f924035fbfe9df24e18..3da8f983c4a13ea773fe808a6f8136018b918a9d 100755 (executable)
@@ -34,6 +34,7 @@ use Debbugs::Control qw(append_action_to_log);
 use Debbugs::Control::Service qw(valid_control control_line);
 use Debbugs::Recipients qw(determine_recipients);
 use Encode qw(encode_utf8 decode);
+use List::AllUtils qw(first uniqnum);
 
 =head1 NAME
 
@@ -312,7 +313,7 @@ if (defined $tryref) {
         $ref= $tryref;
     } else {
         &sendmessage(create_mime_message(
-          [From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+          [From          =>  qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
           To            => $replyto,
           Subject       => "Unknown problem report $gBug#$tryref ($subject)",
           'Message-ID'  => "<handler.x.$nn.unknown\@$gEmailDomain>",
@@ -403,7 +404,7 @@ if ($codeletter eq 'D' || $codeletter eq 'F')
     }
     if ($ref<0) {
        &sendmessage(create_mime_message(
-          [From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+          [From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
           To            => $replyto,
           Subject       => "Message with no $gBug number ignored by $receivedat ($subject)",
           'Message-ID'  => "<handler.x.$nn.warnignore\@$gEmailDomain>",
@@ -495,7 +496,7 @@ if ($codeletter eq 'D' || $codeletter eq 'F')
            &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded.");
             &sendmessage(create_mime_message(
             [@common_headers,
-             From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+             From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
               To            => "$replyto",
               Subject       => "$gBug#$ref: marked as forwarded ($data->{subject})",
               "Message-ID"  => "<header.$ref.$nn.ackfwdd\@$gEmailDomain>",
@@ -520,7 +521,7 @@ if ($codeletter eq 'D' || $codeletter eq 'F')
            &htmllog("Reply","sent",$replyto,"You have taken responsibility.");
             &sendmessage(create_mime_message(
             [@common_headers,
-             From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+             From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
               To            => $replyto,
               Subject       => "$gBug#$ref: marked as done ($data->{subject})",
               "Message-ID"  => "<handler.$ref.$nn.ackdone\@$gEmailDomain>",
@@ -546,7 +547,7 @@ if ($codeletter eq 'D' || $codeletter eq 'F')
                "$gBug acknowledged by developer.");
             &sendmessage(create_mime_message(
             [@common_headers,
-             From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+             From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
               To            => "$data->{originator}",
               Subject       => "$gBug#$ref closed by $markedby ($header{'subject'})",
               "Message-ID"  => "<handler.$ref.$nn.notifdone\@$gEmailDomain>",
@@ -577,7 +578,7 @@ if ($ref<0) { # new bug report
     if ($codeletter eq 'U') { # -submitter
        &sendmessage(create_mime_message(
           [@common_headers,
-          From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+          From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
           To            => $replyto,
           Subject       => "Message with no $gBug number cannot be sent to submitter! ($subject)",
           'Message-ID'  => "<handler.x.$nn.nonumnosub\@$gEmailDomain>",
@@ -617,7 +618,7 @@ if ($ref<0) { # new bug report
                                        );
         &sendmessage(create_mime_message(
                        [@common_headers,
-                       From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+                       From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
                         To            => $replyto,
                         Subject       => "Message with no Package: tag cannot be processed! ($subject)",
                         "Message-ID"  => "<handler.x.$nn.nonumnosub\@$gEmailDomain>",
@@ -989,7 +990,7 @@ if (not exists $header{'x-debbugs-no-ack'} and
                                     );
      &sendmessage(create_mime_message(
                       [@common_headers,
-                       From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+                       From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
                        To            => $replyto,
                        Subject       => $t_h{subject},
                        "Message-ID"  => $t_h{messageid},
@@ -1090,7 +1091,7 @@ if (@control_bits) {
     my $error_text = $errors > 0 ? " (with $errors error" . ($errors > 1 ? "s" : "") . ")" : "";
     my $reply =
        create_mime_message(['X-Loop'      => $gMaintainerEmail,
-                            From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+                            From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
                             To            => $replyto,
                             @maintccs ? (Cc => join(', ',@maintccs)):(),
                             Subject       => "Processed${error_text}: $header{subject}",
@@ -1273,20 +1274,15 @@ sub fill_template{
      my $variables = {config => \%config,
                      defined($ref)?(ref    => $ref):(),
                      defined($data)?(data  => $data):(),
-                     refs => [map {exists $clonebugs{$_}?$clonebugs{$_}:$_} keys %bug_affected],
+                     refs => [sort
+                              uniqnum(defined($ref)?($ref):(),
+                                      map {exists $clonebugs{$_}?$clonebugs{$_}:$_}
+                                      keys %bug_affected)],
                      %{$extra_var},
                     };
-     my $hole_var = {'&bugurl' =>
-                    sub{"$_[0]: ".
-                             $config{cgi_domain}.'/'.
-                                  Debbugs::CGI::bug_links(bug=>$_[0],
-                                                          links_only => 1,
-                                                         );
-                   }
-                   };
      return fill_in_template(template => $template,
                             variables => $variables,
-                            hole_var  => $hole_var,
+                            output_type => 'text',
                            );
 }
 
index c62e3d59e7c632d1457dbf26fd4dce8831ddd146..7e4c2054bcf618b4ec4eb204dbc01d300183d203 100755 (executable)
@@ -39,7 +39,7 @@ use Debbugs::Text qw(:templates);
 
 use Scalar::Util qw(looks_like_number);
 
-use List::AllUtils qw(first);
+use List::AllUtils qw(first uniqnum);
 
 use Mail::RFC822::Address;
 use Encode qw(decode encode);
@@ -518,7 +518,7 @@ eval{
     $temp_transcript = decode("utf8",$temp_transcript,Encode::FB_CROAK);
 };
 my $reply =
-    create_mime_message([From          => "$gMaintainerEmail ($gProject $gBug Tracking System)",
+    create_mime_message([From          => qq("$gProject $gBug Tracking System" <$gMaintainerEmail>),
                         To            => $replyto,
                         @maintccs ? (Cc => join(', ',@maintccs)):(),
                         Subject       => "Processed${error_text}: $header{subject}",
@@ -573,20 +573,15 @@ sub fill_template{
      my $variables = {config => \%config,
                      defined($ref)?(ref    => $ref):(),
                      defined($data)?(data  => $data):(),
-                     refs => [map {exists $clonebugs{$_}?$clonebugs{$_}:$_} keys %bug_affected],
+                     refs => [sort
+                              uniqnum(defined($ref)?($ref):(),
+                                      map {exists $clonebugs{$_}?$clonebugs{$_}:$_}
+                                      keys %bug_affected)],
                      %{$extra_var},
                     };
-     my $hole_var = {'&bugurl' =>
-                    sub{"$_[0]: ".
-                             $config{cgi_domain}.'/'.
-                                  Debbugs::CGI::bug_links(bug=>$_[0],
-                                                          links_only => 1,
-                                                         );
-                   }
-                   };
      return fill_in_template(template => $template,
                             variables => $variables,
-                            hole_var  => $hole_var,
+                            output_type => 'text',
                            );
 }
 
@@ -884,7 +879,7 @@ sub sendtxthelpraw {
     close(D);
     print {$transcript} "Sending $description in separate message.\n";
     &sendmailmessage(<<END.$doc,$replyto);
-From: $gMaintainerEmail ($gProject $gBug Tracking System)
+From: "$gProject $gBug Tracking System" <$gMaintainerEmail>
 To: $replyto
 Subject: $gProject $gBug help: $description
 References: $header{'message-id'}
@@ -912,7 +907,7 @@ sub sendlynxdocraw {
     } else {
         print {$transcript} "Sending $description.\n";
         &sendmailmessage(<<END.$doc,$replyto);
-From: $gMaintainerEmail ($gProject $gBug Tracking System)
+From: "$gProject $gBug Tracking System" <$gMaintainerEmail>
 To: $replyto
 Subject: $gProject $gBugs information: $description
 References: $header{'message-id'}
@@ -949,7 +944,7 @@ sub sendinfo {
     }
     print {$transcript} "Sending $description.\n";
     &sendmailmessage(<<END.$doc,$replyto);
-From: $gMaintainerEmail ($gProject $gBug Tracking System)
+From: "$gProject $gBug Tracking System" <$gMaintainerEmail>
 To: $replyto
 Subject: $gProject $gBugs information: $description
 References: $header{'message-id'}
index c654359028add1255c2fed520148b1cc6af07566..a20b3979364b9d16a4fdcd5c3d35eb9fbd74dbb5 100644 (file)
@@ -1,6 +1,6 @@
 # -*- mode: cperl;-*-
 
-use Test::More tests => 35;
+use Test::More;
 
 use warnings;
 use strict;
@@ -132,7 +132,8 @@ my @control_commands =
                      },
      );
 
-test_control_commands(@control_commands);
+test_control_commands(\%config,
+                     @control_commands);
 
 send_message(to => 'control@bugs.something',
             headers => [To   => 'control@bugs.something',
@@ -160,22 +161,19 @@ found -5 1.2-5
 fixed -5 1.2-6
 thanks
 EOF
-       ;
-       $SD_SIZE =
-           num_messages_sent($SD_SIZE,1,
-                             $sendmail_dir,
-                             'control@bugs.something messages appear to have been sent out properly');
 
-
-test_control_commands(forcemerge   => {command => 'forcemerge',
-                                      value   => '1 2',
+test_control_commands(\%config,
+                     forcemerge   => {command => 'forcemerge',
+                                      value   => "2 3\nseverity 2 minor",
                                       status_key => 'mergedwith',
-                                      status_value => '2',
+                                      status_value => '3',
+                                      bug => 2,
                                      },
                      unmerge      => {command => 'unmerge',
-                                      value   => '1',
+                                      value   => '2',
                                       status_key => 'mergedwith',
                                       status_value => '',
+                                      bug => 2,
                                      },
                      forcemerge   => {command => 'forcemerge',
                                       value   => '1 2 5',
@@ -195,43 +193,4 @@ test_control_commands(forcemerge   => {command => 'forcemerge',
                                      },
                     );
 
-
-sub test_control_commands{
-    my @commands = @_;
-
-    while (my ($command,$control_command) = splice(@commands,0,2)) {
-       # just check to see that control doesn't explode
-       $control_command->{value} = " $control_command->{value}" if length $control_command->{value}
-           and $control_command->{value} !~ /^\s/;
-       send_message(to => 'control@bugs.something',
-                    headers => [To   => 'control@bugs.something',
-                                From => 'foo@bugs.something',
-                                Subject => "Munging a bug with $command",
-                               ],
-                    body => <<EOF) or fail 'message to control@bugs.something failed';
-debug 10
-$control_command->{command} $control_command->{value}
-thanks
-EOF
-       ;
-       $SD_SIZE =
-           num_messages_sent($SD_SIZE,1,
-                             $sendmail_dir,
-                             'control@bugs.something messages appear to have been sent out properly');
-       # now we need to check to make sure the control message was processed without errors
-       ok(system('sh','-c','find '.$sendmail_dir.q( -type f | xargs grep -q "Subject: Processed: Munging a bug with $command")) == 0,
-          'control@bugs.something'. "$command message was parsed without errors");
-       # now we need to check to make sure that the control message actually did anything
-       my $status;
-       $status = read_bug(exists $control_command->{bug}?(bug => $control_command->{bug}):(bug=>1),
-                          exists $control_command->{location}?(location => $control_command->{location}):(),
-                         );
-       is_deeply($status->{$control_command->{status_key}},
-                 $control_command->{status_value},
-                 "bug " .
-                 (exists $control_command->{bug}?$control_command->{bug}:1).
-                 " $command"
-                )
-           or fail(Dumper($status));
-    }
-}
+done_testing();
index fcc0dc04b31bb8f6e9d8e5a21ffcefa712804815..a23fdd4d7a0f56dd4e10df34b79ba1ffbb052dbf 100644 (file)
@@ -43,6 +43,7 @@ BEGIN{
      @EXPORT = ();
      %EXPORT_TAGS = (configuration => [qw(dirsize create_debbugs_configuration send_message)],
                     mail          => [qw(num_messages_sent)],
+                    control       => [qw(test_control_commands)],
                     database => [qw(create_postgresql_database update_postgresql_database)]
                    );
      @EXPORT_OK = ();
@@ -207,6 +208,80 @@ sub send_message{
      }
 }
 
+=item test_control_commands
+
+ test_control_commands(\%config,
+                       forcemerge => {command => 'forcemerge',
+                                      value   => '1 2',
+                                      status_key => 'mergedwith',
+                                      status_value => '2',
+                                      expect_error => 0,
+                                     });
+
+Test a set of control commands to see if they will fail or not. Takes
+SCALAR/HASHREF pairs, where the scalar should be unique, and the HASHREF
+contains the following keys:
+
+=over
+
+=item command -- control command to issue
+
+=item value -- value to pass to control command
+
+=item status_key -- bug status key to check
+
+=item status_value -- value of status key
+
+=item expect_error -- whether to expect the control command to error or not
+
+=back
+
+=cut
+
+sub test_control_commands {
+    my ($config,@commands) = @_;
+
+    # now we need to check to make sure that the control message actually did anything
+    # This is an eval because $ENV{DEBBUGS_CONFIG_FILE} isn't set at BEGIN{} time
+    eval "use Debbugs::Status qw(read_bug writebug);";
+    while (my ($command,$control_command) = splice(@commands,0,2)) {
+       # just check to see that control doesn't explode
+       $control_command->{value} = " $control_command->{value}" if length $control_command->{value}
+           and $control_command->{value} !~ /^\s/;
+       send_message(to => 'control@bugs.something',
+                    headers => [To   => 'control@bugs.something',
+                                From => 'foo@bugs.something',
+                                Subject => "Munging a bug with $command",
+                               ],
+                    body => <<EOF) or fail 'message to control@bugs.something failed';
+debug 10
+$control_command->{command} $control_command->{value}
+thanks
+EOF
+       ;
+       # now we need to check to make sure the control message was processed without errors
+       if (not ($control_command->{expect_error} // 0)) {
+           ok(system('sh','-c','find '.$config->{sendmail_dir}.
+                     q( -type f | xargs grep -q "Subject: Processed: Munging a bug with $command")
+                    ) == 0,
+              'control@bugs.something'. "$command message was parsed without errors");
+       }
+       # now we need to check to make sure that the control message actually did anything
+       my $status;
+       $status = read_bug(exists $control_command->{bug}?(bug => $control_command->{bug}):(bug=>1),
+                          exists $control_command->{location}?(location => $control_command->{location}):(),
+                         );
+       is_deeply($status->{$control_command->{status_key}},
+                 $control_command->{status_value},
+                 "bug " .
+                 (exists $control_command->{bug}?$control_command->{bug}:1).
+                 " $command"
+                )
+           or fail(Data::Dumper->Dump([$status],[qw(status)]));
+    }
+}
+
+
 {
      package DebbugsTest::HTTPServer;
      use base qw(HTTP::Server::Simple::CGI HTTP::Server::Simple::CGI::Environment);
diff --git a/templates/en_US/cgi/bugreport.tmpl b/templates/en_US/cgi/bugreport.tmpl
deleted file mode 100644 (file)
index 2f0ec04..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-{include(q(html/pre_title))}#{$bug_num} - {html_escape($status{subject})} - {html_escape($config{project})} {html_escape($config{bug})} report logs{include(q(html/post_title.tmpl))}
-<script type="text/javascript">
-<!--
-function toggle_infmessages()
-\{
-        allDivs=document.getElementsByTagName("div");
-        for (var i = 0 ; i < allDivs.length ; i++ )
-        \{
-                if (allDivs[i].className == "infmessage")
-                \{
-                        allDivs[i].style.display=(allDivs[i].style.display == 'none' | allDivs[i].style.display == '') ? 'block' : 'none';
-                \}
-        \}
-\}
--->
-</script>
-</head>
-<body>
-<h1>{html_escape($config{project})} {html_escape($config{bug})} report logs - 
-<a href="mailto:{$bug_num}@{html_escape($config{email_domain})}">#{$bug_num}</a><br>
-{html_escape($status{subject})}</h1>
-<div class="versiongraph">{$version_graph}</div>
-{include(q(cgi/bugreport_pkginfo))}
-{include(q(cgi/bugreport_buginfo))}
-{ my $output = '';
-  if (looks_like_number($msg)) {
-     $output .= sprintf qq(<p><a href="%s">Full log</a></p>),html_escape(bug_links(bug=>$bug_num,links_only=>1));
-  }
-  else {
-     if (not $status{archived}) {
-       $output .=  qq(<p><a href="mailto:$bug_num\@$config{email_domain}">Reply</a> ).
-          qq(or <a href="mailto:$bug_num-subscribe\@$config{email_domain}">subscribe</a> ).
-              qq(to this bug.</p>\n);
-     }
-     $output .=  qq(<p><a href="javascript:toggle_infmessages();">Toggle useless messages</a></p>);
-     $output .= sprintf qq(<div class="msgreceived"><p>View this report as an <a href="%s">mbox folder</a>, ).
-         qq(<a href="%s">status mbox</a>, <a href="%s">maintainer mbox</a></p></div>\n),
-              html_escape(bug_links(bug=>$bug_num, links_only=>1,options=>{mbox=>'yes'})),
-                   html_escape(bug_links(bug=>$bug_num, links_only=>1,options=>{mbox=>'yes',mboxstatus=>'yes'})),
-                        html_escape(bug_links(bug=>$bug_num, links_only=>1,options=>{mbox=>'yes',mboxmaint=>'yes'}));
-  }
-  $output;
-}
-{$log}
-<hr>
-<p class="msgreceived">Send a report that <a href="{$config{cgi_domain}}/bugspam.cgi?bug={$bug_num}">this bug log contains spam</a>.</p>
-<hr>
-{include(q(html/html_tail))}
-</body>
-</html>
diff --git a/templates/en_US/cgi/bugreport.tx b/templates/en_US/cgi/bugreport.tx
new file mode 100644 (file)
index 0000000..ce72b32
--- /dev/null
@@ -0,0 +1,52 @@
+<: include "html/pre_title.tx" :>#<: $bug_num :> - <: $status.subject :> - <: $config.project :> <: $config.bug :> report logs<: include "html/post_title.tx" :>
+<link rel="canonical" href="<: bug_links(bug=>$bug_num,links_only=>1) :>">
+<script type="text/javascript">
+<!--
+function toggle_infmessages()
+{
+        allDivs=document.getElementsByTagName("div");
+        for (var i = 0 ; i < allDivs.length ; i++ )
+       {
+                if (allDivs[i].className == "infmessage")
+                {
+                        allDivs[i].style.display=(allDivs[i].style.display == 'none' | allDivs[i].style.display == '') ? 'block' : 'none';
+                }
+       }
+}
+-->
+</script>
+</head>
+<body>
+    <div class="debbugs_install"><: $config.project :> <: $config.bug :> report logs</div>
+    <h1 class="bug_header"><a class="bug_email" href="mailto:<: $bug_num :>@<: $config.email_domain :>">#<: $bug_num :></a>
+        <span class="bug_subject"><: $status.subject :></span>
+    </h1>
+<div class="versiongraph"><: raw($version_graph) :></div>
+<: include "cgi/bugreport_pkginfo.tx" :>
+<: include "cgi/bugreport_buginfo.tx" :>
+<div class="bugreport_operations">
+: if looks_like_number($msg) {
+    <span><a href="<: bug_links(bug => $bug_num, links_only => 1) :>">Full log</a></span>
+: } else {
+: if ! $status.archived {
+<span><a href="mailto:<: $bug_num :>@<: $config.email_domain :>">Reply</a>
+or <a href="mailto:<: $bug_num :>-subscribe@<: $config.email_domain :>">subscribe</a>
+to this <: $config.bug :>.</span>
+: }
+<span>View this <: $config.bug :> as an
+<a href="<: bug_links("bug",$bug_num,links_only=>1,options=>{mbox=>"yes"}) :>">mbox</a>,
+<a href="<: bug_links("bug",$bug_num,links_only=>1,options=>{mbox=>"yes",mboxstatus => "yes"}) :>">status mbox</a>, or
+<a href="<: bug_links("bug",$bug_num,links_only=>1,options=>{mbox=>"yes",mboxmaint => "yes"}) :>">maintainer mbox</a>
+</span>
+</div>
+: }
+<: raw($log) :>
+<script>
+ document.write("<span class=\"uselessmessages\"><a href=\"javascript:toggle_infmessages();\">Toggle useless messages</a></span>")
+</script>
+<hr>
+<p class="msgreceived">Send a report that <a href="<: $config.cgi_domain :>/bugspam.cgi?bug=<: $bug_num :>">this bug log contains spam</a>.</p>
+<hr>
+<: include "html/html_tail.tx" :>
+</body>
+</html>
diff --git a/templates/en_US/cgi/bugreport_buginfo.tmpl b/templates/en_US/cgi/bugreport_buginfo.tmpl
deleted file mode 100644 (file)
index 9b6c4fd..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<div class="buginfo">
-  <p>Reported by: {package_links(submitter=>$status{originator})}</p>
-  <p>Date: {$status{date_text}}</p>
-{ my $output = ''; 
-  if (defined $status{owner} and length $status{owner}) {
-     $output = q(<p>Owned by: ).package_links(owner=>$status{owner}).q(</p>);
-  }
-  $output;
-}
-<p>Severity: {my $output = $status{severity};
-              if (isstrongseverity($status{severity})) {
-                   $output = q(<em class="severity">).$status{severity}.q(</em>);
-              }
-              $output;
-             }</p>
-<p>{@{$status{tags_array}}?q(Tags: ).html_escape(join(q(, ),@{$status{tags_array}})):''}</p>
-{my $output = '';
- if (@{$status{mergedwith_array}}) {
-    $output .= q(<p>Merged with ).join(qq(,\n),bug_links(bug=>$status{mergedwith_array})).qq(</p>\n);
- }
- $output;
-}
-{my $output = '';
- if (@{$status{found_versions}}) {
-    $output .= q(<p>Found in );
-    $output .= (@{$status{found_versions}} == 1) ? 'version ' : 'versions ';
-    $output .= join(qq(, ),map {html_escape($_);} @{$status{found_versions}}).qq(</p>\n);
- }
- if (@{$status{fixed_versions}}) {
-    $output .= q(<p>Fixed in );
-    $output .= (@{$status{fixed_versions}} == 1) ? 'version ' : 'versions ';
-    $output .= join(qq(, ),map {html_escape($_);} @{$status{fixed_versions}}).qq(</p>\n);
- }
- $output;
-}
-{ my $output = '';
-  if (length($status{done})) {
-     $output .= q(<p><strong>Done:</strong> ).html_escape($status{done}).q(</p>)
-  }
-  $output;
-}
-{ my $output = '';
-  if (@{$status{blockedby_array}}) {
-     $output .= q(<p>Fix blocked by ).
-        join(q(, ),
-         map {bug_links(bug=>$_->{bug_num}).q(: ).html_escape($_->{subject})}
-         @{$status{blockedby_array}}).q(</p>)
-  }
-  if (@{$status{blocks_array}}) {
-     $output .= q(<p>Blocking fix for ).
-        join(q(, ),
-         map {bug_links(bug=>$_->{bug_num}).q(: ).html_escape($_->{subject})}
-         @{$status{blocks_array}}).q(</p>)
-  }
-  $output;
-}
-{ my $output = '';
-  if (exists $status{archived} and $status{archived}) {
-     $output .= q(<p>Bug is archived. No further changes may be made.<p>)
-  }
-  $output
-}{ my $output = '';
- if (length($status{forwarded})) {
-    $output = "<p>Forwarded to " . 
-              join(', ',
-                  map {maybelink($_)}
-                   split /\,\s+/,$status{forwarded}
-                 )."</p>\n";
- }
- $output;
-}{ my $output = '';
-  if (exists $status{summary} and defined $status{summary} and length $status{summary}) {
-     $output .= q(<p>Summary: ).html_escape($status{summary}).q(</p>);
-  }
-  if (exists $status{outlook} and defined $status{outlook} and length $status{outlook}) {
-     $output .= q(<p>Outlook: ).html_escape($status{outlook}).q(</p>);
-  }
-  $output;
-}</div>
diff --git a/templates/en_US/cgi/bugreport_buginfo.tx b/templates/en_US/cgi/bugreport_buginfo.tx
new file mode 100644 (file)
index 0000000..9067959
--- /dev/null
@@ -0,0 +1,89 @@
+<div class="buginfo">
+    <ul>
+        <li><span class="key">Reported by</span>
+            <span class="value"><: package_links(submitter=>$status.originator) :></span>
+        </li>
+        <li><span class="key">Date</span>
+            <span class="value"><: $status.date_text :></span>
+        </li>
+        : if defined($status.owner) && $status.owner.length() {
+        <li><span class="key">Owned by</span>
+            <span class="value"><: package_links("owner",$status.owner) :></span>
+        </li>
+        : }
+        <li><span class="key">Severity</span>
+            <span class="value">
+                <:- if $status.severity { :><em class="severity"><: } -:>
+                <:- $status.severity -:>
+                <:- if $status.severity { :></em><: } -:>
+            </span>
+        </li>
+        : if $status.tags_array {
+        <li><span class="key">Tags</span>
+            <span class="value"><: $status.tags_array.join(' ') :></span>
+        </li>
+        : }
+        : if $status.mergedwith_array.count > 0 {
+        <li><span class="key">Merged with</span>
+            <span class="value"><: bug_links(bug=>$status.mergedwith_array).join(",\n") :></span>
+        </li>
+        : }
+        : if $status.found_versions.count {
+        <li><span class="key">Found in
+            version<:- if $status.found_versions.count > 1 { -:>s<: } -:></span>
+            <span class="value"><: $status.found_versions.join(', ') :></span>
+        </li>
+        : }
+        : if $status.fixed_versions.count {
+        <li><span class="key">Fixed in 
+            version<: if $status.fixed_versions.count > 1 { :>s<: } :></span>
+            <span class="value"><: $status.fixed_versions.join(', ') :></span>
+        </li>
+        : }
+        <: if $status.done.length() { :>
+        <li><span class="key">Done</span>
+            <span class="value"><: $status.done :></span>
+        </li>
+        : }
+        : if $status.blockedby_array.count {
+        <li><span class="key">Fix blocked by</span>
+            <span class="value">
+                : for $status.blockedby_array -> $bug {
+                <: bug_links("bug",$bug.bug_num) :>: <: $bug.subject -:>
+                <:- if !$~bug.is_last { :>, <:  } else {  :>.<: } :>
+                : }
+            </span>
+        </li>
+        : }
+        : if $status.blocks_array.count {
+        <li><span class="key">Blocking fix for</span>
+            <span class="value" 
+                  : for $status.blocks_array -> $bug {
+                  <: bug_links("bug",$bug.bug_num) :>: <: $bug.subject -:>
+                  <:- if ! $~bug.is_last { :>, <:  } else {  :>.<: } :>
+                  : }
+            </span>
+        </li>
+        : }
+        : if $status.archived {
+        <li><span class="key">Bug is</span>
+            <span class="value">Archived</span>
+        </li>
+        : }
+        : if defined $status.forwarded and $status.forwarded.length() {
+        <li><span class="key">Forwarded to</span>
+            <span class="value"><: split($status.forwarded,',\s+').map(maybelink).join(', ') :></span>
+        </li>
+        : }
+        : if defined $status.summary and $status.summary.length() {
+        <li><span class="key">Summary</span>
+            <span class="value"><: $status.summary :></span>
+        </li>
+        : }
+        : if defined $status.outlook and $status.outlook.length() {
+        <li><span class="key">Outlook</span>
+            <span class="value"><: $status.outlook :></span>
+        </li>
+        : }
+    </ul>
+</div>
diff --git a/templates/en_US/cgi/bugreport_pkginfo.tmpl b/templates/en_US/cgi/bugreport_pkginfo.tmpl
deleted file mode 100644 (file)
index 777928e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<div class="pkginfo">
-  <p>{if (keys %package > 1) { q(Packages)} else {q(Package)}}:
-     {join(q(, ),package_links(package => [map {$_->{package}} grep {!$_->{is_source}} values %package],
-                               source  => [map {$_->{source} } grep { $_->{is_source}} values %package],
-                               class => q(submitter),
-                              )
-          )};
-{my $output ='';
- for my $package (values %package) {
-     $output .= q(Maintainer for ).package_links($package->{is_source}?(source=>$package->{source}):(package=>$package->{package})).qq( is ).
-                package_links(maintainer => $package->{maintainer}).qq(; );
-     if (exists $package->{source} and not $package->{is_source}) {
-       $output .= q(Source for ).package_links(package=>$package->{package}).qq( is ).
-                   package_links(source => $package->{source}).qq(. );
-     }
- }
- $output;
-}</p>
-{ my $output = '';
-  if (keys %affects) {
-      $output .= q(<p>Affects: ).
-          join(q(, ),
-               package_links(package => [map {$_->{package}} grep {!$_->{is_source}} values %affects],
-                             source  => [map {$_->{source} } grep { $_->{is_source}} values %affects],
-                             class => q(submitter),
-                            )
-              ).q(</p>);
-  }
-  $output;
-}
-</div>
diff --git a/templates/en_US/cgi/bugreport_pkginfo.tx b/templates/en_US/cgi/bugreport_pkginfo.tx
new file mode 100644 (file)
index 0000000..18d259a
--- /dev/null
@@ -0,0 +1,27 @@
+: macro link_to_package -> ($packages) {
+: for $packages.values() -> $pkg {
+: if $pkg.is_source {
+<:- package_links(source => $pkg.source,class=>"submitter"); -:>
+: } else {
+<:- package_links(package => $pkg.package,class=>"submitter"); -:>
+: }
+: if $~pkg.is_last {
+;
+: } else {
+,
+: } } }
+<div class="pkginfo">
+    <p>Package<: if ($package.keys.count > 1) {:>s<: } :>
+    <: link_to_package($package) :>
+: for $package.values() -> $pkg { 
+<p>Maintainer for <: package_links($pkg.is_source ? "source": "package",$pkg.is_source ? $pkg.source : $pkg.package ) :> is <: package_links(maintainer => $pkg.maintainer) :>;
+<: if defined($pkg.source) && not $pkg.is_source { :>
+Source for <: package_links(package => $pkg.package) :> is
+<: package_links(source => $pkg.source) :>.
+<: } :></p>
+: }
+: if $affects.keys.size > 0 {
+<p>Affects: <: link_to_package($affects) :>
+</p>
+: }
+</div>
diff --git a/templates/en_US/cgi/no_such_bug.tmpl b/templates/en_US/cgi/no_such_bug.tmpl
deleted file mode 100644 (file)
index bdbd67d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head><title>#{$bug_num} - {$config{project}} {$config{bug}} report logs</title></head>
-<body>
-<h1>{$config{project}} {$config{bug}} report logs - #{$bug_num}</h1>
-<p>There is no record of {$config{bug}} #{$bug_num}.
-Try the <a href="{$config{web_domain}}/">search page</a> instead.</p>
-{#include('html/html_tail')}
-</body></html>
diff --git a/templates/en_US/cgi/no_such_bug.tx b/templates/en_US/cgi/no_such_bug.tx
new file mode 100644 (file)
index 0000000..b929f85
--- /dev/null
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head><title>#<: $bug_num :> - <: $config.project :> <: $config.bug :> report logs</title></head>
+<body>
+<h1><: $config.project :> <: $config.bug :> report logs - #<: $bug_num :></h1>
+<p>There is no record of <: $config.bug :> #<: $bug_num:>.
+Try the <a href="<: $config.web_domain :>/">search page</a> instead.</p>
+<: include 'html/html_tail.tx' :>
+</body></html>
diff --git a/templates/en_US/cgi/pkgindex.tmpl b/templates/en_US/cgi/pkgindex.tmpl
deleted file mode 100644 (file)
index c645a60..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-{include(q(html/pre_title))}{html_escape($config{project})} {html_escape($config{bug})} report logs by {html_escape($tag)}{include(q(html/post_title.tmpl))}
-</head>
-<body>
-<h1>{html_escape($config{project})} {html_escape($config{bug})} report logs by {html_escape($tag)}</h1> 
-{$note}
-<form>
-<input type="hidden" name="skip" value="{html_escape($param{skip})}">
-<input type="hidden" name="max_results" value="{html_escape($param{max_results})}">
-<input type="hidden" name="indexon" value="{html_escape($param{indexon})}">
-<input type="hidden" name="repeatmerged" value="{html_escape($param{repeatmerged})}">
-<input type="hidden" name="archive" value="{html_escape($param{archive})}">
-<input type="hidden" name="sortby" value="{html_escape($param{sortby})}">
-{ my $output = '';
-if (defined $param{first}) {
-    $output .= qq(<input type="hidden" name="first" value=").html_escape($param{first}).qq(">\n);
-} else {
-    $output .= q(<p>);
-     if ($param{skip}> 0) {
-        $output .= q(<input type="submit" name="prev" value="Prev">);
-     }
-     if (keys %count > ($param{skip} + $param{max_results})) {
-         $output .= q(<input type="submit" name="next" value="Next">);
-     }
-     $output .= qq(</p>\n);
-}
-$output;
-}
-{ $result }
-<hr/>
-{include(q(html/html_tail))}
-</body>
-</html>
diff --git a/templates/en_US/cgi/pkgindex.tx b/templates/en_US/cgi/pkgindex.tx
new file mode 100644 (file)
index 0000000..875d7bc
--- /dev/null
@@ -0,0 +1,29 @@
+<: include "html/pre_title.tx":>.$config.project) .$config.bug report logs by <: $tag :><:include "html/post_title.tx":>
+</head>
+<body>
+    <h1>.$config.project .$config.bug report logs by .$tag</h1> 
+    .$note
+    <form>
+        <input type="hidden" name="skip" value=".$param.skip">
+        <input type="hidden" name="max_results" value=".$param.max_results">
+        <input type="hidden" name="indexon" value=".$param.indexon">
+        <input type="hidden" name="repeatmerged" value=".$param.repeatmerged">
+        <input type="hidden" name="archive" value=".$param.archive">
+        <input type="hidden" name="sortby" value=".$param.sortby">
+        : if (defined $param.first) {
+        <input type="hidden" name="first" value="<: $param.first :>">
+        : } else {
+        <p>
+            : if ($param.skip> 0) {
+               <input type="submit" name="prev" value="Prev">
+            : }
+            : if (keys %count > ($param.skip + $param.max_results)) {
+               <input type="submit" name="next" value="Next">
+            : }
+        </p>
+        : }
+        <: $result :>
+        <hr/>
+        <: include "html/html_tail.tx" :>
+</body>
+</html>
diff --git a/templates/en_US/cgi/pkgreport_javascript.tmpl b/templates/en_US/cgi/pkgreport_javascript.tmpl
deleted file mode 100644 (file)
index a786cbf..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-<script type="text/javascript">
-<!--
-toggle_extra_status_visible();
-function pagemain() \{
-       toggle(1);
-//     toggle(2);
-       enable(1);
-\}
-
-var visible_extra_status = 0;
-
-function toggle_extra_status_visible() \{
-  all_divs = document.getElementsByTagName("div");
-  for (var i = 0; i < all_divs.length; i++) \{
-      if (all_divs[i].className == "shortbugstatusextra") \{
-         if (all_divs[i].style.position == 'absolute' ) \{
-           all_divs[i].style.position = "static";
-           all_divs[i].style.display = "block";
-           all_divs[i].style.zIndex = 0;
-           all_divs[i].style.border = 0;
-           var subspans = all_divs[i].getElementsByTagName("span");
-           for (var j = 0; j < subspans.length; j++) \{
-               subspans[j].style.display = "inline";
-           \}
-         \}
-        else \{
-           all_divs[i].style.position = "absolute";
-           all_divs[i].style.display = "none"
-           all_divs[i].style.zIndex = 2;
-           all_divs[i].style.border = "#000 1px solid";
-           var subspans = all_divs[i].getElementsByTagName("span");
-           for (var j = 0; j < subspans.length; j++) \{
-               subspans[j].style.display = "block";
-           \}
-         \}
-      \}
-  \}
-\}
-
-function extra_status_visible(id) \{
-  var m = document.getElementById("status_mask");
-  if (visible_extra_status) \{
-     var t = document.getElementById("extra_status_"+visible_extra_status);
-     t.style.display = "none";
-     if (m) \{
-        m.style.display = "none";
-     \}
-     if (visible_extra_status == id) \{
-       visible_extra_status = 0;
-        return;
-     \}
-     visible_extra_status = 0;
-  \}
-  var e = document.getElementById("extra_status_"+id);
-  if (e) \{
-     e.style.display = "block";
-     visible_extra_status = id;
-     if (m) \{
-        m.onclick = function() \{ extra_status_visible(id); \};
-        m.style.display = "block";
-     \}
-  \}
-\}
-
-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);
-        if (a) \{
-             if (a.style.display == "none") \{
-                     a.style.display = "";
-             \} else \{
-                     a.style.display = "none";
-             \}
-        \}
-\}
-
-function enable(x) \{
-    for (var i = 1; ; i++) \{
-        var a = document.getElementById("b_" + x + "_" + i);
-        if (a == null) break;
-        var ischecked = a.checked;
-        for (var j = 1; ; j++) \{
-            var b = document.getElementById("b_" + x + "_"+ i + "_" + j);
-            if (b == null) break;
-            if (ischecked) \{
-                b.disabled = false;
-            \} else \{
-                b.disabled = true;
-            \}
-        \}
-    \}
-\}
--->
-</script>
diff --git a/templates/en_US/cgi/pkgreport_javascript.tx b/templates/en_US/cgi/pkgreport_javascript.tx
new file mode 100644 (file)
index 0000000..644feb4
--- /dev/null
@@ -0,0 +1,136 @@
+<script type="text/javascript">
+<!--
+toggle_extra_status_visible();
+function pagemain() {
+       toggle(1);
+//     toggle(2);
+       enable(1);
+}
+
+var visible_extra_status = 0;
+
+function toggle_extra_status_visible() {
+  all_divs = document.getElementsByTagName("div");
+  for (var i = 0; i < all_divs.length; i++) {
+      if (all_divs[i].className == "shortbugstatusextra") {
+         if (all_divs[i].style.position == 'absolute' ) {
+           all_divs[i].style.position = "static";
+           all_divs[i].style.display = "block";
+           all_divs[i].style.zIndex = 0;
+           all_divs[i].style.border = 0;
+           var subspans = all_divs[i].getElementsByTagName("span");
+           for (var j = 0; j < subspans.length; j++) {
+               subspans[j].style.display = "inline";
+           }
+         }
+        else {
+           all_divs[i].style.position = "absolute";
+           all_divs[i].style.display = "none"
+           all_divs[i].style.zIndex = 2;
+           all_divs[i].style.border = "#000 1px solid";
+           var subspans = all_divs[i].getElementsByTagName("span");
+           for (var j = 0; j < subspans.length; j++) {
+               subspans[j].style.display = "block";
+           }
+         }
+      }
+  }
+}
+
+function extra_status_visible(id) {
+  var m = document.getElementById("status_mask");
+  if (visible_extra_status) {
+     var t = document.getElementById("extra_status_"+visible_extra_status);
+     t.style.display = "none";
+     if (m) {
+        m.style.display = "none";
+     }
+     if (visible_extra_status == id) {
+       visible_extra_status = 0;
+        return;
+     }
+     visible_extra_status = 0;
+  }
+  var e = document.getElementById("extra_status_"+id);
+  if (e) {
+     e.style.display = "block";
+     visible_extra_status = id;
+     if (m) {
+        m.onclick = function() { extra_status_visible(id); };
+        m.style.display = "block";
+     }
+  }
+}
+
+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);
+        if (a) {
+             if (a.style.display == "none") {
+                     a.style.display = "";
+             } else {
+                     a.style.display = "none";
+             }
+        }
+}
+
+function enable(x) {
+    for (var i = 1; ; i++) {
+        var a = document.getElementById("b_" + x + "_" + i);
+        if (a == null) break;
+        var ischecked = a.checked;
+        for (var j = 1; ; j++) {
+            var b = document.getElementById("b_" + x + "_"+ i + "_" + j);
+            if (b == null) break;
+            if (ischecked) {
+                b.disabled = false;
+            } else {
+                b.disabled = true;
+            }
+        }
+    }
+}
+-->
+</script>
diff --git a/templates/en_US/cgi/pkgreport_options.tmpl b/templates/en_US/cgi/pkgreport_options.tmpl
deleted file mode 100644 (file)
index da362dd..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<form method="GET">
-<input type="hidden" name="_fo_combine_key_fo_searchkey_value_fo_searchvalue" value="1">
-<input type="hidden" name="form_options" value="1">
-<table class="forms">
-<tr><td><h2>Select bugs</h2>
-</td>
-<td>
-{ my $output = '';
-our $value_index = 0;
-our $search = '';
-our $search_value = '';
-for my $key (@search_key_order){
-   if (exists $param{$key}){
-        for my $value (make_list($param{$key})){
-           $search = $key;
-          $search_value = $value;
-          $output .= include('cgi/pkgreport_options_search_key');
-          $output .= '<br>';
-          $value_index++;
-        }
-   }
- }
- $search = '';
- $search_value = '';
- $output;
-}
-{include('cgi/pkgreport_options_search_key')}
-</td>
-<td>
-<p>The same search fields are ORed, different fields are ANDed.</p>
-<p>Valid severities are {$config{show_severities}}</p>
-<p>Valid tags are {join(', ',@{$config{tags}})}</p>
-</td>
-</tr>
-<tr><td><h2>Include Bugs</h2></td>
-<td>{our $incexc = 'include';
-include('cgi/pkgreport_options_include_exclude');
-}</td>
-<td></td>
-</tr>
-<tr><td><h2>Exclude Bugs</h2></td>
-<td>
-{our $incexc = 'exclude';
-include('cgi/pkgreport_options_include_exclude');
-}
-</td>
-<td></td>
-</tr>
-<tr><td><h2>Categorize/<wbr>Order using</h2></td>
-<td><select name="ordering">{ my $output = '';
-  for my $order (@{$param{orderings}}) {
-    $output .= '<option value="'.$order.'"'.(($order eq $param{ordering})?' selected':'').
-     ">$order</option>\n";
-  }
-$output;
-}</td>
-<td></td>
-</tr>
-<tr><td><h2>Misc options</h2></td>
-<td>
-<input type="checkbox" name="repeatmerged" {exists $param{repeatmerged} and $param{repeatmerged}?' checked':''}> Repeat Merged<br>
-<input type="checkbox" name="bug-rev" {exists $param{"bug-rev"} and $param{"bug-rev"}?' checked':''}> Reverse Bugs<br>
-<input type="checkbox" name="pend-rev" {exists $param{"pend-rev"} and $param{"pend-rev"}?' checked':''}> Reverse Pending<br>
-<input type="checkbox" name="sev-rev" {exists $param{"sev-rev"} and $param{"sev-rev"}?' checked':''}> Reverse Severity<br>
-<input type="checkbox" name="noaffects" {exists $param{"noaffects"} and $param{"noaffects"}?' checked':''}> No Bugs which affect packages<br>
-<select name="dist">
-{output_select_options(['' => 'None',
-                        map {($_,$_)} @{$config{distributions}},
-                       ],$param{dist}||'')
-}</select><br>
-<select name="archive">
-{output_select_options([0 => 'Unarchived',
-                        1 => 'Archived', 
-                        both => 'Archived and Unarchived',
-                       ],$param{archive}||0)
-}</select><br>
-<a href="javascript:toggle_extra_status_visible()">Toggle all extra information</a>
-</td>
-</tr>
-<tr><td><h2>Submit</h2></td><td colspan=2>
-<input type="submit" name="submit" value="Submit">
-</td></tr>
-</table>
-
-
diff --git a/templates/en_US/cgi/pkgreport_options.tx b/templates/en_US/cgi/pkgreport_options.tx
new file mode 100644 (file)
index 0000000..15497a5
--- /dev/null
@@ -0,0 +1,80 @@
+<form method="GET">
+    <input type="hidden" name="_fo_combine_key_fo_searchkey_value_fo_searchvalue" value="1">
+    <input type="hidden" name="form_options" value="1">
+    <table class="forms">
+       <tr><td><h2>Select bugs</h2>
+       </td>
+       <td>
+           : for $search_key_order -> $key {
+               : if defined $param[$key] { 
+               : for $param[$key] -> $value {
+               : include "cgi/pkgreport_options_search_key.tx" { search => $key, search_value => $value };
+               : }
+               : }
+           : }
+           : include "cgi/pkgreport_options_search_key.tx";
+       </td>
+       <td>
+           <p>The same search fields are ORed, different fields are ANDed.</p>
+           <p>Valid severities are <: $config.show_severities :></p>
+           <p>Valid tags are <: $config.tags.join(', ') :></p>
+       </td>
+       </tr>
+       <tr><td><h2>Include Bugs</h2></td>
+           <td>
+               : include "cgi/pkgreport_options_include_exclude.tx" { incexc => "include" };
+           </td>
+           <td></td>
+       </tr>
+       <tr><td><h2>Exclude Bugs</h2></td>
+           <td>
+               : include "cgi/pkgreport_options_include_exclude.tx" { incexc => "exclude" };
+           </td>
+           <td></td>
+       </tr>
+       <tr><td><h2>Categorize/<wbr>Order using</h2></td>
+           <td><select name="ordering">
+                   : for $param.orderings -> $order {
+                   <option value="<: $order :>"
+                               : if $order == $param.ordering {
+                               selected
+                    : }
+            ><:- $order -:></option>
+                   : }
+           </select>
+           </td>
+           <td></td>
+       </tr>
+       <tr><td><h2>Misc options</h2></td>
+           <td>
+               : macro input_checkbox ->($what,$text) {
+               <input type="checkbox" name="<: $what :>"
+                      : if defined($param[$what]) and $param[$what] {
+                          checked
+               : }
+               ><:- $text -:><br>
+               : }
+               <:- input_checkbox("repeatmerged","Repeat Merged") :>
+               <:- input_checkbox("bug-rev","Reverse Bugs") :>
+               <:- input_checkbox("pend-rev","Reverse Pending") :>
+               <:- input_checkbox("sev-rev","Reverse Severity") :>
+               <:- input_checkbox("noaffects","No Bugs which affect packages") :>
+               <select name="dist">
+                   <: output_select_options(['' => 'None',
+                           $config.distributions],
+                                                       ,$param.dist // '') -:>
+               </select><br>
+               <select name="archive">
+                   <: output_select_options([0 => 'Unarchived',
+                           1 => 'Archived', 
+                           both => 'Archived and Unarchived',
+                      ],$param.archive//0) -:></select><br>
+               <a href="javascript:toggle_extra_status_visible()">
+                   Toggle all extra information</a>
+           </td>
+       </tr>
+       <tr><td><h2>Submit</h2></td><td colspan=2>
+           <input type="submit" name="submit" value="Submit">
+       </td></tr>
+    </table>
+</form>
diff --git a/templates/en_US/cgi/pkgreport_options_include_exclude.tmpl b/templates/en_US/cgi/pkgreport_options_include_exclude.tmpl
deleted file mode 100644 (file)
index c0f8acd..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<input type="hidden" name="_fo_concatenate_into_{$incexc}_fo_{$incexc}key_fo_{$incexc}value" value="1">
-{ my $output = '';
-  our $value_index = 0;
-  our $key1 = '';
-  our $key2 = '';
-  for my $field (make_list($param{$incexc})) {
-    ($key1,$key2) = $field =~ m/^([^:]+)\:(.+)/;
-    next unless defined $key2;
-    $output .= include('cgi/pkgreport_options_include_exclude_key');
-  }
-  $key1 = '';
-  $key2 = '';
-  $output .= include('cgi/pkgreport_options_include_exclude_key');
-  $output;
-}
-
diff --git a/templates/en_US/cgi/pkgreport_options_include_exclude.tx b/templates/en_US/cgi/pkgreport_options_include_exclude.tx
new file mode 100644 (file)
index 0000000..a4a6f94
--- /dev/null
@@ -0,0 +1,5 @@
+<input type="hidden" name="_fo_concatenate_into_<:  $incexc :>_fo_<: $incexc :>key_fo_<: $incexc :>value" value="1">
+: for $param[$incexc] -> $field {
+    : include "cgi/pkgreport_options_include_exclude_key.tx" {key1 => split($field,':',2).0, key2 => split($field,':',2).1 };
+: }
+: include "cgi/pkgreport_options_include_exclude_key.tx";
diff --git a/templates/en_US/cgi/pkgreport_options_include_exclude_key.tmpl b/templates/en_US/cgi/pkgreport_options_include_exclude_key.tmpl
deleted file mode 100644 (file)
index ab0a246..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<nobr><select name="_fo_{$incexc}key">
-{output_select_options([subject => 'with subject containing',
-                               tags => 'tagged',
-                       severity => 'with severity',
-                        pending  => 'with pending state',
-                        originator => 'with submitter containing',
-                       forwarded  => 'with forwarded containing',
-                       owner      => 'with owner containing',
-                       package    => 'with package',
-                       ],$key1||'')}
-</select>
-<input type="text" name="_fo_{$incexc}value" value ="{html_escape($key2)||''}">
-<!-- {$value_index} -->
-</nobr>
diff --git a/templates/en_US/cgi/pkgreport_options_include_exclude_key.tx b/templates/en_US/cgi/pkgreport_options_include_exclude_key.tx
new file mode 100644 (file)
index 0000000..5beb8b9
--- /dev/null
@@ -0,0 +1,13 @@
+<nobr><select name="_fo_<: $incexc :>key">
+<:- output_select_options([subject => 'with subject containing',
+                               tags => 'tagged',
+                       severity => 'with severity',
+                        pending  => 'with pending state',
+                        originator => 'with submitter containing',
+                       forwarded  => 'with forwarded containing',
+                       owner      => 'with owner containing',
+                       package    => 'with package',
+                       ],$key1 // '') :>
+</select>
+<input type="text" name="_fo_<: $incexc :>value" value ="<: $key2 // '':>">
+</nobr>
diff --git a/templates/en_US/cgi/pkgreport_options_search_key.tmpl b/templates/en_US/cgi/pkgreport_options_search_key.tmpl
deleted file mode 100644 (file)
index e09fdff..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<nobr><select name="_fo_searchkey">
-{output_select_options(\@search_key_order,$search||'')}
-</select>
-<input type="text" name="_fo_searchvalue" value ="{html_escape($search_value||'')}">
-<!-- {$value_index} -->
-</nobr>
diff --git a/templates/en_US/cgi/pkgreport_options_search_key.tx b/templates/en_US/cgi/pkgreport_options_search_key.tx
new file mode 100644 (file)
index 0000000..4d92782
--- /dev/null
@@ -0,0 +1,5 @@
+<nobr><select name="_fo_searchkey">
+<:- raw(output_select_options($search_key_order,$search // '')) -:>
+</select>
+<input type="text" name="_fo_searchvalue" value ="<:- $search_value // '' -:>">
+</nobr>
diff --git a/templates/en_US/cgi/quit.tmpl b/templates/en_US/cgi/quit.tmpl
deleted file mode 100644 (file)
index 2a89d8e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<HEAD><TITLE>Error</TITLE></HEAD>
-<BODY>
-An error occurred.
-Error was: {$msg}
-</BODY></HTML>
diff --git a/templates/en_US/cgi/quit.tx b/templates/en_US/cgi/quit.tx
new file mode 100644 (file)
index 0000000..d889679
--- /dev/null
@@ -0,0 +1,6 @@
+<HTML>
+<HEAD><TITLE>Error</TITLE></HEAD>
+<BODY>
+An error occurred.
+Error was: <: $msg :>
+</BODY></HTML>
diff --git a/templates/en_US/cgi/short_bug_status.tmpl b/templates/en_US/cgi/short_bug_status.tmpl
deleted file mode 100644 (file)
index 821a459..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-<div class="shortbugstatus">
-  <a href="{html_escape(bug_links(bug=>$status{bug_num},links_only=>1))}"{length($status{done})?' style="text-decoration:line-through"':''}>#{html_escape($status{bug_num})}</a>
-  [<font face="fixed"><span class="link" onclick="javascript:extra_status_visible({html_escape($status{bug_num})})">{
-  my $output = qq(<abbr title="$status{severity}">);
-  my $temp = $status{severity};
-  $temp = substr $temp,0,1;
-  if (isstrongseverity($status{severity})){
-     $temp = q(<em class="severity">).uc($temp).q(</em>);
-  }
-  $output .= $temp.qq(</abbr>);
-  length($output)?$output:'&nbsp;&nbsp;';
-  }|{
-  my $output = '';
-  for my $tag (@{$status{tags_array}}) {
-     next unless exists $config{tags_single_letter}{$tag};
-     $output .= q(<abbr title=").$tag.q(">).$config{tags_single_letter}{$tag}.q(</abbr>);
-  }
-  length($output)?$output:'&nbsp;&nbsp;';
-  }|{
-  my $output = '';
-  if (@{$status{mergedwith_array}}) {
-     $output .= qq(<abbr title="merged">=</abbr>);
-  }
-  if (@{$status{fixed_versions}}) {
-     $output .= qq(<abbr title="fixed versions">☺</abbr>);
-  }
-  if (@{$status{blockedby_array}}) {
-     $output .= qq(<abbr title="blocked by">♙</abbr>);
-  }
-  if (@{$status{blocks_array}}) {
-     $output .= qq(<abbr title="blocks">♔</abbr>);
-  }
-  if (length($status{forwarded})) {
-     $output .= qq(<abbr title="forwarded">↝</abbr>);
-  }
-  if ($status{archived}) {
-     $output .= qq(<abbr title="archived">♲</abbr>);
-  }
-  if (length $status{affects}){
-     $output .= qq(<abbr title="affects">☣</abbr>);
-  }
-  length($output)?$output:'&nbsp;&nbsp;';
-  }</span></font>]
-  [{package_links(package=>[split /,/,$status{package}],options=>\%options,class=>"submitter")}]
-  <a href="{html_escape(bug_links(bug=>$status{bug_num},links_only=>1))}">{html_escape($status{subject})}</a>
-  <div id="extra_status_{html_escape($status{bug_num})}" class="shortbugstatusextra">
-  <span>Reported by: {package_links(submitter=>$status{originator})};</span>
-  <span>Date: {$status{date_text}};</span>
-{ my $output = ''; 
-  if (defined $status{owner} and length $status{owner}) {
-     $output = q(<span>Owned by: ).package_links(owner=>$status{owner}).qq(;</span>\n);
-  }
-  $output;
-}<span>Severity: {my $output = $status{severity};
-              if (isstrongseverity($status{severity})) {
-                   $output = q(<em class="severity">).$status{severity}.q(</em>);
-              }
-              $output;
-             };</span>
-<span>{@{$status{tags_array}}?q(Tags: ).html_escape(join(q(, ),@{$status{tags_array}})).';':''}</span>
-{my $output = '';
- if (@{$status{mergedwith_array}}) {
-    $output .= q(<span>Merged with ).join(qq(,\n),bug_links(bug=>$status{mergedwith_array})).qq(;</span>\n);
- }
- $output;
-}{my $output = '';
- if (@{$status{found_versions}} or @{$status{fixed_versions}}) {
-    $output .= '<a href="'.
-         version_url(package => $status{package},
-                     found   => $status{found_versions},
-                     fixed   => $status{fixed_versions},
-                    ).'"> ';
- }
- if (@{$status{found_versions}}) {
-    $output .= q(<span>Found in );
-    $output .= (@{$status{found_versions}} == 1) ? 'version ' : 'versions ';
-    $output .= join(qq(, ),map {html_escape($_);} @{$status{found_versions}}).qq(;</span>\n);
- }
- if (@{$status{fixed_versions}}) {
-    $output .= q(<span>Fixed in );
-    $output .= (@{$status{fixed_versions}} == 1) ? 'version ' : 'versions ';
-    $output .= join(qq(, ),map {html_escape($_);} @{$status{fixed_versions}}).qq(;</span>\n);
- }
- if (@{$status{found_versions}} or @{$status{fixed_versions}}) {
-    $output .= qq(</a>);
- }
- $output;
-}{ my $output = '';
- if (length($status{forwarded})) {
-    $output = "<span><strong>Forwarded</strong> to " . 
-              join(', ',
-                  map {maybelink($_)}
-                   split /\,\s+/,$status{forwarded}
-                 ).";</span>\n";
- }
- $output;
-}{ my $output = '';
-  if (length($status{done})) {
-     $output .= q(<span><strong>Done:</strong> ).html_escape($status{done}).q(;</span> )
-  }
-  $output;
-}{ my $output = '';
-   my $days = $status{archive_days};
-   if ($days >= 0 and defined $status{location} and $status{location} ne 'archive') {
-       $output .= "<span><strong>Can be archived" .
-          ( $days == 0 ? " today" : $days == 1 ? " in $days day" : " in $days days" ) .
-              ";</strong></span>\n";
-   }
-   elsif (defined $status{location} and $status{location} eq 'archived') {
-       $output .= "<span><strong>Archived</strong></span>;\n";
-   }
-   $output;
-}{ my $output = '';
-  if (@{$status{blockedby_array}}) {
-     $output .= q(<span>Fix blocked by ).
-        join(q(, ),
-         map {bug_links(bug=>$_->{bug_num}).q(: ).html_escape($_->{subject})}
-         @{$status{blockedby_array}}).q(;</span> )
-  }
-  if (@{$status{blocks_array}}) {
-     $output .= q(<span>Blocking fix for ).
-        join(q(, ),
-         map {bug_links(bug=>$_->{bug_num}).q(: ).html_escape($_->{subject})}
-         @{$status{blocks_array}}).q(;</span> )
-  }
-  $output;
-}{ my $output = '';
- my ($days_last,$eng_last) = secs_to_english(time - $status{log_modified});
- my ($days,$eng) = secs_to_english(time - $status{date});
-
- if ($days >= 7) {
-   my $font = "";
-   my $efont = "";
-   $font = "em" if ($days > 30);
-   $font = "strong" if ($days > 60);
-   $efont = "</$font>" if ($font);
-   $font = "<$font>" if ($font);
-
-   $output .= "<span>${font}Filed $eng ago$efont;</span>\n";
- }
- if ($days_last > 7) {
-   my $font = "";
-   my $efont = "";
-   $font = "em" if ($days_last > 30);
-   $font = "strong" if ($days_last > 60);
-   $efont = "</$font>" if ($font);
-   $font = "<$font>" if ($font);
-
-   $output .= "<span>${font}Modified $eng_last ago$efont;</span>\n";
- }
- $output;
- }{ my $output = '';
-  if (exists $status{archived} and $status{archived}) {
-     $output .= q(<span>Bug is archived. No further changes may be made.<span> )
-  }
-  $output}</div>
-</div>
diff --git a/templates/en_US/cgi/short_bug_status.tx b/templates/en_US/cgi/short_bug_status.tx
new file mode 100644 (file)
index 0000000..1952173
--- /dev/null
@@ -0,0 +1,135 @@
+<div class="shortbugstatus">
+  <a href="<: bug_links(bug=>$status.bug_num,links_only=>1):>"<:length($status.done)?' style="text-decoration:line-through"':'':>>#<: $status.bug_num :></a>
+  [<font face="fixed"><span class="link" onclick="javascript:extra_status_visible(<: $status.bug_num :>)"><abbr title="<: $status.severity :>">
+      <:- my $short_sev = substr($status.severity,0,1) -:>
+      <:- if isstrongseverity($status.severity) { -:><em class="severity"><: uc($short_sev) :></em>
+      <:- } else { -:>
+      <:- $short_sev } -:></abbr>|
+      <:- for $status.tags_array -> $tag { -:>
+      <:- if defined($config.tags_single_letter[$tag]) { -:>
+      <abbr title="<: $tag :>"><: $config.tags_single_letter[$tag] :></abbr><:- } -:>
+      : }
+          <:- if $status.tags_array.size() == 0 { -:>&nbsp;&nbsp;<: } :>|
+          <:- if $status.mergedwith_array.count > 0 { -:>
+          <abbr title="merged">=</abbr>
+          <:- } -:>
+          <:- if $status.fixed_versions.count > 0 { -:>
+          <abbr title="fixed versions">☺</abbr>
+          <:- } -:>
+          <:- if $status.fixed_versions.count > 0 { -:>
+          <abbr title="fixed versions">☺</abbr>
+          <:- } -:>
+          <:- if $status.blockedby_array.count > 0 { -:>
+          <abbr title="blocked by">♙</abbr>
+          <:- } -:>
+          <:- if $status.blocks_array.count > 0 { -:>
+          <abbr title="blocks">♔</abbr>
+          <:- } -:>
+          <:- if length($status.forwarded) { -:>
+          <abbr title="forwarded">↝</abbr>
+          <:- } -:>
+          <:- if $status.archived { -:>
+          <abbr title="archived">♲</abbr>
+          <:- } -:>
+          <:- if length($status.affects) { -:>
+          <abbr title="affects">☣</abbr>
+          <:- } -:></span></font>]
+  [<: raw(package_links(package=>$status.package.split(','),class=>"submitter")) :>]
+  <a href="<: bug_links(bug=>$status.bug_num,links_only=>1) :>"><: $status.subject :></a>
+  <div id="extra_status_<: $status.bug_num :>" class="shortbugstatusextra">
+      <span>Reported by: <: raw(package_links(submitter=>$status.originator)) :>;</span>
+      <span>Date: <: $status.date_text :>;</span>
+      <:- if (defined $status.owner and length($status.owner)) { -:>
+      <span>Owned by: <: raw(package_links(owner=>$status.owner)) :>;</span>
+      <:- } :>
+      <span>Severity:
+          <:- if (isstrongseverity($status.severity)) { -:>
+          <em class="severity">)<: $status.severity :></em>
+          <:- } else { -:>
+          <: $status.severity :>
+          <:- } -:></span>
+      <span>
+          <:- if $status.tags_array.size > 0 { -:>
+          Tags: <:  $status.tags_array.join(', ') :>;
+          <:- } -:>
+      </span>
+      : if $status.mergedwith_array.size > 0 {
+      <span>Merged with <: bug_links(bug=>$status.mergedwith_array).join(",\n") :>;</span>
+      : }
+      : if $status.found_versions.size > 0 or $status.fixed_versions.size > 0 {
+      <a href="<:
+                  version_url(package => $status.package,
+                          found   => $status.found_versions,
+                          fixed   => $status.fixed_versions,
+                      ):>">
+          <:- } -:>
+          <:- if $status.found_versions.size > 0 { -:>
+          <span>Found in version<: if $status.found_versions.size > 1 { :>s<: } :>
+              <:- $status.found_versions.join(', ') -:>;
+          </span>
+          <:- } -:>
+          <:- if $status.fixed_versions.size > 0 { :>
+          <span>Fixed in version<: if $status.fixed_versions.size > 1 { :>s<: } :>
+              <:- $status.fixed_versions.join(', ') -:>;
+          </span>
+          <:- } -:>
+          <:- if $status.found_versions.size > 0 or $status.fixed_versions.size > 0 { -:>
+      </a>
+      <:- } -:>
+      <:-  if (length($status.forwarded)) { :>
+      <span><strong>Forwarded</strong> to 
+          <: $status.forwarded.split('\,\s+').map(maybelink).join(', ') :>
+      </span>
+      <:- } -:>
+      <:- if (length($status.done)) { -:>
+      <span><strong>Done:</strong>
+          <: $status.done :>
+      </span>
+      <:- } -:>
+      <:- if  $status.archive_days >= 0  and 
+      defined($status.location) && $status.location != "archive" { -:>
+      <span><strong>Can be archived
+          <: if $status.archive_days == 0 { :>
+          today
+          <: } else if $status.archive_days == 1 { :>
+          in 1 day
+          <: } else { :>
+          in <: $status.archive_days :> days
+          <:- } :>;</strong></span>
+      <:- } else if defined($status.location) && $status.location == "archived" { -:>
+      <span><strong>Archived</strong></span>
+      <:- } -:>
+      <:- if $status.blockedby_array.count > 0 { :>
+      <span>Fix blocked by 
+          <: for $status.blockedby_array -> $bug { :>
+          <: bug_links("bug",bug.bug_num) :>: 
+          <: $bug.subject -:>
+          <:- if ! $~bug.is_last { -:>, <: } else { -:>.<:- } -:>
+          <:- } -:>
+      </span>
+      <:- } -:>
+      <:- if $status.blocks_array.count > 0 { :>
+      <span>Blocking fix for
+          <: for $status.blocks_array -> $bug { :>
+          <: bug_links("bug",bug.bug_num) :>: 
+          <: $bug.subject -:>
+          <:- if ! $~bug.is_last {-:>, <: } else { -:>.<:- } -:>
+          <:- } -:>
+      </span>
+      <:- } -:>
+      <:- macro days_ago->($what,$ago) {-:>
+      <span>
+          <:- if ($time - $ago) / 86400 > 60 { -:>
+          <strong><: $what :> <:  secs_to_english($time-$ago) :> ago.</strong>
+          <:- } else if ($time - $ago) / 86400 > 30 { :>
+          <strong><: $what :> <:  secs_to_english($time-$ago) :> ago.</strong>
+          <:- } -:>;
+      </span>
+      <:- } -:>
+      <: days_ago("Filed",$status.date) :>
+      <: days_ago("Modified",$status.log_modified) :>
+      <:- if defined $status.archived and $status.archived {:>
+      <span>Bug is archived. No further changes may be made.</span>
+      <:- } -:>
+  </div>
+</div>
diff --git a/templates/en_US/html/html_tail.tmpl b/templates/en_US/html/html_tail.tmpl
deleted file mode 100644 (file)
index 0bbfc43..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<ADDRESS>{$config{maintainer}} &lt;<A HREF="mailto:{$config{maintainer_email}}">{$config{maintainer_email}}</A>&gt;.
-Last modified:
-<!--timestamp-->{$last_modified||strftime('%c',gmtime)}<!--end timestamp-->; 
-Machine Name:
-<!--machinename-->{$config{machine_name}||'Unknown'}<!--machinename-->
-<P>
-<A HREF="{$config{web_domain}}/">{$config{project}} {$config{bug}} tracking system</A>
-</p>
-<p>
-  Debbugs is free software and licensed under the terms of the GNU
-  Public License version 2. The current version can be obtained
-  from <a href="https://bugs.debian.org/debbugs-source/">https://bugs.debian.org/debbugs-source/</a>.
-</p>
-<p>
-Copyright © 1999 Darren O. Benham,
-1997,2003 nCipher Corporation Ltd,
-1994-97 Ian Jackson,
-2005-2017 Don Armstrong, and many other contributors.
-</p>
-</ADDRESS>
diff --git a/templates/en_US/html/html_tail.tx b/templates/en_US/html/html_tail.tx
new file mode 100644 (file)
index 0000000..cca1fe7
--- /dev/null
@@ -0,0 +1,21 @@
+<address><: $config.maintainer :>
+    &lt;<a href="mailto:<: $config.maintainer_email :>"><: $config.maintainer_email :></a>&gt;.
+    Last modified:
+    <!--timestamp--><: defined $last_modified ? $last_modified : gm_strftime('%c') :><!--end timestamp-->; 
+    Machine Name:
+    <!--machinename--><: $config.machine_name ||'Unknown' :><!--machinename-->
+    <p>
+        <a href="<: $config.web_domain :>/"><: $config.project :> <: $config.bug :> tracking system</a>
+    </p>
+    <p>
+        Debbugs is free software and licensed under the terms of the
+        GNU Public License version 2. The current version can be
+        obtained from <a href="https://bugs.debian.org/debbugs-source/">https://bugs.debian.org/debbugs-source/</a>.
+    </p>
+    <p>
+        Copyright © 1999 Darren O. Benham,
+        1997,2003 nCipher Corporation Ltd,
+        1994-97 Ian Jackson,
+        2005-2017 Don Armstrong, and many other contributors.
+    </p>
+</address>
diff --git a/templates/en_US/html/post_title.tmpl b/templates/en_US/html/post_title.tmpl
deleted file mode 100644 (file)
index 5ec109a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<link rel="stylesheet" href="{$config{web_host_bug_dir}}/css/bugs.css" type="text/css">
diff --git a/templates/en_US/html/post_title.tx b/templates/en_US/html/post_title.tx
new file mode 100644 (file)
index 0000000..0061ca2
--- /dev/null
@@ -0,0 +1,4 @@
+</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<link rel="stylesheet" href="<: $config.web_host_bug_dir :>/css/bugs.css" type="text/css">
diff --git a/templates/en_US/html/pre_title.tmpl b/templates/en_US/html/pre_title.tmpl
deleted file mode 100644 (file)
index 2f7ab77..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html><head>
-<title>
\ No newline at end of file
diff --git a/templates/en_US/html/pre_title.tx b/templates/en_US/html/pre_title.tx
new file mode 100644 (file)
index 0000000..22cdfda
--- /dev/null
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html><head>
+<link rel="icon" href="//favicon.png">
+<title>
\ No newline at end of file
diff --git a/templates/en_US/mail/excluded_from_control.tmpl b/templates/en_US/mail/excluded_from_control.tmpl
deleted file mode 100644 (file)
index adf10e4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-You have been specifically excluded from using the control interface.
-
-Have a nice day
diff --git a/templates/en_US/mail/excluded_from_control.tx b/templates/en_US/mail/excluded_from_control.tx
new file mode 100644 (file)
index 0000000..adf10e4
--- /dev/null
@@ -0,0 +1,3 @@
+You have been specifically excluded from using the control interface.
+
+Have a nice day
diff --git a/templates/en_US/mail/fake_control_message.tmpl b/templates/en_US/mail/fake_control_message.tmpl
deleted file mode 100644 (file)
index 2af273d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Received: (at fakecontrol) by fakecontrolmessage;
-To: {$request_addr}
-From: {$requester}
-Subject: Internal Control
-Message-Id: {$action}
-Date: {$date}
-User-Agent: Fakemail v42.6.9
-
-# A New Hope
-# A long time ago, in a galaxy far, far away
-# something happened.
-#
-# Magically this resulted in the following
-# action being taken, but this fake control
-# message doesn't tell you why it happened
-#
-# The action:
-# {$action}
-thanks
-# This fakemail brought to you by your local debbugs
-# administrator
diff --git a/templates/en_US/mail/fake_control_message.tx b/templates/en_US/mail/fake_control_message.tx
new file mode 100644 (file)
index 0000000..9df6c9b
--- /dev/null
@@ -0,0 +1,21 @@
+Received: (at fakecontrol) by fakecontrolmessage;
+To: <: $request_addr :>
+From: <: $requester :>
+Subject: Internal Control
+Message-Id: <: $action :>
+Date: <: $date :>
+User-Agent: Fakemail v42.6.9
+
+# A New Hope
+# A long time ago, in a galaxy far, far away
+# something happened.
+#
+# Magically this resulted in the following
+# action being taken, but this fake control
+# message doesn't tell you why it happened
+#
+# The action:
+# <: $action :>
+thanks
+# This fakemail brought to you by your local debbugs
+# administrator
diff --git a/templates/en_US/mail/footer.tmpl b/templates/en_US/mail/footer.tmpl
deleted file mode 100644 (file)
index 132201f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
--- 
-{
-my %ref_handled;
-for my $bug (sort ($ref,@refs)) {
-    next unless defined $bug;
-    next if exists $ref_handled{$bug};
-    $ref_handled{$bug} = 1;
-    $OUT .= bugurl($bug).qq(\n);
-}
-}{$config{project}} {ucfirst($config{bug})} Tracking System
-Contact {$config{maintainer_email}} with problems
diff --git a/templates/en_US/mail/footer.tx b/templates/en_US/mail/footer.tx
new file mode 100644 (file)
index 0000000..921606e
--- /dev/null
@@ -0,0 +1,6 @@
+-- 
+: for $refs -> $bug {
+<: bugurl($bug) :>
+: }
+<:$config.project:> <: $config.ubug :> Tracking System
+Contact <: $config.maintainer_email :> with problems
diff --git a/templates/en_US/mail/forward_maintonly.tmpl b/templates/en_US/mail/forward_maintonly.tmpl
deleted file mode 100644 (file)
index ec6606e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-Your message has been forwarded to the package maintainers (but not
-other interested parties, as you requested) for their attention; they
-will reply in due course.
diff --git a/templates/en_US/mail/forward_maintonly.tx b/templates/en_US/mail/forward_maintonly.tx
new file mode 100644 (file)
index 0000000..ec6606e
--- /dev/null
@@ -0,0 +1,4 @@
+
+Your message has been forwarded to the package maintainers (but not
+other interested parties, as you requested) for their attention; they
+will reply in due course.
diff --git a/templates/en_US/mail/forward_normal.tmpl b/templates/en_US/mail/forward_normal.tmpl
deleted file mode 100644 (file)
index c345364..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-Your message is being forwarded to the package maintainers and other
-interested parties for their attention; they will reply in due course.
diff --git a/templates/en_US/mail/forward_normal.tx b/templates/en_US/mail/forward_normal.tx
new file mode 100644 (file)
index 0000000..c345364
--- /dev/null
@@ -0,0 +1,3 @@
+
+Your message is being forwarded to the package maintainers and other
+interested parties for their attention; they will reply in due course.
diff --git a/templates/en_US/mail/forward_veryquiet.tmpl b/templates/en_US/mail/forward_veryquiet.tmpl
deleted file mode 100644 (file)
index 623eded..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Your message has not been forwarded to the package maintainers or
-other interested parties; you should ensure that the developers are
-aware of the problem you have entered into the system - preferably
-quoting the { $config{bug} } reference number, #{ $ref }.
diff --git a/templates/en_US/mail/forward_veryquiet.tx b/templates/en_US/mail/forward_veryquiet.tx
new file mode 100644 (file)
index 0000000..b98e82f
--- /dev/null
@@ -0,0 +1,5 @@
+
+Your message has not been forwarded to the package maintainers or
+other interested parties; you should ensure that the developers are
+aware of the problem you have entered into the system - preferably
+quoting the <: $config.bug :> reference number, #<: $ref :>.
diff --git a/templates/en_US/mail/header.tmpl b/templates/en_US/mail/header.tmpl
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/templates/en_US/mail/header.tx b/templates/en_US/mail/header.tx
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/templates/en_US/mail/invalid_maintainer.tmpl b/templates/en_US/mail/invalid_maintainer.tmpl
deleted file mode 100644 (file)
index 9a244ff..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-You requested that the message be sent to the package maintainer(s)
-but either the { $config{bug} } report is not associated with any package (probably
-because of a missing Package pseudo-header field in the original { $config{bug} }
-report), or the package(s) specified do not have any maintainer(s).
-
-Your message has *not* been sent to any package maintainers; it has
-merely been filed in the { $config{bug} } tracking system.  If you require assistance
-please contact { $config{maintainer_email} } quoting the { $config{bug} } number { $ref }.
diff --git a/templates/en_US/mail/invalid_maintainer.tx b/templates/en_US/mail/invalid_maintainer.tx
new file mode 100644 (file)
index 0000000..cff38b4
--- /dev/null
@@ -0,0 +1,9 @@
+
+You requested that the message be sent to the package maintainer(s)
+but either the <: $config.bug :> report is not associated with any package (probably
+because of a missing Package pseudo-header field in the original <: $config.bug :>
+report), or the package(s) specified do not have any maintainer(s).
+
+Your message has *not* been sent to any package maintainers; it has
+merely been filed in the <: $config.bug :> tracking system.  If you require assistance
+please contact <: $config.maintainer_email :> quoting the <: $config.bug :> number <: $ref :>.
diff --git a/templates/en_US/mail/invalid_severity.tmpl b/templates/en_US/mail/invalid_severity.tmpl
deleted file mode 100644 (file)
index dad928f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Your message specified a Severity: in the pseudo-header, but
-the severity value {$severity} was not recognised.
-The default severity {$config{default_severity}} is being used instead.
-The recognised values are: {$config{show_severities}}.
diff --git a/templates/en_US/mail/invalid_severity.tx b/templates/en_US/mail/invalid_severity.tx
new file mode 100644 (file)
index 0000000..826f6c8
--- /dev/null
@@ -0,0 +1,5 @@
+
+Your message specified a Severity: in the pseudo-header, but
+the severity value <: $severity :> was not recognised.
+The default severity <: $config.default_severity :> is being used instead.
+The recognised values are: <: $config.show_severities :>.
diff --git a/templates/en_US/mail/invalid_user.tmpl b/templates/en_US/mail/invalid_user.tmpl
deleted file mode 100644 (file)
index d7f3891..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-Your message tried to set a usertag, but didn't have a valid
-user set ('{$user}' isn't valid)
diff --git a/templates/en_US/mail/invalid_user.tx b/templates/en_US/mail/invalid_user.tx
new file mode 100644 (file)
index 0000000..2df06f2
--- /dev/null
@@ -0,0 +1,3 @@
+
+Your message tried to set a usertag, but didn't have a valid
+user set ('<: $user :>' isn't valid)
diff --git a/templates/en_US/mail/invalid_version.tmpl b/templates/en_US/mail/invalid_version.tmpl
deleted file mode 100644 (file)
index 1bddeab..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-Your message had a Version: pseudo-header with an invalid package
-version:
-
-{$version}
-
-please either use found or fixed to the control server with a correct
-version, or reply to this report indicating the correct version so the
-maintainer (or someone else) can correct it for you.
diff --git a/templates/en_US/mail/invalid_version.tx b/templates/en_US/mail/invalid_version.tx
new file mode 100644 (file)
index 0000000..a1bbcaf
--- /dev/null
@@ -0,0 +1,9 @@
+
+Your message had a Version: pseudo-header with an invalid package
+version:
+
+<: $version :>
+
+please either use found or fixed to the control server with a correct
+version, or reply to this report indicating the correct version so the
+maintainer (or someone else) can correct it for you.
diff --git a/templates/en_US/mail/maintainercc.tmpl b/templates/en_US/mail/maintainercc.tmpl
deleted file mode 100644 (file)
index 5a6cb41..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-Your message has been sent to the package maintainer(s):
-{join('',map {" $_\n"} @maintaddrs)}
\ No newline at end of file
diff --git a/templates/en_US/mail/maintainercc.tx b/templates/en_US/mail/maintainercc.tx
new file mode 100644 (file)
index 0000000..e168771
--- /dev/null
@@ -0,0 +1,3 @@
+
+Your message has been sent to the package maintainer(s):
+<: $maintaddrs.join("\n") :>
diff --git a/templates/en_US/mail/message_body.tmpl b/templates/en_US/mail/message_body.tmpl
deleted file mode 100644 (file)
index b2f7c4d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-{include('mail/header')}{$body}
-{include('mail/footer')}
\ No newline at end of file
diff --git a/templates/en_US/mail/message_body.tx b/templates/en_US/mail/message_body.tx
new file mode 100644 (file)
index 0000000..a7a4863
--- /dev/null
@@ -0,0 +1,3 @@
+: include "mail/header.tx"
+<: $body :>
+: include "mail/footer.tx"
\ No newline at end of file
diff --git a/templates/en_US/mail/process_ack.tmpl b/templates/en_US/mail/process_ack.tmpl
deleted file mode 100644 (file)
index e15ea5a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{$thanks}
-This is an automatically generated reply to let you know your message
-has been received.
-{ $forwardexplain }{ $resentccexplain }
-If you wish to submit further information on this problem, please
-send it to { $refreplyto }.
-
-Please do not send mail to {$config{maintainer_email}} unless you wish
-to report a problem with the {ucfirst($config{bug})}-tracking system.
-{$brokenness}
\ No newline at end of file
diff --git a/templates/en_US/mail/process_ack.tx b/templates/en_US/mail/process_ack.tx
new file mode 100644 (file)
index 0000000..e3ca006
--- /dev/null
@@ -0,0 +1,10 @@
+<: $thanks :>
+This is an automatically generated reply to let you know your message
+has been received.
+<: $forwardexplain :><: $resentccexplain :>
+If you wish to submit further information on this problem, please
+send it to <: $refreplyto :>.
+
+Please do not send mail to <:$config.maintainer_email:> unless you wish
+to report a problem with the <: $config.bug :>-tracking system.
+<: $brokenness :>
\ No newline at end of file
diff --git a/templates/en_US/mail/process_ack_thanks_additional.tmpl b/templates/en_US/mail/process_ack_thanks_additional.tmpl
deleted file mode 100644 (file)
index 47e7675..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Thank you for the additional information you have supplied regarding
-this {$config{bug}} report.
diff --git a/templates/en_US/mail/process_ack_thanks_additional.tx b/templates/en_US/mail/process_ack_thanks_additional.tx
new file mode 100644 (file)
index 0000000..f431380
--- /dev/null
@@ -0,0 +1,2 @@
+Thank you for the additional information you have supplied regarding
+this <: $config.bug :> report.
diff --git a/templates/en_US/mail/process_ack_thanks_new.tmpl b/templates/en_US/mail/process_ack_thanks_new.tmpl
deleted file mode 100644 (file)
index adcb5c0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Thank you for filing a new {$config{bug}} report with {$config{project}}.
-
-You can follow progress on this {$config{bug}} here: {bugurl($ref)}.
diff --git a/templates/en_US/mail/process_ack_thanks_new.tx b/templates/en_US/mail/process_ack_thanks_new.tx
new file mode 100644 (file)
index 0000000..538eb50
--- /dev/null
@@ -0,0 +1,3 @@
+Thank you for filing a new <: $config.bug :> report with <:$config.project:>.
+
+You can follow progress on this <: $config.bug :> here: <: bugurl($ref) :>
diff --git a/templates/en_US/mail/process_broken_subject.tmpl b/templates/en_US/mail/process_broken_subject.tmpl
deleted file mode 100644 (file)
index b14668d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Your message did not contain a Subject field. They are recommended and
-useful because the title of a {$config{bug}} is determined using this field.
-Please remember to include a Subject field in your messages in future.
diff --git a/templates/en_US/mail/process_broken_subject.tx b/templates/en_US/mail/process_broken_subject.tx
new file mode 100644 (file)
index 0000000..38275bd
--- /dev/null
@@ -0,0 +1,3 @@
+Your message did not contain a Subject field. They are recommended and
+useful because the title of a <: $config.bug :> is determined using this field.
+Please remember to include a Subject field in your messages in future.
diff --git a/templates/en_US/mail/process_default_package_selected.tmpl b/templates/en_US/mail/process_default_package_selected.tmpl
deleted file mode 100644 (file)
index 46cbe54..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-The ${gBug} you submitted against package '{$old_package}' has no
-known maintainer. This usually means that you either did not include a
-Package: pseudoheader, or you filed a bug against a non-existant
-package. Your bug report has been reassigned to package
-'{$new_package}' which is the default package for this bug reporting
-system.
diff --git a/templates/en_US/mail/process_default_package_selected.tx b/templates/en_US/mail/process_default_package_selected.tx
new file mode 100644 (file)
index 0000000..c5d941e
--- /dev/null
@@ -0,0 +1,6 @@
+The <: $config.bug :> you submitted against package '<: $old_package :>' has no
+known maintainer. This usually means that you either did not include a
+Package: pseudoheader, or you filed a bug against a non-existant
+package. Your bug report has been reassigned to package
+'<: $new_package :>' which is the default package for this bug reporting
+system.
diff --git a/templates/en_US/mail/process_mark_as_done.tmpl b/templates/en_US/mail/process_mark_as_done.tmpl
deleted file mode 100644 (file)
index f764c43..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-Your message dated {$date}
-with message-id {$messageid}
-and subject line {$subject}
-has caused the {$config{project}} {$config{bug}} report #{$ref},
-regarding {$data{subject}}
-to be marked as done.
-
-This means that you claim that the problem has been dealt with.
-If this is not the case it is now your responsibility to reopen the
-{$config{bug}} report if necessary, and/or fix the problem forthwith.
-
-{include('mail/serious_mail_misconfiguration')}
-
diff --git a/templates/en_US/mail/process_mark_as_done.tx b/templates/en_US/mail/process_mark_as_done.tx
new file mode 100644 (file)
index 0000000..3c8a4e0
--- /dev/null
@@ -0,0 +1,13 @@
+Your message dated <: $date :>
+with message-id <: $messageid :>
+and subject line <: $subject :>
+has caused the <: $config.project :> <: $config.bug :> report #<: $ref:>
+regarding <:$data.subject:>
+to be marked as done.
+
+This means that you claim that the problem has been dealt with.
+If this is not the case it is now your responsibility to reopen the
+<: $config.bug :> report if necessary, and/or fix the problem forthwith.
+
+: include "mail/serious_mail_misconfiguration.tx"
+
diff --git a/templates/en_US/mail/process_mark_as_forwarded.tmpl b/templates/en_US/mail/process_mark_as_forwarded.tmpl
deleted file mode 100644 (file)
index c099230..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Your message dated {$date}
-with message-id {$messageid}
-has caused the {$gProject} {$gBug} report #{$ref},
-regarding {$data{subject}}
-to be marked as having been forwarded to the upstream software
-author(s) {$data{forwarded}}
-
-{include('mail/serious_mail_misconfiguration')}
-
diff --git a/templates/en_US/mail/process_mark_as_forwarded.tx b/templates/en_US/mail/process_mark_as_forwarded.tx
new file mode 100644 (file)
index 0000000..e8d9341
--- /dev/null
@@ -0,0 +1,8 @@
+Your message dated <: $date :>
+with message-id <: $messageid :>
+has caused the <: $config.project :> <: $config.bug :> report #<: $ref :>
+regarding <: $data.subject :>
+to be marked as having been forwarded to the upstream software
+author(s) <: $data.forwarded :>
+
+: include "mail/serious_mail_misconfiguration.tx"
diff --git a/templates/en_US/mail/process_no_bug_number.tmpl b/templates/en_US/mail/process_no_bug_number.tmpl
deleted file mode 100644 (file)
index 033d180..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-You sent a message to the {$config{project}} {$config{bug}} tracking system old-style
-{$markaswhat} address ({$receivedat}),
-without a recognisable $gBug number in the Subject.
-Your message has been filed under junk but otherwise ignored.
-
-If you don't know what I'm talking about then probably either:
-
-You unwittingly sent a message to {$receivedat}
-because you replied to all recipients of the message a developer used
-to mark a {$config{bug}} as {$markaswhat} and you modified the Subject.  In this case,
-please do not be alarmed.  To avoid confusion do not do it again, but
-there is no need to apologise or mail anyone asking for an explanation.
-
--or-
-
-{include('mail/serious_mail_misconfiguration')}
-
-Your message was dated {$date} and had
-message-id {$messageid}
-and subject {$subject}.
-
-If you need any assistance or explanation please contact {$config{maintainer_email}}.
diff --git a/templates/en_US/mail/process_no_bug_number.tx b/templates/en_US/mail/process_no_bug_number.tx
new file mode 100644 (file)
index 0000000..b420deb
--- /dev/null
@@ -0,0 +1,22 @@
+You sent a message to the <:$config.project:> <: $config.bug :> tracking system old-style
+<: $markaswhat :> address (<: $receivedat :>),
+without a recognisable <: $config.bug :> number in the Subject.
+Your message has been filed under junk but otherwise ignored.
+
+If you don't know what I'm talking about then probably either:
+
+You unwittingly sent a message to <: $receivedat :>
+because you replied to all recipients of the message a developer used
+to mark a <: $config.bug :> as <: $markaswhat :> and you modified the Subject.  In this case,
+please do not be alarmed.  To avoid confusion do not do it again, but
+there is no need to apologise or mail anyone asking for an explanation.
+
+-or-
+
+: include('mail/serious_mail_misconfiguration.tx')
+
+Your message was dated <: $date :> and had
+message-id <: $messageid :>
+and subject <: $subject :>.
+
+If you need any assistance or explanation please contact <:$config.maintainer_email:>.
diff --git a/templates/en_US/mail/process_no_package.tmpl b/templates/en_US/mail/process_no_package.tmpl
deleted file mode 100644 (file)
index ccfc486..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Your message didn't have a Package: line at the very first line of the
-mail body (part of the pseudo-header), or didn't have a Package: line
-at all. Unfortunatly, this means that your message has been ignored
-completely.
-
-Without this information we are unable to categorise or otherwise deal
-with your problem report. Please _resubmit_ your report to
-{$baddress}@{$config{email_domain}} and tell us which package the
-report is for. For help, check out
-{$config{web_domain}}/Reporting{$config{html_suffix}}.
-
-Your message was dated {$date} and had
-message-id {$messageid}
-and subject {$subject}.
-The complete text of it is attached to this message.
-
-If you need any assistance or explanation please contact
-{$config{maintainer_email}} and include the the attached
-message.
-
-If you didn't send the attached message (spam was sent forging your
-from address), we apologize; please disregard this message.
diff --git a/templates/en_US/mail/process_no_package.tx b/templates/en_US/mail/process_no_package.tx
new file mode 100644 (file)
index 0000000..d6391eb
--- /dev/null
@@ -0,0 +1,22 @@
+Your message didn't have a Package: line at the very first line of the
+mail body (part of the pseudo-header), or didn't have a Package: line
+at all. Unfortunatly, this means that your message has been ignored
+completely.
+
+Without this information we are unable to categorise or otherwise deal
+with your problem report. Please _resubmit_ your report to
+<: $baddress :>@<: $config.email_domain:> and tell us which package the
+report is for. For help, check out:
+<: $config.web_domain :>/Reporting<: $config.html_suffix :>
+
+Your message was dated <: $date :> and had
+message-id <: $messageid :>
+and subject <: $subject :>.
+The complete text of it is attached to this message.
+
+If you need any assistance or explanation please contact
+<: $config.maintainer_email :> and include the the attached
+message.
+
+If you didn't send the attached message (spam was sent forging your
+from address), we apologize; please disregard this message.
diff --git a/templates/en_US/mail/process_unknown_bug_number.tmpl b/templates/en_US/mail/process_unknown_bug_number.tmpl
deleted file mode 100644 (file)
index b3391a1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-You sent a message to the {$config{bug}} tracking system which gave (in the
-Subject line or encoded into the recipient at {$config{email_domain}),
-the number of a nonexistent {$config{bug}} report (#{$tryref}).
-{if ($config{remove_age}){
-  $OUT .= "\n".
-"This may be because that $config{bug} report has been resolved for more than $config{remove_age}\n".
-"days, and the record of it has been archived and made read-only, or\n".
-"because you mistyped the $config{bug} report number.\n"
-  }
-}
-Your message was dated {$date} and was sent to
-{$baddress}@{$config{email_domain}}.  It had
-Message-ID {$messageid}
-and Subject {$subject}
-
-It has been filed (under junk) but otherwise ignored.
-
-Please consult your records to find the correct {$config{bug}} report
-number, or contact {$config{maintainer_email}} for assistance.
-
-{include('mail/serious_mail_misconfiguration')}
\ No newline at end of file
diff --git a/templates/en_US/mail/process_unknown_bug_number.tx b/templates/en_US/mail/process_unknown_bug_number.tx
new file mode 100644 (file)
index 0000000..76b72df
--- /dev/null
@@ -0,0 +1,20 @@
+You sent a message to the <: $config.bug :> tracking system which gave (in the
+Subject line or encoded into the recipient at <: $config.email_domain :>),
+the number of a nonexistent <: $config.bug :> report (#<: $tryref :>).
+:if ($config.remove_age) {
+This may be because that <: $config.bug :> report has been resolved for more than <: $config.remove_age :>
+days, and the record of it has been archived and made read-only, or
+because you mistyped the <: $config.bug :> report number.
+: }
+
+Your message was dated <: $date :> and was sent to
+< :$baddress :>@<:$config.email_domain:>.  It had
+Message-ID <: $messageid :>
+and Subject <: $subject :>
+
+It has been filed (under junk) but otherwise ignored.
+
+Please consult your records to find the correct <: $config.bug :> report
+number, or contact <: $config.maintainer_email :> for assistance.
+
+: include('mail/serious_mail_misconfiguration.tx')
\ No newline at end of file
diff --git a/templates/en_US/mail/process_your_bug_done.tmpl b/templates/en_US/mail/process_your_bug_done.tmpl
deleted file mode 100644 (file)
index f01e5b0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-This is an automatic notification regarding your {$config{bug}} report
-which was filed against the {$data{package}} package:
-
-#{$data{bug_num}}: {$data{subject}}
-
-It has been closed by {$markedby}.
-
-Their explanation is attached below along with your original report.
-If this explanation is unsatisfactory and you have not received a
-better one in a separate message then please contact {$markedby} by
-replying to this email.
-
diff --git a/templates/en_US/mail/process_your_bug_done.tx b/templates/en_US/mail/process_your_bug_done.tx
new file mode 100644 (file)
index 0000000..faac745
--- /dev/null
@@ -0,0 +1,12 @@
+This is an automatic notification regarding your <: $config.bug :> report
+which was filed against the <: $data.package :> package:
+
+#<: $data.bug_num :>: <: $data.subject :>
+
+It has been closed by <: $markedby :>
+
+Their explanation is attached below along with your original report.
+If this explanation is unsatisfactory and you have not received a
+better one in a separate message then please contact <: $markedby :> by
+replying to this email.
+
diff --git a/templates/en_US/mail/serious_mail_misconfiguration.tmpl b/templates/en_US/mail/serious_mail_misconfiguration.tmpl
deleted file mode 100644 (file)
index 1a9539f..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-(NB: If you are a system administrator and have no idea what this
-message is talking about, this may indicate a serious mail system
-misconfiguration somewhere. Please contact {$config{maintainer_email}}
-immediately.)
\ No newline at end of file
diff --git a/templates/en_US/mail/serious_mail_misconfiguration.tx b/templates/en_US/mail/serious_mail_misconfiguration.tx
new file mode 100644 (file)
index 0000000..4f7477c
--- /dev/null
@@ -0,0 +1,4 @@
+(NB: If you are a system administrator and have no idea what this
+message is talking about, this may indicate a serious mail system
+misconfiguration somewhere. Please contact <: $config.maintainer_email :>
+immediately.)
\ No newline at end of file
diff --git a/templates/en_US/mail/submitter_changed.tmpl b/templates/en_US/mail/submitter_changed.tmpl
deleted file mode 100644 (file)
index c7032f1..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-The submitter address recorded for your {$config{bug}} report
-#{$data{bug_num}}: {$data{subject}}
-has been changed.
-
-The old submitter address for this report was
-{$old_data{originator}}.
-
-The new submitter address is
-{$data{originator}}.
-
-This change was made by
-{$replyto}.
-If it was incorrect, please contact them directly.
diff --git a/templates/en_US/mail/submitter_changed.tx b/templates/en_US/mail/submitter_changed.tx
new file mode 100644 (file)
index 0000000..5920c0e
--- /dev/null
@@ -0,0 +1,13 @@
+The submitter address recorded for your <: $config.bug :> report
+#<: $data.bug_num :>: <:$data.subject:>
+has been changed.
+
+The old submitter address for this report was
+<: $old_data.originator :>.
+
+The new submitter address is
+<: $data.originator :>.
+
+This change was made by
+<: $replyto :>
+If it was incorrect, please contact them directly.
diff --git a/templates/en_US/mail/xdebbugscc.tmpl b/templates/en_US/mail/xdebbugscc.tmpl
deleted file mode 100644 (file)
index cc6e4d3..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-As you requested using X-Debbugs-CC, your message was also forwarded to
-  { $xcchdr }
-(after having been given a { $config{bug} } report number, if it did not have one).
diff --git a/templates/en_US/mail/xdebbugscc.tx b/templates/en_US/mail/xdebbugscc.tx
new file mode 100644 (file)
index 0000000..3641584
--- /dev/null
@@ -0,0 +1,4 @@
+
+As you requested using X-Debbugs-CC, your message was also forwarded to
+  <: $xcchdr :>
+(after having been given a <: $config.bug :> report number, if it did not have one).