print header( -type => 'application/mbox', -charset => 'utf-8', );
},
Message => sub ($) {
- my $m = shift;
- eval {
- my $fh;
-
- # Could forge a placeholder for messages which aren't present here.
-
- $fh = $m->headers;
- print for (<$fh>);
-
- print "\n";
-
- $fh = $m->body;
- print for (<$fh>);
- };
-
- # Ignore errors...
+ eval { format_raw(shift) }; # Ignore errors...
},
Footer => sub () { }
},
use Emesinae::Common;
use Emesinae::CGI;
+use Emesinae::CGI::Message;
+
+use URI::Escape;
readconfig;
my $dbh = opendb;
exit(0);
}
-# Not implemented yet.
-fourohfour();
+# Parse path to determine message number (or ID) and (optional) mode (raw, part
+# etc):
+
+my $path = url( -absolute => 1 );
+
+$path =~ s,^$c{CGIPath},, or fourohfour();
+$path =~ m,^(mid|message)/, or fourohfoud();
+my $lookup_key = $1;
+$path =~ s,^$lookup_key,,;
+
+my $idre;
+if ( $lookup_key eq "message" ) { $idre = "[0-9]+"; }
+elsif ( $lookup_key eq "mid" ) { $idre = ".+?"; } # Not greedy.
+die "unknown key" unless $idre;
+
+$path =~ m,^/($idre)(?:/(raw|part/[0-9]+))?/?$, or fourohfour();
+
+my $lookup_value = $1;
+
+my $mode = $2 || "normal";
+
+my ( $msg, $partid );
+
+if ( $mode =~ m,^part/([0-9]+)/?$, ) {
+ $mode = "part";
+ $partid = $1;
+}
+
+eval {
+ if ( $lookup_key eq "message" )
+ {
+ $msg = Emesinae::Message->lookup_id( $dbh, $lookup_value );
+ }
+ elsif ( $lookup_key eq "mid" ) {
+ $lookup_value = uri_unescape($lookup_value);
+ $msg = Emesinae::Message->lookup_msgid( $dbh, $lookup_value );
+ }
+};
+fourohfour() if $@;
+fourohfour() unless $msg;
+
+if ( $mode eq "raw" ) {
+ print header( -type => 'text/plain', -charset => 'utf-8' );
+ format_raw($msg) or print "Message not present in archive\n";
+}
+elsif ( $mode eq "normal" ) {
+ print header( -charset => 'utf-8', );
+
+ my $title;
+ if ( $msg->{present} ) {
+ $title =
+ "message " . $msg->{id} . " - " . htmlsanit( $msg->{subject}->text );
+ }
+ else {
+ $title = "message " . $msg->{id} . " - (Not Present)";
+ }
+ print start_html(
+ -title => $c{TrackerName} . ": " . $title,
+ -style => { 'src' => $c{StyleSheet} }
+ );
+ format_html( $msg, undef );
+ print end_html;
+}
+elsif ( $mode eq "part" ) {
+ fourohfour unless $msg->{present};
+ format_part( $msg, $partid );
+
+}
use Emesinae::Common;
use Emesinae::CGI;
+use IO::Scalar;
+
BEGIN {
use Exporter ();
our ( $VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS );
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(
- format_html
+ format_html
+ format_raw
+ format_part
);
%EXPORT_TAGS = ();
}
sub reply_link ($$) {
- my $m = shift;
+ my $m = shift;
my $bug = shift;
my $p = $m->{present};
+ return "" unless $p and defined $bug;
+
my %hdrs = ( "In-Reply-To" => $m->{msgid}, );
my $to = join( ",", $m->{from}->addresses );
. " ($type, $disposition)" . "]";
}
-sub format_html ($$) {
- my $m = shift;
+sub format_html ($;$) {
+ my $m = shift;
my $bug = shift;
print comment( "Message "
)
)
) . "\n";
+ my $reply = reply_link( $m, $bug );
+ $reply .= "; " if $reply;
print p(
{ -class => "msgcontrol" },
- "[ "
- . reply_link($m, $bug) . "; "
+ "[ "
+ . $reply
. raw_link($m) . "; "
. "Archives: "
. join( ", ", @archives ) . " ]"
}
}
+sub format_raw($) {
+ my $m = shift;
+ my $fh;
+
+ # Could forge a placeholder for messages which aren't present here.
+ return 0 unless $m->{present};
+
+ $fh = $m->headers;
+ print for (<$fh>);
+
+ print "\n";
+
+ $fh = $m->body;
+ print for (<$fh>);
+
+ return 1;
+}
+
+sub format_part($$) {
+ my $m = shift;
+ my $part = shift;
+
+ my $tempdir = File::Temp::tempdir();
+ my $e = $m->get_mime($tempdir);
+
+ my @parts = getmailparts($e);
+ my $entity = $parts[ $part - 1 ];
+ my $head = $entity->head;
+
+ my $filename = $head->recommended_filename;
+ $filename = '' unless defined $filename;
+
+ my $body = $entity->stringify_body;
+
+ chomp( my $type = $entity->effective_type );
+ print "Content-Type: $type";
+ print "; name=\"$filename\"" if $filename ne '';
+ print "\n\n";
+ my $decoder = new MIME::Decoder( $head->mime_encoding );
+ $decoder->decode( new IO::Scalar( \$body ), \*STDOUT );
+
+ rmtree $tempdir, 0, 1;
+}
+
1;
libmime-tools-perl
libdbd-sqlite3-perl
liburi-perl
+ libio-stringy-perl
libjs-jquery
- SEO
- make sure there is an index page of all bugs for them to start from
-message.pl:
- - Write it
- - return entire raw message
- - return individual parts
-
database:
- Add "created-by" and "reported-by" fields to bug, allow owner to be NULL by
default.
Alias /test/static/ /srv/test/var/www/
ScriptAliasMatch /test/bug/.* /srv/test/lib/emesinae/cgi-bin/bug.cgi
ScriptAliasMatch /test/message/.* /srv/test/lib/emesinae/cgi-bin/message.cgi
+ ScriptAliasMatch /test/mid/.* /srv/test/lib/emesinae/cgi-bin/message.cgi
ScriptAlias /test/ /srv/test/lib/emesinae/cgi-bin/bugs.cgi
<Directory "/srv/test/lib/emesinae/cgi-bin">
AllowOverride None
Alias /xen/static/ /srv/xen-devel-bugs/var/www/
ScriptAliasMatch /xen/bug/.* /srv/xen-devel-bugs/lib/emesinae/cgi-bin/bug.cgi
ScriptAliasMatch /xen/message/.* /srv/xen-devel-bugs/lib/emesinae/cgi-bin/message.cgi
+ ScriptAliasMatch /xen/mid/.* /srv/test/lib/emesinae/cgi-bin/message.cgi
ScriptAlias /xen/ /srv/xen-devel-bugs/lib/emesinae/cgi-bin/bugs.cgi
<Directory "/srv/xen-devel-bugs/lib/emesinae/cgi-bin">
AllowOverride None