[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#207225: debbugs: add RFC822 output option



Package: debbugs
Version: 2.4.2 UNRELEASED (cvs 20030825.2100 +0200)
Severity: wishlist
Tags: patch

Hi,

I finished adding the rfc822=yes option to debbugs. Patch is attached.

Changelog:
----------
debbugs (2.4.2-1) UNRELEASED; urgency=low

  * Goswin von Brederlow
    - add rfc822 parsable output
      (pkgindex.cgi, pkgreport.cgi, bugreport.cgi, common.pl, text)
      + http://host/pkgreport.cgi?which=pkg&data=test&rfc822=yes
        Display in text/plain rfc822 format
      + http://host/bugreport.cgi?bug=341&rfc822=yes
        Display in text/plain rfc822 format without mails
      + http://host/bugreport.cgi?bug=340&rfc822=yes&mbox=yes
        Display in text/plain rfc822 format with mbox mails
      + http://alpha/Bugs/Bugs/cgi/pkgindex.cgi?indexon=submitter&rfc822=yes
        Display in text/plain rfc822, same for the other indexes.
    - add "Last modified 2 years and 17 days ago;" to bugreport.cgi
      (bugreport.cgi)

 -- Goswin von Brederlow <brederlo@informatik.uni-tuebingen.de>  Mon, 25 Aug 2003 21:05:25 +0200


MfG
	Goswin

-- System Information:
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux dual 2.4.21-ac4 #1 SMP Sat Jul 5 17:53:13 CEST 2003 i686
Locale: LANG=C, LC_CTYPE=de_DE

Index: cgi/bugreport.cgi
===================================================================
RCS file: /cvs/debbugs/source/cgi/bugreport.cgi,v
retrieving revision 1.60
diff -u -p -r1.60 bugreport.cgi
--- cgi/bugreport.cgi	23 Aug 2003 13:17:32 -0000	1.60
+++ cgi/bugreport.cgi	25 Aug 2003 19:07:43 -0000
@@ -15,12 +15,10 @@ require './common.pl';
 require '/etc/debbugs/config';
 require '/etc/debbugs/text';
 
-use vars(qw($gEmailDomain $gHTMLTail $gSpoolDir $gWebDomain));
+use vars(qw($gEmailDomain $gHTMLTail $gTextTail $gSpoolDir $gWebDomain));
 
 my %param = readparse();
 
-my $tail_html;
-
 my $ref = $param{'bug'} || quitcgi("No bug number");
 $ref =~ /(\d+)/ or quitcgi("Invalid bug number");
 $ref = $1;
@@ -32,6 +30,7 @@ my $terse = ($param{'terse'} || 'no') eq
 my $reverse = ($param{'reverse'} || 'no') eq 'yes';
 my $mbox = ($param{'mbox'} || 'no') eq 'yes'; 
 my $mime = ($param{'mime'} || 'yes') eq 'yes';
+my $rfc822 = ($param{'rfc822'} || 'no') eq 'yes';
 
 # Not used by this script directly, but fetch these so that pkgurl() and
 # friends can propagate them correctly.
@@ -39,18 +38,27 @@ my $archive = ($param{'archive'} || 'no'
 my $repeatmerged = ($param{'repeatmerged'} || 'yes') eq 'yes';
 set_option('archive', $archive);
 set_option('repeatmerged', $repeatmerged);
+set_option('rfc822', $rfc822);
 
 my $buglog = buglog($ref);
+my @stat = stat $buglog;
 
 if ($ENV{REQUEST_METHOD} eq 'HEAD' and not defined($att) and not $mbox) {
+  if ($rfc822) {
+    print "Content-Type: text/plain\n";
+    if (@stat) {
+	my $mtime = strftime '%a, %d %b %Y %T GMT', gmtime($stat[9]);
+	print "Last-Modified: $mtime\n";
+    }
+  } else {
     print "Content-Type: text/html\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;
+  }
+  print "\n";
+  exit 0;
 }
 
 sub display_entity ($$$$\$\@);
@@ -138,11 +146,26 @@ $ENV{"TZ"} = 'UTC';
 tzset();
 
 my $dtime = strftime "%a, %e %b %Y %T UTC", localtime;
-$tail_html = $debbugs::gHTMLTail;
+my $tail_html;
+if ($rfc822) {
+    $tail_html = $debbugs::gTextTail;
+} else {
+    $tail_html = $debbugs::gHTMLTail;
+}
 $tail_html =~ s/SUBSTITUTE_DTIME/$dtime/;
 
 my %status = %{getbugstatus($ref)};
 unless (%status) {
+  if ($rfc822) {
+    print <<EOF;
+Content-Type: text/plain
+
+; TITLE: $debbugs::gProject $debbugs::gBug report logs - $short
+; There is no record of $debbugs::gBug $short.
+; Try the search page (http://$gWebDomain/) instead.
+$tail_html
+EOF
+  } else {
     print <<EOF;
 Content-Type: text/html
 
@@ -155,6 +178,7 @@ Content-Type: text/html
 Try the <a href="http://$gWebDomain/";>search page</a> instead.</p>
 $tail_html</body></html>
 EOF
+  }
     exit 0;
 }
 
@@ -163,69 +187,144 @@ $|=1;
 $tpack = lc $status{'package'};
 my @tpacks = splitpackages($tpack);
 
-if  ($status{severity} eq 'normal') {
-	$showseverity = '';
+if ($rfc822) {
+  $showseverity = "Severity: $status{severity}\n";
+} else {
+  if  ($status{severity} eq 'normal') {
+    $showseverity = '<p>';
 #} elsif (isstrongseverity($status{severity})) {
-#	$showseverity = "<strong>Severity: $status{severity}</strong>;\n";
+#	$showseverity = "<p><strong>Severity: $status{severity}</strong>;\n";
+  } else {
+	$showseverity = "<p>Severity: <em>$status{severity}</em>;\n";
+  }
+
+}
+$indexentry .= "$showseverity";
+my $mtime = $stat[9];
+if ($rfc822) {
+  $indexentry .= "Package: " . $status{package} . "\n";
+  $indexentry .= "Reported by: " . $status{originator} . "\n";
+  $indexentry .= "Date: " . int($status{date}) . "\n";
+  $indexentry .= "MTime: " . $mtime . "\n";
 } else {
-	$showseverity = "Severity: <em>$status{severity}</em>;\n";
+  $indexentry .= htmlpackagelinks($status{package}, 0);
+  $indexentry .= "Reported by: <a href=\"" . submitterurl($status{originator})
+               . "\">" . htmlsanit($status{originator}) . "</a>;\n";
+  my $dummy = strftime "%a, %e %b %Y %T UTC", localtime($status{date});
+  $indexentry .= "Date: " . $dummy . ";\n";
+  my $daysold = int((time - $mtime) / 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;
+
+    $indexentry .= $font . "Last modified ";
+    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);
+    $indexentry .= join(" and ", @age);
+    $indexentry .= " ago;$efont\n";
+  }
 }
 
-$indexentry .= "<p>$showseverity";
-$indexentry .= htmlpackagelinks($status{package}, 0);
+my @descstates;
 
-$indexentry .= "Reported by: <a href=\"" . submitterurl($status{originator})
-              . "\">" . htmlsanit($status{originator}) . "</a>;\n";
+if ($rfc822) {
+  push @descstates, "Tags: "
+                  . (join(", ", sort(split(/\s+/, $status{tags}))))
+	if length($status{tags});
+
+  my @merged= split(/ /,$status{mergedwith});
+  if (@merged) {
+    my $descmerged = 'Merged with: ';
+    my $mseparator = '';
+    for my $m (@merged) {
+      $descmerged .= $mseparator."#$m";
+      $mseparator= ", ";
+    }
+    push @descstates, $descmerged;
+  }
 
-my $dummy = strftime "%a, %e %b %Y %T UTC", localtime($status{date});
-$indexentry .= "Date: ".$dummy.";\n<br>";
+  if (@{$status{found_versions}}) {
+    my $foundtext = 'Found in version: ';
+    $foundtext .= join ', ', @{$status{found_versions}};
+    push @descstates, $foundtext;
+  }
 
-my @descstates;
+  if (@{$status{fixed_versions}}) {
+    my $fixedtext = 'Fixed in version: ';
+    $fixedtext .= join ', ', @{$status{fixed_versions}};
+    push @descstates, $fixedtext;
+    if (length($status{done})) {
+      push @descstates, 'Fixed by: ' . $status{done};
+    }
+  } elsif (length($status{done})) {
+    push @descstates, "Done: " . $status{done};
+  } elsif (length($status{forwarded})) {
+    push @descstates, "Forwarded to: " . $status{forwarded};
+  }
 
-push @descstates, "Tags: <strong>"
-		. htmlsanit(join(", ", sort(split(/\s+/, $status{tags}))))
-		. "</strong>"
-			if length($status{tags});
-
-my @merged= split(/ /,$status{mergedwith});
-if (@merged) {
-	my $descmerged = 'merged with ';
-	my $mseparator = '';
-	for my $m (@merged) {
-		$descmerged .= $mseparator."<a href=\"" . bugurl($m) . "\">#$m</a>";
-		$mseparator= ",\n";
-	}
-	push @descstates, $descmerged;
-}
+  $indexentry .= join("\n", @descstates) . "\n" if @descstates;
+} else {
+  push @descstates, "Tags: <strong>"
+                  . htmlsanit(join(", ", sort(split(/\s+/, $status{tags}))))
+		  . "</strong>"
+		    if length($status{tags});
+
+  my @merged= split(/ /,$status{mergedwith});
+  if (@merged) {
+    my $descmerged = 'merged with ';
+    my $mseparator = '';
+    for my $m (@merged) {
+      $descmerged .= $mseparator."<a href=\"" . bugurl($m) . "\">#$m</a>";
+      $mseparator= ",\n";
+    }
+    push @descstates, $descmerged;
+  }
 
-if (@{$status{found_versions}}) {
+  if (@{$status{found_versions}}) {
     my $foundtext = 'Found in ';
     $foundtext .= (@{$status{found_versions}} == 1) ? 'version ' : 'versions ';
     $foundtext .= join ', ', map htmlsanit($_), @{$status{found_versions}};
     push @descstates, $foundtext;
-}
+  }
 
-if (@{$status{fixed_versions}}) {
+  if (@{$status{fixed_versions}}) {
     my $fixedtext = '<strong>Fixed</strong> in ';
     $fixedtext .= (@{$status{fixed_versions}} == 1) ? 'version ' : 'versions ';
     $fixedtext .= join ', ', map htmlsanit($_), @{$status{fixed_versions}};
     if (length($status{done})) {
-	$fixedtext .= ' by ' . htmlsanit($status{done});
+      $fixedtext .= ' by ' . htmlsanit($status{done});
     }
     push @descstates, $fixedtext;
-} elsif (length($status{done})) {
-	push @descstates, "<strong>Done:</strong> ".htmlsanit($status{done});
-} elsif (length($status{forwarded})) {
-	push @descstates, "<strong>Forwarded</strong> to ".maybelink($status{forwarded});
+  } elsif (length($status{done})) {
+    push @descstates, "<strong>Done:</strong> ".htmlsanit($status{done});
+  } elsif (length($status{forwarded})) {
+    push @descstates, "<strong>Forwarded</strong> to ".maybelink($status{forwarded});
+  }
+
+  $indexentry .= join(";\n", @descstates) . ";\n<br>" if @descstates;
 }
 
-$indexentry .= join(";\n", @descstates) . ";\n<br>" if @descstates;
 
 $descriptivehead = $indexentry;
 foreach my $pkg (@tpacks) {
     my $tmaint = defined($maintainer{$pkg}) ? $maintainer{$pkg} : '(unknown)';
     my $tsrc = defined($pkgsrc{$pkg}) ? $pkgsrc{$pkg} : '(unknown)';
 
+    if ($rfc822) {
+      $descriptivehead .= "\nPackage: $pkg\n"
+	                . "Maintainer: $tmaint\n";
+      $descriptivehead .= "Source: $tsrc\n" if ($tsrc ne "(unknown)");
+    } else {
     $descriptivehead .=
             htmlmaintlinks(sub { $_[0] == 1 ? "Maintainer for $pkg is\n"
                                             : "Maintainers for $pkg are\n" },
@@ -233,11 +332,18 @@ foreach my $pkg (@tpacks) {
     $descriptivehead .= ";\nSource for $pkg is\n".
             '<a href="'.srcurl($tsrc)."\">$tsrc</a>" if ($tsrc ne "(unknown)");
     $descriptivehead .= ".\n<br>";
+    }
 }
 
 open L, "<$buglog" or &quitcgi("open log for $ref: $!");
 if ($buglog !~ m#^\Q$gSpoolDir/db#) {
+  if ($rfc822) {
+    $descriptivehead .= "\nArchived: yes\n";
+  } else {
     $descriptivehead .= "\n<p>Bug is <strong>archived</strong>. No further changes may be made.</p>";
+  }
+} else {
+  $descriptivehead .= "\nArchived: no\n" if ($rfc822);
 }
 
 my $log='';
@@ -296,7 +402,7 @@ while(my $line = <L>) {
 
 			$show = ($xmessage == $msg) if ($msg);
 
-			push @mails, join( '', @mail ) if ( $mbox && @mail );
+			push @mails, join( '', @mail ) if ($mbox && @mail );
 			if ($show) {
 				if (not $mime and @mail) {
 					$this .= htmlsanit(join '', @mail);
@@ -412,7 +518,7 @@ while(my $line = <L>) {
 &quitcgi("$ref state $normstate at end") unless $normstate eq 'kill-end';
 close(L);
 
-if ( $mbox ) {
+if ( $mbox && !$rfc822) {
 	print "Content-Type: text/plain\n\n";
 	foreach ( @mails ) {
 		my @lines = split( "\n", $_, -1 );
@@ -431,6 +537,32 @@ if ( $mbox ) {
 	print join("", @mails );
 	exit 0;
 }
+if ($rfc822) {
+  print "Content-Type: text/plain\n\n";
+
+  my $title = $status{subject};
+
+  print "; TITLE: $debbugs::gProject $debbugs::gBug report logs - $short - $title\n\n";
+
+  print "$descriptivehead\n\n";
+  foreach ( @mails ) {
+    my @lines = split( "\n", $_, -1 );
+    if ( $lines[ 1 ] =~ m/^From / ) {
+      my $tmp = $lines[ 0 ];
+      $lines[ 0 ] = $lines[ 1 ];
+      $lines[ 1 ] = $tmp;
+    }
+    if ( !( $lines[ 0 ] =~ m/^From / ) ) {
+      my $date = strftime "%a %b %d %T %Y", localtime;
+      unshift @lines, "From unknown $date";
+    }
+    map { s/^(>*From )/>$1/ } @lines[ 1 .. $#lines ];
+    $_ = join( "\n ", @lines ) . "\n";
+  }
+  print "Mail: ". join("\nMail: ", @mails ) if @mails;
+
+  print $tail_html;
+}else {
 print "Content-Type: text/html\n\n";
 
 my $title = htmlsanit($status{subject});
@@ -451,5 +583,5 @@ print "$log";
 print $tail_html;
 
 print "</BODY></HTML>\n";
-
+}
 exit 0;
Index: cgi/common.pl
===================================================================
RCS file: /cvs/debbugs/source/cgi/common.pl,v
retrieving revision 1.90
diff -u -p -r1.90 common.pl
--- cgi/common.pl	23 Aug 2003 15:12:57 -0000	1.90
+++ cgi/common.pl	25 Aug 2003 19:07:44 -0000
@@ -284,6 +284,58 @@ sub htmlindexentrystatus {
     return $result;
 }
 
+sub textindexentrystatus {
+    my $s = shift;
+    my %status = %{$s};
+
+    my $result = "";
+
+    if  ($status{severity} eq 'normal') {
+        $showseverity = '';
+    } else {
+        $showseverity = "Severity: " . $status{severity} . "\n";
+    }
+
+    $result .= "Package: " . $status{"package"} . "\n";
+    $result .= $showseverity;
+    $result .= "Reported by: " . $status{originator};
+    $result .= "\nTags: " . (join(", ", sort(split(/\s+/, $status{tags}))))
+                       if (length($status{tags}));
+
+    my @merged= split(/ /,$status{mergedwith});
+    my $mseparator= "\nMerged with:";
+    for my $m (@merged) {
+        $result .= "$mseparator #$m";
+        $mseparator= ",";
+    }
+
+    if (@{$status{found_versions}}) {
+        $result .= "\nFound in version: ";
+        $result .= join ', ', @{$status{found_versions}};
+    }
+
+    if (@{$status{fixed_versions}}) {
+        $result .= "\nFixed in versions: ";
+        $result .= join ', ', @{$status{fixed_versions}};
+        if (length($status{done})) {
+            $result .= '\nDone: ' . $status{done};
+        }
+    } elsif (length($status{done})) {
+        $result .= "\nDone: " . $status{done};
+    }
+
+    unless (length($status{done})) {
+        if (length($status{forwarded})) {
+            $result .= "\nForwarded to: " . $status{forwarded};
+        }
+	$result .= "\nDate: " . $status{date};
+    }
+
+    $result .= "\n";
+
+    return $result;
+}
+
 sub urlargs {
     my $args = '';
     $args .= "&archive=yes" if $common_archive;
@@ -490,6 +542,111 @@ sub htmlizebugs {
 
     }
     $result .= $debbugs::gHTMLExpireNote if $gRemoveAge and $anydone;
+    return $result;
+}
+
+sub textizebugs {
+    $b = $_[0];
+    my @bugs = @$b;
+    my @rawsort;
+
+    my %section = ();
+
+    my %displayshowpending = ("pending", "outstanding",
+			      "pending-fixed", "pending upload",
+			      "fixed", "fixed in NMU",
+                              "done", "resolved",
+                              "forwarded", "forwarded to upstream software authors",
+                              "absent", "not applicable to this version");
+
+    if (@bugs == 0) {
+        return "; No reports found!\n";
+    }
+
+    if ( $common_bug_reverse ) {
+	@bugs = sort {$b<=>$a} @bugs;
+    } else {
+	@bugs = sort {$a<=>$b} @bugs;
+    }
+    my %seenmerged;
+    foreach my $bug (@bugs) {
+	my %status = %{getbugstatus($bug)};
+        next unless %status;
+	if (%common_include) {
+	    my $okay = 0;
+	    foreach my $t (split /\s+/, $status{tags}) {
+		$okay = 1, last if (defined $common_include{$t});
+	    }
+	    if (defined $common_include{subj}) {
+                if (index($status{subject}, $common_include{subj}) > -1) {
+                    $okay = 1;
+                }
+            }
+	    next unless ($okay);
+        }
+	if (%common_exclude) {
+	    my $okay = 1;
+	    foreach my $t (split /\s+/, $status{tags}) {
+		$okay = 0, last if (defined $common_exclude{$t});
+	    }
+	    if (defined $common_exclude{subj}) {
+                if (index($status{subject}, $common_exclude{subj}) > -1) {
+                    $okay = 0;
+                }
+            }
+	    next unless ($okay);
+	}
+	next if @common_pending_include and
+	     not grep { $_ eq $status{pending} } @common_pending_include;
+	next if @common_severity_include and
+	     not grep { $_ eq $status{severity} } @common_severity_include;
+	next if grep { $_ eq $status{pending} } @common_pending_exclude;
+	next if grep { $_ eq $status{severity} } @common_severity_exclude;
+
+	my @merged = sort {$a<=>$b} ($bug, split(/ /, $status{mergedwith}));
+	next unless ($common_repeatmerged || !$seenmerged{$merged[0]});
+	$seenmerged{$merged[0]} = 1;
+
+	my $text = sprintf "Bug: #%d\nTitle: %s\n",
+	    $bug, $status{subject};
+	$text .= textindexentrystatus(\%status);
+	my $buglog = buglog($bug);
+	my @stat = stat $buglog;
+	$text .= "MTime: " . $stat[9] . "\n\n" if (@stat);
+	$section{$status{pending} . "_" . $status{severity}} .= $text;
+	push @rawsort, $text if $common_raw_sort;
+    }
+
+    my $result = "";
+    my $anydone = 0;
+    if ($common_raw_sort) {
+	$result .= "\n" . join("", @rawsort ) . "\n";
+    } else {
+	my @pendingList = qw(pending forwarded pending-fixed fixed done absent);
+	@pendingList = reverse @pendingList if $common_pending_reverse;
+#print STDERR join(",",@pendingList)."\n";
+#print STDERR join(",",@common_pending_include).":$#common_pending_include\n";
+    foreach my $pending (@pendingList) {
+	my @severityList = @debbugs::gSeverityList;
+	@severityList = reverse @severityList if $common_severity_reverse;
+#print STDERR join(",",@severityList)."\n";
+
+#        foreach my $severity(@debbugs::gSeverityList) {
+        foreach my $severity(@severityList) {
+            $severity = $debbugs::gDefaultSeverity if ($severity eq '');
+            next unless defined $section{${pending} . "_" . ${severity}};
+            $result .= "\n; $debbugs::gSeverityDisplay{$severity}: $displayshowpending{$pending}\n";
+            #$result .= "(A list of <a href=\"http://${debbugs::gWebDomain}/db/si/$pending$severity\";>all such bugs</a> is available).\n";
+            #$result .= "(A list of all such bugs used to be available).\n";
+            $result .= "\n";
+	    $result .= $section{$pending . "_" . $severity}; 
+	    $result .= "\n";
+            $anydone = 1 if ($pending eq "done");
+         }
+    }
+
+    }
+    $result .= $debbugs::gTEXTExpireNote if $gRemoveAge and $anydone;
     return $result;
 }
 
Index: cgi/pkgindex.cgi
===================================================================
RCS file: /cvs/debbugs/source/cgi/pkgindex.cgi,v
retrieving revision 1.18
diff -u -p -r1.18 pkgindex.cgi
--- cgi/pkgindex.cgi	6 Aug 2003 23:35:55 -0000	1.18
+++ cgi/pkgindex.cgi	25 Aug 2003 19:07:44 -0000
@@ -29,6 +29,7 @@ if ($sortby !~ m/^(alpha|count)$/) {
 
 #my $include = $param{'include'} || "";
 #my $exclude = $param{'exclude'} || "";
+my $rfc822 = ($param{'rfc822'} || "no") eq "yes";
 
 my $Archived = $archive ? " Archived" : "";
 
@@ -39,8 +40,12 @@ $ENV{"TZ"} = 'UTC';
 tzset();
 
 my $dtime = strftime "%a, %e %b %Y %T UTC", localtime;
-my $tail_html = $debbugs::gHTMLTail;
-$tail_html = $debbugs::gHTMLTail;
+my $tail_html;
+if ($rfc822) {
+    $tail_html = $debbugs::gTextTail;
+} else {
+    $tail_html = $debbugs::gHTMLTail;
+}
 $tail_html =~ s/SUBSTITUTE_DTIME/$dtime/;
 
 set_option("repeatmerged", $repeatmerged);
@@ -49,17 +54,24 @@ set_option("archive", $archive);
 #	if ($include);
 #set_option("exclude", { map {($_,1)} (split /[\s,]+/, $exclude) })
 #	if ($exclude);
+set_option("rfc822", $rfc822);
 
 my %count;
 my $tag;
 my $note;
 my %htmldescrip = ();
+my %textdescrip = ();
 my %sortkey = ();
 if ($indexon eq "pkg") {
   $tag = "package";
   %count = countbugs(sub {my %d=@_; return splitpackages($d{"pkg"})});
-  $note = "<p>Note that with multi-binary packages there may be other\n";
-  $note .= "reports filed under the different binary package names.</p>\n";
+  if ($rfc822) {
+    $note = "; Note that with multi-binary packages there may be other\n";
+    $note .= "; reports filed under the different binary package names.\n";
+  } else {
+    $note = "<p>Note that with multi-binary packages there may be other\n";
+    $note .= "reports filed under the different binary package names.</p>\n";
+  }
   foreach my $pkg (keys %count) {
     $sortkey{$pkg} = lc $pkg;
     $htmldescrip{$pkg} = sprintf('<a href="%s">%s</a> (%s)',
@@ -68,6 +80,7 @@ if ($indexon eq "pkg") {
                            htmlmaintlinks(sub { $_[0] == 1 ? 'maintainer: '
                                                            : 'maintainers: ' },
                                           $maintainers{$pkg}));
+    $textdescrip{$pkg} = "Package: $pkg\nMaintainer: $maintainers{$pkg}\n";
   }
 } elsif ($indexon eq "src") {
   $tag = "source package";
@@ -86,6 +99,7 @@ if ($indexon eq "pkg") {
                            htmlmaintlinks(sub { $_[0] == 1 ? 'maintainer: '
                                                            : 'maintainers: ' },
                                           $maintainers{$src}));
+    $textdescrip{$src} = "Source: $src\nMaintainer: $maintainers{$src}\n";
   }
 } elsif ($indexon eq "maint") {
   $tag = "maintainer";
@@ -100,12 +114,19 @@ if ($indexon eq "pkg") {
                             map { $_->address } @me;
                           } splitpackages($d{"pkg"});
                          });
-  $note = "<p>Note that maintainers may use different Maintainer fields for\n";
-  $note .= "different packages, so there may be other reports filed under\n";
-  $note .= "different addresses.</p>\n";
+  if ($rfc822) {
+    $note = "; Note that maintainers may use different Maintainer fields for\n";
+    $note .= "; different packages, so there may be other reports filed under\n";
+    $note .= "; different addresses.\n";
+  } else {
+    $note = "<p>Note that maintainers may use different Maintainer fields for\n";
+    $note .= "different packages, so there may be other reports filed under\n";
+    $note .= "different addresses.</p>\n";
+  }
   foreach my $maint (keys %count) {
     $sortkey{$maint} = lc $email2maint{$maint} || "(unknown)";
     $htmldescrip{$maint} = htmlmaintlinks('', $email2maint{$maint});
+    $textdescrip{$maint} = "Maintainer: $email2maint{$maint}\n";
   }
 } elsif ($indexon eq "submitter") {
   $tag = "submitter";
@@ -120,10 +141,17 @@ if ($indexon eq "pkg") {
     $htmldescrip{$sub} = sprintf('<a href="%s">%s</a>',
                            submitterurl($sub),
 			   htmlsanit($fullname{$sub}));
+    $textdescrip{$sub} = "Submitter: $fullname{$sub}\n";
+  }
+  if ($rfc822) {
+    $note = "; Note that people may use different email accounts for\n";
+    $note .= "; different bugs, so there may be other reports filed under\n";
+    $note .= "; different addresses.\n";
+  } else {
+    $note = "<p>Note that people may use different email accounts for\n";
+    $note .= "different bugs, so there may be other reports filed under\n";
+    $note .= "different addresses.</p>\n";
   }
-  $note = "<p>Note that people may use different email accounts for\n";
-  $note .= "different bugs, so there may be other reports filed under\n";
-  $note .= "different addresses.</p>\n";
 } elsif ($indexon eq "tag") {
   $tag = "tag";
   %count = countbugs(sub {my %d=@_; return split ' ', $d{tags}; });
@@ -133,9 +161,30 @@ if ($indexon eq "pkg") {
     $htmldescrip{$keyword} = sprintf('<a href="%s">%s</a>',
                                tagurl($keyword),
                                htmlsanit($keyword));
+    $textdescrip{$keyword} = "Tag: $keyword\n";
   }
 }
 
+if ($rfc822) {
+  my $result;
+  my @orderedentries;
+  if ($sortby eq "count") {
+    @orderedentries = sort { $count{$a} <=> $count{$b} } keys %count;
+  } else { # sortby alpha
+    @orderedentries = sort { $sortkey{$a} cmp $sortkey{$b} } keys %count;
+  }
+  foreach my $x (@orderedentries) {
+    $result .= $textdescrip{$x} . "Count: $count{$x}\n";
+  }
+
+  print "Content-Type: text/plain\n\n";
+
+  print "; TITLE: $debbugs::gProject$Archived $debbugs::gBug reports by $tag\n";
+  print $note . "\n";
+  print $result;
+
+  print "$tail_html";
+} else {
 my $result = "<ul>\n";
 my @orderedentries;
 if ($sortby eq "count") {
@@ -167,3 +216,4 @@ print "<hr>\n";
 print "$tail_html";
 
 print "</body></html>\n";
+}
Index: cgi/pkgreport.cgi
===================================================================
RCS file: /cvs/debbugs/source/cgi/pkgreport.cgi,v
retrieving revision 1.72
diff -u -p -r1.72 pkgreport.cgi
--- cgi/pkgreport.cgi	24 Aug 2003 10:47:55 -0000	1.72
+++ cgi/pkgreport.cgi	25 Aug 2003 19:07:44 -0000
@@ -14,8 +14,15 @@ require '/etc/debbugs/text';
 use vars qw($gPackagePages $gWebDomain);
 
 if ($ENV{REQUEST_METHOD} eq 'HEAD') {
-    print "Content-Type: text/html\n\n";
-    exit 0;
+    my %param = readparse();
+    my $rfc822 = ($param{'rfc822'} || "no") eq "yes";
+    if ($rfc822) {
+      print "Content-Type: text/plain\n\n";
+      exit 0;
+    } else {
+      print "Content-Type: text/html\n\n";
+      exit 0;
+    }
 }
 
 nice(5);
@@ -37,6 +44,7 @@ my $sev_inc = $param{'&sev-inc'} || $par
 my $version = $param{'version'} || undef;
 my $dist = $param{'dist'} || undef;
 my $arch = $param{'arch'} || undef;
+my $rfc822 = ($param{'rfc822'} || "no") eq "yes";
 
 my ($pkg, $src, $maint, $maintenc, $submitter, $severity, $status, $tag);
 
@@ -92,8 +100,12 @@ $ENV{"TZ"} = 'UTC';
 tzset();
 
 my $dtime = strftime "%a, %e %b %Y %T UTC", localtime;
-my $tail_html = $debbugs::gHTMLTail;
-$tail_html = $debbugs::gHTMLTail;
+my $tail_html;
+if ($rfc822) {
+    $tail_html = $debbugs::gTextTail;
+} else {
+    $tail_html = $debbugs::gHTMLTail;
+}
 $tail_html =~ s/SUBSTITUTE_DTIME/$dtime/;
 
 set_option("repeatmerged", $repeatmerged);
@@ -111,6 +123,7 @@ set_option("sev-inc", $sev_inc);
 set_option("version", $version);
 set_option("dist", $dist);
 set_option("arch", $arch);
+set_option("rfc822", $rfc822);
 
 my $title;
 my @bugs;
@@ -227,18 +240,28 @@ if (defined $pkg) {
                         })};
 }
 
-my $result = htmlizebugs(\@bugs);
+my $result;
+if ($rfc822) {
+    $result = textizebugs(\@bugs);
+
+    print "Content-Type: text/plain\n\n";
+
+    print "; TITLE: $debbugs::gProject$Archived $debbugs::gBug report logs: $title\n";
+} else {
+    $result = htmlizebugs(\@bugs);
 
-print "Content-Type: text/html\n\n";
+    print "Content-Type: text/html\n\n";
+
+    print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
+    print "<HTML><HEAD>\n" . 
+	  "<TITLE>$debbugs::gProject$Archived $debbugs::gBug report logs: $title</TITLE>\n" .
+          "</HEAD>\n" .
+          '<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#800080">' .
+          "\n";
+    print "<H1>" . "$debbugs::gProject$Archived $debbugs::gBug report logs: $title" .
+          "</H1>\n";
+}
 
-print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
-print "<HTML><HEAD>\n" . 
-    "<TITLE>$debbugs::gProject$Archived $debbugs::gBug report logs: $title</TITLE>\n" .
-    "</HEAD>\n" .
-    '<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#800080">' .
-    "\n";
-print "<H1>" . "$debbugs::gProject$Archived $debbugs::gBug report logs: $title" .
-      "</H1>\n";
 
 my $showresult = 1;
 
@@ -246,13 +269,20 @@ if (defined $pkg || defined $src) {
     my %maintainers = %{getmaintainers()};
     my $maint = $pkg ? $maintainers{$pkg} : $maintainers{$src} ? $maintainers{$src} : undef;
     if (defined $maint) {
-        print '<p>';
-        my $showpkg = (defined $pkg) ? $pkg : "source package $src";
-        print htmlmaintlinks(sub { $_[0] == 1 ? "Maintainer for $showpkg is "
-                                              : "Maintainers for $showpkg are "
-                                 },
-                             $maint);
-        print ".</p>\n";
+        if ($rfc822) {
+	    print "Package: $pkg\n" if defined $pkg;
+	    print "Source: $pkg\n" if defined $src;
+	    print "Maintainer: $maint\n";
+	} else {
+	    print '<p>';
+            my $showpkg = (defined $pkg) ? $pkg : "source package $src";
+            print htmlmaintlinks(sub { $_[0] == 1 ?
+					  "Maintainer for $showpkg is "
+					: "Maintainers for $showpkg are "
+				      },
+				 $maint);
+	    print ".</p>\n";
+	}
     }
     if (defined $maint or @bugs) {
 	my %pkgsrc = %{getpkgsrc()};
@@ -267,58 +297,93 @@ if (defined $pkg || defined $src) {
 	if ( @pkgs ) {
 	    @pkgs = sort @pkgs;
 	    if ($pkg) {
+	        if ($rfc822) {
+		    print "Same source: ";
+		} else {
 		    print "You may want to refer to the following packages that are part of the same source:<br>\n";
+		}
 	    } else {
-		    print "You may want to refer to the following individual bug pages:<br>\n";
+	        if ($pkg) {
+	            if ($rfc822) {
+		        print "Indivual bugs: ";
+		    } else {
+		        print "You may want to refer to the following individual bug pages:<br>\n";
+		    }
+		}
+		push @pkgs, $src if ( $src && !grep(/^\Q$src\E$/, @pkgs) );
+		if ($rfc822) {
+		    print join(", ", @pkgs);
+		} else {
+	            print join( ", ", map( "<A href=\"" . pkgurl($_) . "\">$_</A>", @pkgs ) );
+	            print ".\n";
+	        }
 	    }
-	    push @pkgs, $src if ( $src && !grep(/^\Q$src\E$/, @pkgs) );
-	    print join( ", ", map( "<A href=\"" . pkgurl($_) . "\">$_</A>", @pkgs ) );
-	    print ".\n";
 	}
-	my @references;
-	my $pseudodesc = getpseudodesc();
-	if ($pkg and defined($pseudodesc) and exists($pseudodesc->{$pkg})) {
-	    push @references, "to the <a href=\"http://${debbugs::gWebDomain}/pseudo-packages${debbugs::gHTMLSuffix}\";>list of other pseudo-packages</a>";
-	} else {
-	    if ($pkg) {
-		push @references, sprintf "to the <a href=\"%s\">%s package page</a>", urlsanit("http://${debbugs::gPackagePages}/$pkg";), htmlsanit("$pkg");
-	    }
-	    if (defined $debbugs::gSubscriptionDomain) {
-		my $ptslink = $pkg ? $srcforpkg : $src;
-		push @references, "to the <a href=\"http://$debbugs::gSubscriptionDomain/$ptslink\";>Package Tracking System</a>";
+	if (!$rfc822) {
+	    my @references;
+	    my $pseudodesc = getpseudodesc();
+	    if ($pkg and defined($pseudodesc) and exists($pseudodesc->{$pkg})) {
+	        push @references, "to the <a href=\"http://${debbugs::gWebDomain}/pseudo-packages${debbugs::gHTMLSuffix}\";>list of other pseudo-packages</a>";
+	    } else {
+	        if ($pkg) {
+		    push @references, sprintf "to the <a href=\"%s\">%s package page</a>", urlsanit("http://${debbugs::gPackagePages}/$pkg";), htmlsanit("$pkg");
+	        }
+	        if (defined $debbugs::gSubscriptionDomain) {
+		    my $ptslink = $pkg ? $srcforpkg : $src;
+		    push @references, "to the <a href=\"http://$debbugs::gSubscriptionDomain/$ptslink\";>Package Tracking System</a>";
+	        }
+	        # Only output this if the source listing is non-trivial.
+	        if ($pkg and $srcforpkg and (@pkgs or $pkg ne $srcforpkg)) {
+		    push @references, sprintf "to the source package <a href=\"%s\">%s</a>'s bug page", srcurl($srcforpkg), htmlsanit($srcforpkg);
+	        }
 	    }
-	    # Only output this if the source listing is non-trivial.
-	    if ($pkg and $srcforpkg and (@pkgs or $pkg ne $srcforpkg)) {
-		push @references, sprintf "to the source package <a href=\"%s\">%s</a>'s bug page", srcurl($srcforpkg), htmlsanit($srcforpkg);
+	    if (@references) {
+	        $references[$#references] = "or $references[$#references]" if @references > 1;
+	        print "<p>You might like to refer ", join(", ", @references), ".</p>\n";
 	    }
-	}
-	if (@references) {
-	    $references[$#references] = "or $references[$#references]" if @references > 1;
-	    print "<p>You might like to refer ", join(", ", @references), ".</p>\n";
-	}
-	print "<p>If you find a bug not listed here, please\n";
-	printf "<a href=\"%s\">report it</a>.</p>\n",
-	       urlsanit("http://${debbugs::gWebDomain}/Reporting${debbugs::gHTMLSuffix}";);
+	    print "<p>If you find a bug not listed here, please\n";
+	    printf "<a href=\"%s\">report it</a>.</p>\n",
+	           urlsanit("http://${debbugs::gWebDomain}/Reporting${debbugs::gHTMLSuffix}";);
+	  }
     } else {
-	print "<p>There is no record of the " .
+        if ($rfc822) {
+	    print "; There is no record of the " .
 	      (defined($pkg) ? htmlsanit($pkg) . " package"
 			     : htmlsanit($src) . " source package") .
-	      ", and no bugs have been filed against it.</p>";
+	      ", and no bugs have been filed against it.";
+	} else {
+	    print "<p>There is no record of the " .
+	          (defined($pkg) ? htmlsanit($pkg) . " package"
+			         : htmlsanit($src) . " source package") .
+	          ", and no bugs have been filed against it.</p>";
+        }
 	$showresult = 0;
     }
 } elsif (defined $maint || defined $maintenc) {
+  if ($rfc822) {
+    print ";Note that maintainers may use different Maintainer fields for"
+        . " different packages, so there may be other reports filed under"
+	. " different addresses.\n";
+  } else {
     print "<p>Note that maintainers may use different Maintainer fields for\n";
     print "different packages, so there may be other reports filed under\n";
     print "different addresses.\n";
+  }
 } elsif (defined $submitter) {
+  if ($rfc822) {
+    print ";Note that people may use different email accounts for"
+        . " different bugs, so there may be other reports filed under"
+	. " different addresses.\n";
+  }else {
     print "<p>Note that people may use different email accounts for\n";
     print "different bugs, so there may be other reports filed under\n";
     print "different addresses.\n";
+  }
 }
 
 print $result if $showresult;
 
-print "<hr>\n";
+print "<hr>\n" if !($rfc822);
 print "$tail_html";
 
-print "</body></html>\n";
+print "</body></html>\n" if !($rfc822);
Index: scripts/text.in
===================================================================
RCS file: /cvs/debbugs/source/scripts/text.in,v
retrieving revision 1.22
diff -u -p -r1.22 text.in
--- scripts/text.in	24 Aug 2003 23:30:04 -0000	1.22
+++ scripts/text.in	25 Aug 2003 19:07:45 -0000
@@ -167,6 +167,7 @@ $gHTMLTagDesc = "
 # shows up at the start of (most) html pages.
 ############################################################################
 $gHTMLStart = "<BODY>";
+$gTextStart = "";
 
 ############################################################################
 # shows up at the end of (most) html pages.
@@ -185,11 +186,21 @@ $gHTMLTail = "<HR>
  1994-97 Ian Jackson.
  </ADDRESS>
 ";
+$gTextTail = "
+; $gMaintainer <$gMaintainerEmail>
+; Last modified: SUBSTITUTE_DTIME
+
+; Debian $gBug tracking system: http://$gWebDomain/
+; Copyright (C) 1999 Darren O. Benham,
+;               1997,2003 nCipher Corporation Ltd,
+;               1994-97 Ian Jackson.
+";
 
 ############################################################################
 # Message on when reports are purged.
 ############################################################################
 $gHTMLExpireNote = "(Closed $gBugs are archived $gRemoveAge days after the last related message is received.)";
+$gTextExpireNote = "; (Closed $gBugs are archived $gRemoveAge days after the last related message is received.)\n";
 
 ############################################################################
 # Makeup of the stamp page

Reply to: