]> git.donarmstrong.com Git - debbugs.git/commitdiff
* Move code from bugreport.cgi to Debbugs::CGI::Bugreport
authorDon Armstrong <don@donarmstrong.com>
Sat, 24 May 2008 12:46:52 +0000 (14:46 +0200)
committerDon Armstrong <don@donarmstrong.com>
Sat, 24 May 2008 12:46:52 +0000 (14:46 +0200)
 * Switch bugreport.cgi to using templates
 * Remove useless calls from pkgreport
 * Add new package_links and report_links commands to unify the
   package and bug linking
 * Delete extra copy of bugs.css
 * Fix the naming of the html_tail file
 * Use UNTAINT in Debbugs::Text
 * Remove useless prototypes in Debbugs::MIME
 * Tweak Debbugs::Config to allow empty $ENV{HOME}

18 files changed:
Debbugs/CGI.pm
Debbugs/CGI/Bugreport.pm
Debbugs/Common.pm
Debbugs/Config.pm
Debbugs/MIME.pm
Debbugs/Text.pm
cgi/bugreport.cgi
cgi/bugs.css [deleted file]
cgi/pkgreport.cgi
html/bugs.css
t/07_bugreport.t
templates/en_US/cgi/bugreport.tmpl [new file with mode: 0644]
templates/en_US/cgi/bugreport_buginfo.tmpl [new file with mode: 0644]
templates/en_US/cgi/bugreport_pkginfo.tmpl [new file with mode: 0644]
templates/en_US/html/html_tail [deleted file]
templates/en_US/html/html_tail.tmpl [new file with mode: 0644]
templates/en_US/html/post_title.tmpl [new file with mode: 0644]
templates/en_US/html/pre_title.tmpl [new file with mode: 0644]

index 86f82e7f100f460626cab2657a9a098163b4c008..e18891ab32c1a1882c4795548f03eb0050884534 100644 (file)
@@ -37,7 +37,7 @@ use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
 use base qw(Exporter);
 use Debbugs::URI;
 use HTML::Entities;
-use Debbugs::Common qw(getparsedaddrs);
+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);
@@ -45,6 +45,8 @@ use Mail::Address;
 use POSIX qw(ceil);
 use Storable qw(dclone);
 
+use Carp;
+
 use Debbugs::Text qw(fill_in_template);
 
 our %URL_PARAMS = ();
@@ -57,7 +59,8 @@ BEGIN{
      @EXPORT = ();
      %EXPORT_TAGS = (url    => [qw(bug_url bug_links bug_linklist maybelink),
                                qw(set_url_params pkg_url version_url),
-                               qw(submitterurl mainturl munge_url)
+                               qw(submitterurl mainturl munge_url),
+                               qw(package_links bug_links),
                               ],
                     html   => [qw(html_escape htmlize_bugs htmlize_packagelinks),
                                qw(maybelink htmlize_addresslinks htmlize_maintlinks),
@@ -284,158 +287,184 @@ sub quitcgi {
 
 =head HTML
 
-=head2 htmlize_bugs
+=head2 htmlize_packagelinks
 
-     htmlize_bugs({bug=>1,status=>\%status,extravars=>\%extra},{bug=>...}});
+     htmlize_packagelinks
 
-Turns a list of bugs into an html snippit of the bugs.
+Given a scalar containing a list of packages separated by something
+that L<Debbugs::CGI/splitpackages> can separate, returns a
+formatted set of links to packages.
 
 =cut
-#     htmlize_bugs(bugs=>[@bugs]);
-sub htmlize_bugs{
-     my @bugs = @_;
-     my @html;
-
-     for my $bug (@bugs) {
-         my $html = sprintf "<li><a href=\"%s\">#%d: %s</a>\n<br>",
-              bug_url($bug->{bug}), $bug->{bug}, html_escape($bug->{status}{subject});
-         $html .= htmlize_bugstatus($bug->{status}) . "\n";
-     }
-     return @html;
+
+sub htmlize_packagelinks {
+    my ($pkgs) = @_;
+    return '' unless defined $pkgs and $pkgs ne '';
+    my @pkglist = splitpackages($pkgs);
+
+    carp "htmlize_packagelinks is deprecated";
+
+    return 'Package' . (@pkglist > 1 ? 's' : '') . ': ' .
+           join(', ',
+                package_links(package =>\@pkglist,
+                             class   => 'submitter'
+                            )
+           );
 }
 
+=head2 package_links
 
-sub htmlize_bugstatus {
-     my %status = %{$_[0]};
+     join(', ', package_links(packages => \@packages))
 
-     my $result = "";
+Given a list of packages, return a list of html which links to the package
 
-     my $showseverity;
-     if  ($status{severity} eq $config{default_severity}) {
-         $showseverity = '';
-     } elsif (isstrongseverity($status{severity})) {
-         $showseverity = "Severity: <em class=\"severity\">$status{severity}</em>;\n";
-     } else {
-         $showseverity = "Severity: <em>$status{severity}</em>;\n";
-     }
+=over
 
-     $result .= htmlize_packagelinks($status{"package"}, 1);
+=item package -- arrayref or scalar of package(s)
 
-     my $showversions = '';
-     if (@{$status{found_versions}}) {
-         my @found = @{$status{found_versions}};
-         local $_;
-         s{/}{ } foreach @found;
-         $showversions .= join ', ', map html_escape($_), @found;
-     }
-     if (@{$status{fixed_versions}}) {
-         $showversions .= '; ' if length $showversions;
-         $showversions .= '<strong>fixed</strong>: ';
-         my @fixed = @{$status{fixed_versions}};
-         $showversions .= join ', ', map {s#/##; html_escape($_)} @fixed;
+=item submitter -- arrayref or scalar of submitter(s)
+
+=item source -- arrayref or scalar of source(s)
+
+=item maintainer -- arrayref or scalar of maintainer(s)
+
+=item links_only -- return only links, not htmlized links, defaults to
+returning htmlized links.
+
+=item class -- class of the a href, defaults to ''
+
+=back
+
+=cut
+
+sub package_links {
+     my %param = validate_with(params => \@_,
+                              spec   => {package => {type => SCALAR|ARRAYREF,
+                                                     optional => 1,
+                                                    },
+                                         source  => {type => SCALAR|ARRAYREF,
+                                                     optional => 1,
+                                                    },
+                                         maintainer => {type => SCALAR|ARRAYREF,
+                                                        optional => 1,
+                                                       },
+                                         submitter => {type => SCALAR|ARRAYREF,
+                                                       optional => 1,
+                                                      },
+                                         owner     => {type => SCALAR|ARRAYREF,
+                                                       optional => 1,
+                                                      },
+                                         links_only => {type => BOOLEAN,
+                                                        default => 0,
+                                                       },
+                                         class => {type => SCALAR,
+                                                   default => '',
+                                                  },
+                                         separator => {type => SCALAR,
+                                                       default => ', ',
+                                                      },
+                                        },
+                             );
+     my @links = ();
+     push @links, map {(pkg_url(source => $_),$_)
+                 } make_list($param{source}) if exists $param{source};
+     push @links, map {my $addr = getparsedaddrs($_);
+                      $addr = defined $addr?$addr->address:'';
+                      (pkg_url(maint => $addr),$_)
+                 } make_list($param{maintainer}) if exists $param{maintainer};
+     push @links, map {my $addr = getparsedaddrs($_);
+                      $addr = defined $addr?$addr->address:'';
+                      (pkg_url(owner => $addr),$_)
+                 } make_list($param{owner}) if exists $param{owner};
+     push @links, map {my $addr = getparsedaddrs($_);
+                      $addr = defined $addr?$addr->address:'';
+                      (pkg_url(submitter => $addr),$_)
+                 } make_list($param{submitter}) if exists $param{submitter};
+     push @links, map {(pkg_url(pkg => $_),
+                       html_escape($_))
+                 } make_list($param{package}) if exists $param{package};
+     my @return = ();
+     my ($link,$link_name);
+     my $class = '';
+     if (length $param{class}) {
+         $class = q( class=").html_escape($param{class}).q(");
      }
-     $result .= " ($showversions)" if length $showversions;
-     $result .= ";\n";
-
-     $result .= $showseverity;
-     $result .= htmlize_addresslinks("Reported by: ", \&submitterurl,
-                                $status{originator});
-     $result .= ";\nOwned by: " . html_escape($status{owner})
-         if length $status{owner};
-     $result .= ";\nTags: <strong>" 
-         . html_escape(join(", ", sort(split(/\s+/, $status{tags}))))
-              . "</strong>"
-                   if (length($status{tags}));
-
-     $result .= ";\nMerged with ".
-         bug_linklist(', ',
-                      'submitter',
-                      split(/ /,$status{mergedwith}))
-              if length $status{mergedwith};
-     $result .= ";\nBlocked by ".
-         bug_linklist(", ",
-                      'submitter',
-                      split(/ /,$status{blockedby}))
-              if length $status{blockedby};
-     $result .= ";\nBlocks ".
-         bug_linklist(", ",
-                      'submitter',
-                      split(/ /,$status{blocks})
-                     )
-              if length $status{blocks};
-
-     my $days = 0;
-     if (length($status{done})) {
-         $result .= "<br><strong>Done:</strong> " . html_escape($status{done});
-         $days = ceil($debbugs::gRemoveAge - -M buglog($status{id}));
-         if ($days >= 0) {
-              $result .= ";\n<strong>Will be archived" . ( $days == 0 ? " today" : $days == 1 ? " in $days day" : " in $days days" ) . "</strong>";
-         } else {
-              $result .= ";\n<strong>Archived</strong>";
+     while (($link,$link_name) = splice(@links,0,2)) {
+         if ($param{links_only}) {
+              push @return,$link
          }
+         else {
+              push @return,
+                   qq(<a$class href=").
+                        html_escape($link).q(">).
+                             html_escape($link_name).q(</a>);
+         }
+     }
+     if (wantarray) {
+         return @return;
      }
      else {
-         if (length($status{forwarded})) {
-              $result .= ";\n<strong>Forwarded</strong> to "
-                   . maybelink($status{forwarded});
-         }
-         my $daysold = int((time - $status{date}) / 86400);   # seconds to days
-         if ($daysold >= 7) {
-              my $font = "";
-              my $efont = "";
-              $font = "em" if ($daysold > 30);
-              $font = "strong" if ($daysold > 60);
-              $efont = "</$font>" if ($font);
-              $font = "<$font>" if ($font);
-
-              my $yearsold = int($daysold / 365);
-              $daysold -= $yearsold * 365;
-
-              $result .= ";\n $font";
-              my @age;
-              push @age, "1 year" if ($yearsold == 1);
-              push @age, "$yearsold years" if ($yearsold > 1);
-              push @age, "1 day" if ($daysold == 1);
-              push @age, "$daysold days" if ($daysold > 1);
-              $result .= join(" and ", @age);
-              $result .= " old$efont";
-        }
-    }
+         return join($param{separator},@return);
+     }
+}
 
-    $result .= ".";
+=head2 bug_links
 
-    return $result;
-}
+     join(', ', bug_links(bug => \@packages))
 
-=head2 htmlize_packagelinks
+Given a list of bugs, return a list of html which links to the bugs
 
-     htmlize_packagelinks
+=over
 
-Given a scalar containing a list of packages separated by something
-that L<Debbugs::CGI/splitpackages> can separate, returns a
-formatted set of links to packages.
+=item bug -- arrayref or scalar of bug(s)
 
-=cut
+=item links_only -- return only links, not htmlized links, defaults to
+returning htmlized links.
 
-sub htmlize_packagelinks {
-    my ($pkgs,$strong) = @_;
-    return unless defined $pkgs and $pkgs ne '';
-    my @pkglist = splitpackages($pkgs);
+=item class -- class of the a href, defaults to ''
 
-    $strong = 0;
-    my $openstrong  = $strong ? '<strong>' : '';
-    my $closestrong = $strong ? '</strong>' : '';
+=back
 
-    return 'Package' . (@pkglist > 1 ? 's' : '') . ': ' .
-           join(', ',
-                map {
-                    '<a class="submitter" href="' . pkg_url(pkg=>$_||'') . '">' .
-                    $openstrong . html_escape($_) . $closestrong . '</a>'
-                } @pkglist
-           );
+=cut
+
+sub bug_links {
+     my %param = validate_with(params => \@_,
+                              spec   => {bug => {type => SCALAR|ARRAYREF,
+                                                 optional => 1,
+                                                },
+                                         links_only => {type => BOOLEAN,
+                                                        default => 0,
+                                                       },
+                                         class => {type => SCALAR,
+                                                   default => '',
+                                                  },
+                                        },
+                             );
+     my @links;
+     push @links, map {(bug_url($_),$_)
+                 } make_list($param{bug}) if exists $param{bug};
+     my @return;
+     my ($link,$link_name);
+     my $class = '';
+     if (length $param{class}) {
+         $class = q( class=").html_escape($param{class}).q(");
+     }
+     while (($link,$link_name) = splice(@links,0,2)) {
+         if ($param{links_only}) {
+              push @return,$link
+         }
+         else {
+              push @return,
+                   qq(<a$class href=").
+                        html_escape($link).q(">).
+                             html_escape($link_name).q(</a>);
+         }
+     }
+     return @return;
 }
 
 
+
 =head2 maybelink
 
      maybelink($in);
@@ -487,6 +516,8 @@ or submitterurl which returns the URL for each individual address.
 
 sub htmlize_addresslinks {
      my ($prefixfunc, $urlfunc, $addresses,$class) = @_;
+     carp "htmlize_addresslinks is deprecated";
+
      $class = defined $class?qq(class="$class" ):'';
      if (defined $addresses and $addresses ne '') {
          my @addrs = getparsedaddrs($addresses);
@@ -520,6 +551,7 @@ sub mainturl { pkg_url(maint => emailfromrfc822($_[0])); }
 sub submitterurl { pkg_url(submitter => emailfromrfc822($_[0])); }
 sub htmlize_maintlinks {
     my ($prefixfunc, $maints) = @_;
+    carp "htmlize_maintlinks is deprecated";
     return htmlize_addresslinks($prefixfunc, \&mainturl, $maints);
 }
 
@@ -527,33 +559,6 @@ sub htmlize_maintlinks {
 our $_maintainer;
 our $_maintainer_rev;
 
-=head2 bug_links
-
-     bug_links($one_bug);
-     bug_links($starting_bug,$stoping_bugs,);
-
-Creates a set of links to bugs, starting with bug number
-$starting_bug, and finishing with $stoping_bug; if only one bug is
-passed, makes a link to only a single bug.
-
-The content of the link is the bug number.
-
-XXX Use L<Params::Validate>; we want to be able to support query
-arguments here too.
-
-=cut
-
-sub bug_links{
-     my ($start,$stop,$query_arguments) = @_;
-     $stop = $stop || $start;
-     $query_arguments ||= '';
-     my @output;
-     for my $bug ($start..$stop) {
-         push @output,'<a href="'.bug_url($bug,'').qq(">$bug</a>);
-     }
-     return join(', ',@output);
-}
-
 =head2 bug_linklist
 
      bug_linklist($separator,$class,@bugs)
@@ -571,12 +576,7 @@ too.]
 
 sub bug_linklist{
      my ($sep,$class,@bugs) = @_;
-     if (length $class) {
-         $class = qq(class="$class" );
-     }
-     return join($sep,map{qq(<a ${class}href=").
-                              bug_url($_).qq(">#$_</a>)
-                         } @bugs);
+     return join($sep,bug_links(bug=>\@bugs,class=>$class));
 }
 
 
index 28bc63f771efaf97759e620055c38affc1ae8e77..85dc3b98bae04f8ddcd3a2f08f6b1750ba1c818b 100644 (file)
@@ -31,6 +31,10 @@ use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
 use base qw(Exporter);
 
 use IO::Scalar;
+use Params::Validate qw(validate_with :types);
+use Debbugs::MIME qw(convert_to_utf8 decode_rfc1522 create_mime_message);
+use Debbugs::CGI qw(:url :html :util);
+use POSIX qw(strftime);
 
 BEGIN{
      ($VERSION) = q$Revision: 494 $ =~ /^Revision:\s+([^\s+])/;
@@ -74,40 +78,43 @@ BEGIN{
 =cut
 
 sub display_entity {
-    my %param = valid_with(params => \@_,
-                          spec   => {entity      => {type => OBJECT,
-                                                    },
-                                     bug_num     => {type => SCALAR,
-                                                     regex => qr/^\d+$/,
-                                                    },
-                                     outer       => {type => BOOLEAN,
-                                                     default => 1,
-                                                     },
-                                     msg_num     => {type => SCALAR,
-                                                    },
-                                     attachments => {type => ARRAYREF,
-                                                     default => [],
-                                                    },
-                                     output      => {type => SCALARREF|HANDLE,
-                                                     default => \*STDOUT,
-                                                    },
-                                     terse       => {type => BOOLEAN,
-                                                     default => 0,
-                                                    },
-                                     msg         => {type => SCALAR,
-                                                     optional => 1,
-                                                    },
-                                     attachment => {type => SCALAR,
-                                                    optional => 1,
-                                                   },
-                                    }
-                         );
+    my %param = validate_with(params => \@_,
+                             spec   => {entity      => {type => OBJECT,
+                                                       },
+                                        bug_num     => {type => SCALAR,
+                                                        regex => qr/^\d+$/,
+                                                       },
+                                        outer       => {type => BOOLEAN,
+                                                        default => 1,
+                                                       },
+                                        msg_num     => {type => SCALAR,
+                                                       },
+                                        attachments => {type => ARRAYREF,
+                                                        default => [],
+                                                       },
+                                        output      => {type => SCALARREF|HANDLE,
+                                                        default => \*STDOUT,
+                                                       },
+                                        terse       => {type => BOOLEAN,
+                                                        default => 0,
+                                                       },
+                                        msg         => {type => SCALAR,
+                                                        optional => 1,
+                                                       },
+                                        att         => {type => SCALAR,
+                                                        optional => 1,
+                                                       },
+                                        trim_headers => {type => BOOLEAN,
+                                                         default => 1,
+                                                        },
+                                       }
+                            );
 
     my $entity = $param{entity};
     my $ref = $param{bug_num};
-    my $top = $param{outer}
+    my $top = $param{outer};
     my $xmessage = $param{msg_num};
-    if (defined ref($options) and
+    if (defined ref($param{output}) and
        ref($param{output}) eq 'SCALAR' and
        not UNIVERSAL::isa($param{output},'GLOB')) {
         $param{output} = IO::Scalar->new($param{output});
@@ -125,7 +132,7 @@ sub display_entity {
     if ($top and not $param{terse}) {
         my $header = $entity->head;
         print {$param{output}} "<pre class=\"headers\">\n";
-        if ($trim_headers) {
+        if ($param{trim_headers}) {
              my @headers;
              foreach (qw(From To Cc Subject Date)) {
                   my $head_field = $head->get($_);
@@ -150,7 +157,7 @@ sub display_entity {
                  "($type, $disposition)]</pre>\n";
 
        if (exists $param{msg} and exists $param{att} and
-           $att == $#$attachments) {
+           $param{att} == $#$attachments) {
            my $head = $entity->head;
            chomp(my $type = $entity->effective_type);
            my $body = $entity->stringify_body;
@@ -171,7 +178,7 @@ sub display_entity {
        }
     }
 
-    return if not $top and $disposition eq 'attachment' and not defined($att);
+    return if not $top and $disposition eq 'attachment' and not defined($param{att});
     return unless ($type =~ m[^text/?] and
                   $type !~ m[^text/(?:html|enriched)(?:;|$)]) or
                  $type =~ m[^application/pgp(?:;|$)] or
@@ -223,9 +230,11 @@ sub display_entity {
              # flowed e-mails cause they don't really matter.
         }
         # Add links to URLs
-        # We don't html escape here because we escape above
-        $body =~ s{((ftp|http|https)://[\S~-]+?/?)((\&gt\;)?[)]?[']?[:.\,]?(\s|$))}
-                  {<a href=\"$1\">$1</a>$3}go;
+        # We don't html escape here because we escape above;
+        # wierd terminators are because of that
+        $body =~ s{((?:ftp|http|https|svn|ftps|rsync)://[\S~-]+?/?) # Url
+                   ((?:\&gt\;)?[)]?(?:'|\&\#39\;)?[:.\,]?(?:\s|$)) # terminators
+             }{<a href=\"$1\">$1</a>$2}gox;
         # Add links to bug closures
         $body =~ s[(closes:\s*(?:bug)?\#?\s?\d+(?:,?\s*(?:bug)?\#?\s?\d+)*)]
                   [my $temp = $1;
@@ -244,7 +253,7 @@ sub display_entity {
 
      handle_email_message($record->{text},
                          ref        => $bug_number,
-                         msg_number => $msg_number,
+                         msg_num => $msg_number,
                         );
 
 Returns a decoded e-mail message and displays entities/attachments as
@@ -254,7 +263,7 @@ appropriate.
 =cut
 
 sub handle_email_message{
-     my ($email,%options) = @_;
+     my ($email,%param) = @_;
 
      my $output = '';
      my $parser = new MIME::Parser;
@@ -265,12 +274,12 @@ sub handle_email_message{
      my $entity = $parser->parse_data( $email);
      my @attachments = ();
      display_entity(entity  => $entity,
-                   bug_num => $options{ref},
+                   bug_num => $param{ref},
                    outer   => 1,
-                   msg_number => $options{msg_number},
-                   ouput => $output,
+                   msg_num => $param{msg_num},
+                   output => \$output,
                    attachments => \@attachments,
-                   terse       => $params{terse},
+                   terse       => $param{terse},
                    exists $param{msg}?(msg=>$param{msg}):(),
                    exists $param{att}?(attachment=>$param{att}):(),
                   );
@@ -301,21 +310,21 @@ sub handle_record{
          # (even though these links already exist at the top)
          $output =~ s,((?:ftp|http|https)://[\S~-]+?/?)([\)\'\:\.\,]?(?:\s|\.<|$)),<a href=\"$1\">$1</a>$2,go;
          # Add links to the cloned bugs
-         $output =~ s{(Bug )(\d+)( cloned as bugs? )(\d+)(?:\-(\d+)|)}{$1.bug_links($2).$3.bug_links($4,$5)}eo;
+         $output =~ s{(Bug )(\d+)( cloned as bugs? )(\d+)(?:\-(\d+)|)}{$1.bug_links(bug=>$2).$3.bug_links(bug=>[$4..$5])}eo;
          # Add links to merged bugs
-         $output =~ s{(?<=Merged )([\d\s]+)(?=\.)}{join(' ',map {bug_links($_)} (split /\s+/, $1))}eo;
+         $output =~ s{(?<=Merged )([\d\s]+)(?=\.)}{join(' ',map {bug_links(bug=>$_)} (split /\s+/, $1))}eo;
          # Add links to blocked bugs
          $output =~ s{(?<=Blocking bugs)(?:( of )(\d+))?( (?:added|set to|removed):\s+)([\d\s\,]+)}
-                     {(defined $2?$1.bug_links($2):'').$3.
-                           join(' ',map {bug_links($_)} (split /\,?\s+/, $4))}eo;
+                     {(defined $2?$1.bug_links(bug=>$2):'').$3.
+                           join(' ',map {bug_links(bug=>$_)} (split /\,?\s+/, $4))}eo;
          # Add links to reassigned packages
          $output =~ s{(Bug reassigned from package \`)([^']+?)((?:'|\&\#39;) to \`)([^']+?)((?:'|\&\#39;))}
          {$1.q(<a href=").html_escape(pkg_url(pkg=>$2)).qq(">$2</a>).$3.q(<a href=").html_escape(pkg_url(pkg=>$4)).qq(">$4</a>).$5}eo;
          if (defined $time) {
               $output .= ' ('.strftime('%a, %d %b %Y %T GMT',gmtime($time)).') ';
          }
-         $output .= '<a href="' . html_escape(bug_url($ref, msg => ($msg_number+1))) . '">Full text</a> and <a href="' .
-              html_escape(bug_url($ref, msg => ($msg_number+1), mbox => 'yes')) . '">rfc822 format</a> available.';
+         $output .= '<a href="' . html_escape(bug_url($bug_number, msg => ($msg_number+1))) . '">Full text</a> and <a href="' .
+              html_escape(bug_url($bug_number, msg => ($msg_number+1), mbox => 'yes')) . '">rfc822 format</a> available.';
 
          $output = qq(<div class="$class"><hr>\n<a name="$msg_number"></a>\n) . $output . "</div>\n";
      }
@@ -328,11 +337,11 @@ sub handle_record{
               $$seen_msg_ids{$msg_id} = 1;
          }
          $output .= qq(<hr><p class="msgreceived"><a name="$msg_number"></a>\n);
-         $output .= 'View this message in <a href="' . html_escape(bug_url($ref, msg=>$msg_number, mbox=>'yes')) . '">rfc822 format</a></p>';
+         $output .= 'View this message in <a href="' . html_escape(bug_url($bug_number, msg=>$msg_number, mbox=>'yes')) . '">rfc822 format</a></p>';
          $output .= handle_email_message($record->{text},
-                                   ref        => $bug_number,
-                                   msg_number => $msg_number,
-                                  );
+                                         ref     => $bug_number,
+                                         msg_num => $msg_number,
+                                        );
      }
      elsif (/autocheck/) {
          # Do nothing
@@ -349,12 +358,12 @@ sub handle_record{
          my ($received,$hostname) = $record->{text} =~ m/Received: \(at (\S+)\) by (\S+)\;/;
          $output .= qq|<hr><p class="msgreceived"><a name="$msg_number"></a><a name="msg$msg_number"></a><a href="#$msg_number">Message #$msg_number</a> received at |.
               html_escape("$received\@$hostname") .
-                   q| (<a href="| . html_escape(bug_url($ref, msg=>$msg_number)) . '">full text</a>'.
-                        q|, <a href="| . html_escape(bug_url($ref, msg=>$msg_number,mbox=>'yes')) .'">mbox</a>)'.":</p>\n";
+                   q| (<a href="| . html_escape(bug_url($bug_number, msg=>$msg_number)) . '">full text</a>'.
+                        q|, <a href="| . html_escape(bug_url($bug_number, msg=>$msg_number,mbox=>'yes')) .'">mbox</a>)'.":</p>\n";
          $output .= handle_email_message($record->{text},
-                                   ref        => $bug_number,
-                                   msg_number => $msg_number,
-                                  );
+                                         ref     => $bug_number,
+                                         msg_num => $msg_number,
+                                        );
      }
      else {
          die "Unknown record type $_";
index bb42bf8b207c171f240c48779a3c18b680124ddc..8d837291274afee68326b54a2ca1cab4b98364ce 100644 (file)
@@ -430,7 +430,7 @@ instead. (Or possibly a die handler, if the cleanups are important)
 =cut
 
 sub quit {
-    print $DEBUG_FH "quitting >$_[0]<\n" if $DEBUG;
+    print {$DEBUG_FH} "quitting >$_[0]<\n" if $DEBUG;
     my ($u);
     while ($u= $cleanups[$#cleanups]) { &$u; }
     die "*** $_[0]\n";
index 895b799f7c8e0c7c20a53f70360df4d52e51f455..5c3e6439523ca4185f0fafa56b523ce1f88c6317 100644 (file)
@@ -67,7 +67,7 @@ BEGIN {
                                 qw(@gDefaultArchitectures),
                                 qw($gTemplateDir),
                                 qw($gDefaultPackage),
-                                qw($gSpamMaxThreads $gSpamSpamsPerThread $gSpamKeepRunning $gSpamScan $gSpamCrossassassinDb)
+                                qw($gSpamMaxThreads $gSpamSpamsPerThread $gSpamKeepRunning $gSpamScan $gSpamCrossassassinDb),
                                ],
                     text     => [qw($gBadEmailPrefix $gHTMLTail $gHTMLExpireNote),
                                 ],
@@ -76,6 +76,7 @@ BEGIN {
      @EXPORT_OK = ();
      Exporter::export_ok_tags(qw(globals text config));
      $EXPORT_TAGS{all} = [@EXPORT_OK];
+     $ENV{HOME} = '' if not defined $ENV{HOME};
 }
 
 use File::Basename qw(dirname);
@@ -729,7 +730,6 @@ Site rules directory for spamassassin, defaults to
 
 set_default(\%config,'spam_rules_dir','/usr/share/spamassassin');
 
-
 =back
 
 
index 183adc7df072bb732155b1c022639f676cc5c3af..2a695e5859a96a506cceac22c7abba40df44e51b 100644 (file)
@@ -215,8 +215,7 @@ BEGIN {
        ]));
 }
 
-sub decode_rfc1522 ($)
-{
+sub decode_rfc1522 {
     my ($string) = @_;
 
     # this is craptacular, but leading space is hacked off by unmime.
@@ -240,7 +239,7 @@ MIME::Words::encode_mimeword on distinct words as appropriate.
 # We cannot use MIME::Words::encode_mimewords because that function
 # does not handle spaces properly at all.
 
-sub encode_rfc1522 ($) {
+sub encode_rfc1522 {
      my ($rawstr) = @_;
 
      # handle being passed undef properly
index 0f3a5299a226d8647e07aa97d54d3f59de5faf3c..c49981411eb8a7ed1f502896a7d7aaa6dea0e344 100644 (file)
@@ -16,8 +16,8 @@ Debbugs::Text -- General routines for text templates
 
 =head1 SYNOPSIS
 
-use Debbugs::Text qw(:templates);
-print fill_in_template(template => 'cgi/foo');
+ use Debbugs::Text qw(:templates);
+ print fill_in_template(template => 'cgi/foo');
 
 =head1 DESCRIPTION
 
@@ -164,6 +164,7 @@ sub fill_in_template{
                             qw(padsv padav padhv padany),
                             qw(rv2gv refgen srefgen ref),
                             qw(caller require entereval),
+                            qw(gmtime sprintf prtf),
                            );
          $safe->share('*STDERR');
          $safe->share('%config');
@@ -191,7 +192,7 @@ sub fill_in_template{
      my $tt;
      if ($tt_type eq 'FILE' and
         defined $tt_templates{$tt_source} and
-        (stat $tt_source)[9] > $tt_templates{$tt_source}{mtime}
+        (stat $tt_source)[9] <= $tt_templates{$tt_source}{mtime}
        ) {
          $tt = $tt_templates{$tt_source}{template};
      }
@@ -202,6 +203,7 @@ sub fill_in_template{
          }
          $tt = Text::Template->new(TYPE => $tt_type,
                                    SOURCE => $tt_source,
+                                   UNTAINT => 1,
                                   );
          if ($tt_type eq 'FILE') {
               $tt_templates{$tt_source}{template} = $tt;
@@ -210,10 +212,7 @@ sub fill_in_template{
      if (not defined $tt) {
          die "Unable to create Text::Template for $tt_type:$tt_source";
      }
-     my $ret = $tt->fill_in(#(defined $param{nosafe} and $param{nosafe})?():(HASH=>$param{variables}),
-                           #(defined $param{nosafe} and $param{nosafe})?():(SAFE=>$safe),
-                           SAFE => $safe,
-                           #(defined $param{nosafe} and $param{nosafe})?(PACKAGE => 'main'):(),
+     my $ret = $tt->fill_in(SAFE => $safe,
                            defined $param{output}?(OUTPUT=>$param{output}):(),
                           );
      if (not defined $ret) {
index dcb6482345f984479a7e20499232cb6e0d60c239..28c78249e89b10c2c5fd924c07e18936fe819a9f 100755 (executable)
@@ -3,7 +3,7 @@
 use warnings;
 use strict;
 
-use POSIX qw(strftime tzset);
+use POSIX qw(strftime);
 use MIME::Parser;
 use MIME::Decoder;
 use IO::Scalar;
@@ -13,7 +13,6 @@ use Debbugs::Config qw(:globals :text);
 
 # for read_log_records
 use Debbugs::Log qw(read_log_records);
-use Debbugs::MIME qw(convert_to_utf8 decode_rfc1522 create_mime_message);
 use Debbugs::CGI qw(:url :html :util);
 use Debbugs::CGI::Bugreport qw(:all);
 use Debbugs::Common qw(buglog getmaintainers);
@@ -21,6 +20,9 @@ use Debbugs::Packages qw(getpkgsrc);
 use Debbugs::Status qw(splitpackages get_bug_status isstrongseverity);
 
 use Scalar::Util qw(looks_like_number);
+
+use Debbugs::Text qw(:templates);
+
 use CGI::Simple;
 my $q = new CGI::Simple;
 
@@ -44,14 +46,12 @@ my %param = cgi_parameters(query => $q,
                          );
 # This is craptacular.
 
-my $tail_html;
-
 my $ref = $param{bug} or quitcgi("No bug number");
 $ref =~ /(\d+)/ or quitcgi("Invalid bug number");
 $ref = $1;
 my $short = "#$ref";
-my $msg = $param{'msg'};
-my $att = $param{'att'};
+my ($msg) = $param{msg} =~ /^\d+$/ if exists $param{msg};
+my ($att) = $param{att} =~ /^\d+$/ if exists $param{att};
 my $boring = $param{'boring'} eq 'yes';
 my $terse = $param{'terse'} eq 'yes';
 my $reverse = $param{'reverse'} eq 'yes';
@@ -71,16 +71,18 @@ my $archive = $param{'archive'} eq 'yes';
 my $repeatmerged = $param{'repeatmerged'} eq 'yes';
 
 my $buglog = buglog($ref);
+my @stat = stat $buglog;
+my $mtime = '';
+if (@stat) {
+     $mtime = strftime '%a, %d %b %Y %T GMT', gmtime($stat[9]);
+}
 
-if (defined $ENV{REQUEST_METHOD} and $ENV{REQUEST_METHOD} eq 'HEAD' and not defined($att) and not $mbox) {
-    print "Content-Type: text/html; charset=utf-8\n";
-    my @stat = stat $buglog;
-    if (@stat) {
-       my $mtime = strftime '%a, %d %b %Y %T GMT', gmtime($stat[9]);
-       print "Last-Modified: $mtime\n";
-    }
-    print "\n";
-    exit 0;
+if ($q->request_method() eq 'HEAD' and not defined($att) and not $mbox) {
+     print $q->header(-type => "text/html",
+                     -charset => 'utf-8',
+                     (length $mtime)?(-last_modified => $mtime):(),
+                    );
+     exit 0;
 }
 
 
@@ -88,13 +90,15 @@ my $buglogfh;
 if ($buglog =~ m/\.gz$/) {
     my $oldpath = $ENV{'PATH'};
     $ENV{'PATH'} = '/bin:/usr/bin';
-    $buglogfh = new IO::File "zcat $buglog |" or &quitcgi("open log for $ref: $!");
+    $buglogfh = IO::File->new("zcat $buglog |") or quitcgi("open log for $ref: $!");
     $ENV{'PATH'} = $oldpath;
 } else {
-    $buglogfh = new IO::File "<$buglog" or &quitcgi("open log for $ref: $!");
+    $buglogfh = IO::File->new($buglog,'r') or quitcgi("open log for $ref: $!");
 }
 
 
+my %status = %{get_bug_status(bug=>$ref)};
+
 my @records;
 eval{
      @records = read_log_records($buglogfh);
@@ -211,218 +215,104 @@ my $tpack;
 my $tmain;
 
 my $dtime = strftime "%a, %e %b %Y %T UTC", gmtime;
-$tail_html = $gHTMLTail;
-$tail_html =~ s/SUBSTITUTE_DTIME/$dtime/;
 
-my %status = %{get_bug_status(bug=>$ref)};
 unless (%status) {
-    print "Content-Type: text/html; charset=utf-8\n\n";
+    print $q->header(-type => "text/html",
+                    -charset => 'utf-8',
+                    (length $mtime)?(-last_modified => $mtime):(),
+                   );
     print fill_in_template(template=>'cgi/no_such_bug',
                           variables => {modify_time => $dtime,
                                         bug_num     => $ref,
                                        },
-                         )
+                         );
     exit 0;
 }
 
-$|=1;
+#$|=1;
 
-$tpack = lc $status{'package'};
-my @tpacks = splitpackages($tpack);
+my %package;
+my @packages = splitpackages($status{package});
 
-if  ($status{severity} eq 'normal') {
-       $showseverity = '';
-} elsif (isstrongseverity($status{severity})) {
-       $showseverity = "Severity: <em class=\"severity\">$status{severity}</em>;\n";
-} else {
-       $showseverity = "Severity: $status{severity};\n";
+foreach my $pkg (@packages) {
+     $package{$pkg} = {maintainer => exists($maintainer{$pkg}) ? $maintainer{$pkg} : '(unknown)',
+                      source     => exists($pkgsrc{$pkg}) ? $pkgsrc{$pkg} : '(unknown)',
+                      package    => $pkg,
+                     };
 }
 
+# fixup various bits of the status
+$status{tags_array} = [sort(split(/\s+/, $status{tags}))];
+$status{date_text} = strftime('%a, %e %b %Y %T UTC', gmtime($status{date}));
+$status{mergedwith_array} = [split(/ /,$status{mergedwith})];
+
+
+my $version_graph = '';
 if (@{$status{found_versions}} or @{$status{fixed_versions}}) {
-     $indexentry.= q(<div style="float:right"><a href=").
+     $version_graph = q(<a href=").
          html_escape(version_url(package => $status{package},
                                  found => $status{found_versions},
                                  fixed => $status{fixed_versions},
-                                )).
+                                )
+                    ).
          q("><img alt="version graph" src=").
-              html_escape(version_url(package => $status{package},
-                                      found => $status{found_versions},
-                                      fixed => $status{fixed_versions},
-                                      width => 2,
-                                      height => 2,
-                                     )).qq{"></a></div>};
-}
-
-
-$indexentry .= "<div class=\"msgreceived\">\n";
-$indexentry .= htmlize_packagelinks($status{package}, 0) . ";\n";
-
-foreach my $pkg (@tpacks) {
-    my $tmaint = defined($maintainer{$pkg}) ? $maintainer{$pkg} : '(unknown)';
-    my $tsrc = defined($pkgsrc{$pkg}) ? $pkgsrc{$pkg} : '(unknown)';
-
-    $indexentry .=
-            htmlize_maintlinks(sub { $_[0] == 1 ? "Maintainer for $pkg is\n"
-                                            : "Maintainers for $pkg are\n" },
-                           $tmaint);
-    $indexentry .= ";\nSource for $pkg is\n".
-            '<a href="'.html_escape(pkg_url(src=>$tsrc))."\">$tsrc</a>" if ($tsrc ne "(unknown)");
-    $indexentry .= ".\n";
-}
-
-$indexentry .= "<br>";
-$indexentry .= htmlize_addresslinks("Reported by: ", \&submitterurl,
-                                $status{originator}) . ";\n";
-$indexentry .= sprintf "Date: %s.\n",
-               (strftime "%a, %e %b %Y %T UTC", localtime($status{date}));
-
-$indexentry .= "<br>Owned by: " . html_escape($status{owner}) . ".\n"
-              if length $status{owner};
-
-$indexentry .= "</div>\n";
-
-my @descstates;
-
-$indexentry .= "<h3>$showseverity";
-$indexentry .= sprintf "Tags: %s;\n", 
-               html_escape(join(", ", sort(split(/\s+/, $status{tags}))))
-                       if length($status{tags});
-$indexentry .= "<br>" if (length($showseverity) or length($status{tags}));
-
-my @merged= split(/ /,$status{mergedwith});
-if (@merged) {
-       my $descmerged = 'Merged with ';
-       my $mseparator = '';
-       for my $m (@merged) {
-               $descmerged .= $mseparator."<a href=\"" . html_escape(bug_url($m)) . "\">#$m</a>";
-               $mseparator= ",\n";
-       }
-       push @descstates, $descmerged;
-}
-
-if (@{$status{found_versions}}) {
-    my $foundtext = 'Found in ';
-    $foundtext .= (@{$status{found_versions}} == 1) ? 'version ' : 'versions ';
-    $foundtext .= join ', ', map html_escape($_), @{$status{found_versions}};
-    push @descstates, $foundtext;
-}
-if (@{$status{fixed_versions}}) {
-    my $fixedtext = '<strong>Fixed</strong> in ';
-    $fixedtext .= (@{$status{fixed_versions}} == 1) ? 'version ' : 'versions ';
-    $fixedtext .= join ', ', map html_escape($_), @{$status{fixed_versions}};
-    if (length($status{done})) {
-       $fixedtext .= ' by ' . html_escape(decode_rfc1522($status{done}));
-    }
-    push @descstates, $fixedtext;
-}
-
-if (@{$status{found_versions}} or @{$status{fixed_versions}}) {
-     push @descstates, '<a href="'.
-         html_escape(version_url($status{package},
-                                 $status{found_versions},
-                                 $status{fixed_versions},
-                                )).qq{">Version Graph</a>};
-}
-
-if (length($status{done})) {
-    push @descstates, "<strong>Done:</strong> ".html_escape(decode_rfc1522($status{done}));
+         html_escape(version_url(package => $status{package},
+                                 found => $status{found_versions},
+                                 fixed => $status{fixed_versions},
+                                 width => 2,
+                                 height => 2,
+                                )
+                    ).
+         qq{"></a>};
 }
 
-if (length($status{forwarded})) {
-    my $forward_link = html_escape($status{forwarded});
-    $forward_link =~ s,((ftp|http|https)://[\S~-]+?/?)((\&gt\;)?[)]?[']?[:.\,]?(\s|$)),<a href="$1">$1</a>$3,go;
-    push @descstates, "<strong>Forwarded</strong> to $forward_link";
-}
 
 
 my @blockedby= split(/ /, $status{blockedby});
+$status{blockedby_array} = [];
 if (@blockedby && $status{"pending"} ne 'fixed' && ! length($status{done})) {
     for my $b (@blockedby) {
         my %s = %{get_bug_status($b)};
         next if $s{"pending"} eq 'fixed' || length $s{done};
-        push @descstates, "Fix blocked by <a href=\"" . html_escape(bug_url($b)) . "\">#$b</a>: ".html_escape($s{subject});
-    }
+       push @{$status{blockedby_array}},{bug_num => $b, subject => $s{subject}, status => \%s};
+   }
 }
 
 my @blocks= split(/ /, $status{blocks});
+$status{blocks_array} = [];
 if (@blocks && $status{"pending"} ne 'fixed' && ! length($status{done})) {
     for my $b (@blocks) {
         my %s = %{get_bug_status($b)};
         next if $s{"pending"} eq 'fixed' || length $s{done};
-        push @descstates, "Blocking fix for <a href=\"" . html_escape(bug_url($b)) . "\">#$b</a>: ".html_escape($s{subject});
+       push @{$status{blocks_array}}, {bug_num => $b, subject => $s{subject}, status => \%s};
     }
 }
 
 if ($buglog !~ m#^\Q$gSpoolDir/db#) {
-    push @descstates, "Bug is archived. No further changes may be made";
+     $status{archived} = 1;
 }
 
-$indexentry .= join(";\n<br>", @descstates) . ".\n" if @descstates;
-$indexentry .= "</h3>\n";
-
 my $descriptivehead = $indexentry;
 
-print "Content-Type: text/html; charset=utf-8\n";
-
-my @stat = stat $buglog;
-if (@stat) {
-     my $mtime = strftime '%a, %d %b %Y %T GMT', gmtime($stat[9]);
-     print "Last-Modified: $mtime\n";
-}
-
-print "\n";
-
-my $title = html_escape($status{subject});
-
-my $dummy2 = $gWebHostBugDir;
-
-print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
-print <<END;
-<HTML><HEAD>
-<TITLE>$short - $title - $gProject $gBug report logs</TITLE>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
-<link rel="stylesheet" href="$gWebHostBugDir/css/bugs.css" type="text/css">
-<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>
-END
-print "<H1>" . "$gProject $gBug report logs - <A HREF=\"mailto:$ref\@$gEmailDomain\">$short</A>" .
-      "<BR>" . $title . "</H1>\n";
-print "$descriptivehead\n";
-
-if (looks_like_number($msg)) {
-     printf qq(<p><a href="%s">Full log</a></p>),html_escape(bug_url($ref));
-}
-else {
-     print qq(<p><a href="mailto:$ref\@$gEmailDomain">Reply</a> ),
-         qq(or <a href="mailto:$ref-subscribe\@$gEmailDomain">subscribe</a> ),
-              qq(to this bug.</p>\n);
-     print qq(<p><a href="javascript:toggle_infmessages();">Toggle useless messages</a></p>);
-     printf 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_url($ref, mbox=>'yes')),
-                   html_escape(bug_url($ref, mbox=>'yes',mboxstatus=>'yes')),
-                        html_escape(bug_url($ref, mbox=>'yes',mboxmaint=>'yes'));
-}
-print "$log";
-print "<HR>";
-print "<p class=\"msgreceived\">Send a report that <a href=\"/cgi-bin/bugspam.cgi?bug=$ref\">this bug log contains spam</a>.</p>\n<HR>\n";
-print $tail_html;
-
-print "</BODY></HTML>\n";
-
-exit 0;
+print $q->header(-type => "text/html",
+                -charset => 'utf-8',
+                (length $mtime)?(-last_modified => $mtime):(),
+               );
+
+print fill_in_template(template => 'cgi/bugreport',
+                      variables => {status => \%status,
+                                    package => \%package,
+                                    log           => $log,
+                                    bug_num       => $ref,
+                                    version_graph => $version_graph,
+                                    isstrongseverity => \&Debbugs::Status::isstrongseverity,
+                                    html_escape   => \&Debbugs::CGI::html_escape,
+                                    looks_like_number => \&Scalar::Util::looks_like_number,
+                                   },
+                      hole_var  => {'&package_links' => \&Debbugs::CGI::package_links,
+                                    '&bug_links'     => \&Debbugs::CGI::bug_links,
+                                    '&version_url'   => \&Debbugs::CGI::version_url,
+                                    '&bug_url'       => \&Debbugs::CGI::bug_url,
+                                    '&strftime'      => \&POSIX::strftime,
+                                   }
+                     );
diff --git a/cgi/bugs.css b/cgi/bugs.css
deleted file mode 100644 (file)
index ed42581..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-html {
-    color: #000; 
-    background: #fefefe;
-    font-family: serif;
-    margin: 1em;
-    border: 0;
-    padding: 0;
-    line-height: 120%;
-}
-
-body {
-    margin: 0;
-    border: 0;
-    padding: 0;
-}
-
-h1, h2, h3 {
-    text-align: left; 
-    font-family: sans-serif;
-}
-
-h1 {
-    font-size: 150%;
-    line-height: 150%;
-}
-
-h2 {
-    font-size: 130%;
-}
-
-h3 {
-    font-size: 100%;
-}
-
-a:link {
-    color: #1b56ce;
-    font-weight: bold;
-}
-
-a:visited {
-    color:#1b56ce;
-}
-
-a:link:active, a:link:visited {
-    color:#ff0000;
-}
-
-a:link:hover, a:visited:hover {
-    color: #d81e1e;
-}
-
-a.submitter:link {
-    color: #242424;
-    font-family: sans-serif;
-    font-size: 95%;
-    text-decoration: underline;
-    font-weight: normal;
-}
-
-a.submitter:visited, a.submitter:active {
-    color: #6e6e6e;
-    font-family: sans-serif;
-    font-size: 95%;
-}
-
-a.submitter:hover, a.submitter:visited:hover {
-    color: #d01414;
-    font-family: sans-serif;
-    font-size: 95%;
-}
-
-pre.message {
-    font-family: monospace;
-    padding-top: 0;
-    margin-top: 0;
-    border-top: 0;
-}
-
-.sparse li {
-    padding-top: 1ex;
-    margin-top: 1ex;
-    border-top: 1ex;
-}
-
-a.bugtitle {
-    font-weight: bold;
-    font-size: 110%;
-}
-
-
-pre.headers {
-    font-family: sans-serif;
-    font-size: 95%;
-    color: #3c3c3c;
-    background-color: #f0f0f0;
-    padding: 2px;
-    border: #a7a7a7 1px solid;
-    line-height: 120%
-}
-
-pre.mime {
-    font-family: monospace;
-    font-size: 95%;
-    color: #797979;
-}
-
-/* This must be separate from the other CSS to make the showing of
-   unimportant messages work in bugreport.cgi. */ 
-.infmessage { display: none; }
-
-.infmessage {
-    font-family: sans-serif;
-    font-size: 90%;
-    color: #686868;
-}
-
-.msgreceived {
-    font-family: sans-serif;
-    font-size: 90%;
-    color: #686868;
-}
-
-pre.tags {
-    color: #a3a3a3;
-    font-size: 90%;
-}
-
-hr.thin {
-    color: #a1a1a1;
-}
-
-em.severity {
-    color: #c31212;
-}
-
-code, address {
-    font-family: sans-serif;
-}
-
-p {
-    font-family: sans-serif;
-    font-size: 95%;
-}
-
-h2.outstanding {
-    font-family: sans-serif;
-    background-color: #f0f0f0;
-    color: #3c3c3c;
-    border: #a7a7a7 1px solid;
-    padding: 10px;
-}
-
-a.options:link, a.options:visited {
-    font-family: sans-serif;
-    background-color: #f0f0f0;
-    color: #3c3c3c;
-    text-decoration: none;
-    border-bottom: #3c3c3c 1px dotted;
-}
-
-li {
-    list-style-type: square;
-}
-
-.bugs li {
-    margin-top: 5px;
-}
-
-input {
-    border: #000 1px solid;
-    margin: 3px;
-}
-
-table.forms {
-    font-size: 95%;
-    font-family: sans-serif;
-    margin-left: 10px;
-}
-
-select {
-    margin: 3px;
-    border: #000 1px solid;
-}
-
index a841b2089cb4d3f060d6fe61f4b6a7c5b955e86f..d0db7cbd65edc48f015c9283b6617c70bb6446f9 100755 (executable)
@@ -661,9 +661,8 @@ sub pkg_htmlindexentrystatus {
     $result .= ";\n";
 
     $result .= $showseverity;
-    $result .= pkg_htmladdresslinks("Reported by: ", \&submitterurl,
-                                $status{originator});
-    $result .= ";\nOwned by: " . html_escape($status{owner})
+    $result .= "Reported by: ".package_links(submitter=>$status{originator});
+    $result .= ";\nOwned by: " . package_links(owner => $status{owner})
                if length $status{owner};
     $result .= ";\nTags: <strong>" 
                  . html_escape(join(", ", sort(split(/\s+/, $status{tags}))))
@@ -904,10 +903,6 @@ sub pkg_htmlpackagelinks {
            );
 }
 
-sub pkg_htmladdresslinks {
-     htmlize_addresslinks(@_,'submitter');
-}
-
 sub pkg_javascript {
     return <<EOF ;
 <script type="text/javascript">
index ed42581fc96de888417f64974b4ccd7a3bd75cee..abe4f580a383af1f7c0ac5ab1946a4b170586dbc 100644 (file)
@@ -2,14 +2,14 @@ html {
     color: #000; 
     background: #fefefe;
     font-family: serif;
-    margin: 1em;
+    margin: 0;
     border: 0;
     padding: 0;
     line-height: 120%;
 }
 
 body {
-    margin: 0;
+    margin: 10px;
     border: 0;
     padding: 0;
 }
@@ -120,6 +120,42 @@ pre.mime {
     color: #686868;
 }
 
+.buginfo p
+{ 
+  font-family: sans-serif;
+  font-size: 110%;
+  margin-bottom: 0px
+}
+
+.buginfo p + p
+{ 
+  margin: 0;
+  margin-top: 0px;
+  border: 0;
+}
+
+
+.pkginfo p
+{ font-family: sans-serif;
+  font-size: 110%;
+  margin-bottom: 0px
+}
+
+.pkginfo p + p
+{ 
+  margin: 0;
+  margin-top: 0px;
+  padding: 0;
+  border: 0;
+}
+
+
+.versiongraph
+{
+  float: right
+  
+}
+
 pre.tags {
     color: #a3a3a3;
     font-size: 90%;
index dedd4458e0b342fed92ba16f97472dd0e7285e4f..18ccbc5c9cc472dbf759da64d87e74bac9416d41 100644 (file)
@@ -74,7 +74,7 @@ my $mech = Test::WWW::Mechanize->new();
 
 $mech->get_ok('http://localhost:'.$port.'/?bug=1',
              'Page received ok');
-ok($mech->content() =~ qr/\<title\>\#1\s+\-\s+Submitting a bug/i,
+ok($mech->content() =~ qr/\<title\>\#1.+Submitting a bug/i,
    'Title of bug is submitting a bug');
 
 # Other tests for bugs in the page should be added here eventually
diff --git a/templates/en_US/cgi/bugreport.tmpl b/templates/en_US/cgi/bugreport.tmpl
new file mode 100644 (file)
index 0000000..4a7c638
--- /dev/null
@@ -0,0 +1,48 @@
+{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_url($ref));
+  }
+  else {
+     $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_url($bug_num, mbox=>'yes')),
+                   html_escape(bug_url($bug_num, mbox=>'yes',mboxstatus=>'yes')),
+                        html_escape(bug_url($bug_num, mbox=>'yes',mboxmaint=>'yes'));
+  }
+  $output;
+}
+{$log}
+<hr>
+<p class="msgreceived">Send a report that <a href="{$config{cgi_domain}}/bugspam.cgi">this bug log contains spam</a>.</p>
+<hr>
+{include(q(html/html_tail))}
+</body>
+</html>
diff --git a/templates/en_US/cgi/bugreport_buginfo.tmpl b/templates/en_US/cgi/bugreport_buginfo.tmpl
new file mode 100644 (file)
index 0000000..6bd16e0
--- /dev/null
@@ -0,0 +1,62 @@
+<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
+}</div>
diff --git a/templates/en_US/cgi/bugreport_pkginfo.tmpl b/templates/en_US/cgi/bugreport_pkginfo.tmpl
new file mode 100644 (file)
index 0000000..22806f7
--- /dev/null
@@ -0,0 +1,16 @@
+<div class="pkginfo">
+  <p>{if (keys %package > 1) { q(Packages)} else {q(Package)}}:
+     {join(q(, ),package_links(package => [map {$_->{package}} values %package],
+                               class => q(submitter),
+                              )
+          )};
+{my $output ='';
+ for my $package (values %package) {
+     $output .= q(Maintainer for ).package_links(package=>$package->{package}).qq( is ).
+                package_links(maintainer => $package->{maintainer}).qq(; );
+     $output .= q(Source for ).package_links(package=>$package->{package}).qq( is ).
+                package_links(source => $package->{source}).qq(. );
+ }
+ $output;
+}</p>
+</div>
diff --git a/templates/en_US/html/html_tail b/templates/en_US/html/html_tail
deleted file mode 100644 (file)
index aa640d2..0000000
+++ /dev/null
@@ -1,11 +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)}
-<!--timestamp-->
-<P>
-<A HREF="http://{$config{web_domain}}/">{$config{project}} {$config{bug}} tracking system</A><BR>
-Copyright (C) 1999 Darren O. Benham,
-1997,2003 nCipher Corporation Ltd,
-1994-97 Ian Jackson.
-</ADDRESS>
diff --git a/templates/en_US/html/html_tail.tmpl b/templates/en_US/html/html_tail.tmpl
new file mode 100644 (file)
index 0000000..d7eb979
--- /dev/null
@@ -0,0 +1,11 @@
+<ADDRESS>{$config{maintainer}} &lt;<A HREF="mailto:{$config{maintainer_email}}">{$config{maintainer_email}}</A>&gt;.
+Last modified:
+<!--timestamp-->
+{$last_modified||strftime('%c',gmtime)}
+<!--timestamp-->
+<P>
+<A HREF="http://{$config{web_domain}}/">{$config{project}} {$config{bug}} tracking system</A><BR>
+Copyright (C) 1999 Darren O. Benham,
+1997,2003 nCipher Corporation Ltd,
+1994-97 Ian Jackson.
+</ADDRESS>
diff --git a/templates/en_US/html/post_title.tmpl b/templates/en_US/html/post_title.tmpl
new file mode 100644 (file)
index 0000000..169d161
--- /dev/null
@@ -0,0 +1,3 @@
+</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+<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
new file mode 100644 (file)
index 0000000..2f7ab77
--- /dev/null
@@ -0,0 +1,3 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title>
\ No newline at end of file