From d0755b0e3693b8497e7232cb31a53686a3181eb8 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 5 Apr 2014 01:11:08 +0000 Subject: view: implement quote folding and flesh out tests Unfortunately, quoting is often excessive, so hide multi-line quotes by default and provide anchored links to full messages instead. --- lib/PublicInbox/View.pm | 61 +++++++++++++++++++++++++++++++++++++++++++------ t/view.t | 57 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 9 deletions(-) diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index 08849a92..3d3b6b5e 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -9,17 +9,17 @@ use Encode::MIME::Header; # only one public function: sub as_html { - my ($class, $mime) = @_; + my ($class, $mime, $full_pfx) = @_; headers_to_html_header($mime) . - multipart_text_as_html($mime) . + multipart_text_as_html($mime, $full_pfx) . "\n"; } # only private functions below. sub multipart_text_as_html { - my ($mime) = @_; + my ($mime, $full_pfx) = @_; my $rv = ""; my $part_nr = 0; @@ -33,15 +33,19 @@ sub multipart_text_as_html { my $fn = $part->filename; if ($part_nr > 0) { - defined($fn) or $fn = "part #$part_nr"; + defined($fn) or $fn = "part #" . ($part_nr + 1); $rv .= add_filename_line($fn); } - # n.b. $part->body should already be decoded if text - $rv .= escapeHTML($part->body); + if (defined $full_pfx) { + $rv .= add_text_body_short($part, $part_nr, + $full_pfx); + } else { + $rv .= add_text_body_full($part, $part_nr); + } $rv .= "\n" unless $rv =~ /\n\z/s; } else { - $rv .= "-- part #$part_nr "; + $rv .= "-- part #" . ($part_nr + 1) . " "; $rv .= escapeHTML($part_type); $rv .= " skipped\n"; } @@ -60,6 +64,49 @@ sub add_filename_line { "$pad " . escapeHTML($fn) . " $pad\n"; } +sub add_text_body_short { + my ($part, $part_nr, $full_pfx) = @_; + my $n = 0; + my $s = escapeHTML($part->body); + $s =~ s!^((?:(?:>[^\n]+)\n)+)! + my $cur = $1; + my @lines = split(/\n/, $cur); + if (@lines > 1) { + # show a short snippet of quoted text + $cur = join(' ', @lines); + $cur =~ s/> ?//g; + + my @sum = split(/\s+/, $cur); + $cur = ''; + do { + $cur .= shift(@sum) . ' '; + } while (@sum && length($cur) < 68); + $cur=~ s/ \z/ .../; + "> <$cur<\/a>>"; + } else { + $cur; + } + !emg; + $s; +} + +sub add_text_body_full { + my ($part, $part_nr) = @_; + my $n = 0; + my $s = escapeHTML($part->body); + $s =~ s!^((?:(?:>[^\n]+)\n)+)! + my $cur = $1; + my @lines = split(/\n/, $cur); + if (@lines > 1) { + "$cur"; + } else { + $cur; + } + !emg; + $s; +} + sub trim_message_id { my ($mid) = @_; $mid =~ tr/<>//d; diff --git a/t/view.t b/t/view.t index df79bd49..fbdbd884 100644 --- a/t/view.t +++ b/t/view.t @@ -8,6 +8,17 @@ use PublicInbox::View; # plain text { + my $body = < keep this inline + +OK + +> Long and wordy reply goes here and it is split across multiple lines. +> We generate links to a separate full page where quoted-text is inline. + +hello world +EOF my $s = Email::Simple->create( header => [ From => 'a@example.com', @@ -16,7 +27,7 @@ use PublicInbox::View; 'Message-ID' => '', Subject => 'this is a subject', ], - body => "hello world\n", + body => $body, ); $s = Email::MIME->new($s->as_string); my $html = PublicInbox::View->as_html($s); @@ -24,6 +35,18 @@ use PublicInbox::View; # ghetto like($html, qr/]+>> Long and wordy/, + "long quoted text is anchored"); + + # short page + my $pfx = "http://example.com/test/full"; + my $short = PublicInbox::View->as_html($s, $pfx); + like($short, qr/\n> keep this inline/, + "short quoted text is inline"); + like($short, qr/]+>Long and wordy/, + "long quoted text is made into a link"); + ok(length($short) < length($html), "short page is shorter"); } # multipart crap @@ -49,7 +72,37 @@ use PublicInbox::View; ); my $html = PublicInbox::View->as_html($mime); - print $html; + like($html, qr/hi\n-+ part #2 -+\nbye\n/, "multipart split"); +} + +# multipart email with attached patch +{ + my $parts = [ + Email::MIME->create( + attributes => { content_type => 'text/plain', }, + body => 'hi, see attached patch', + ), + Email::MIME->create( + attributes => { + content_type => 'text/plain', + filename => "foo.patch", + }, + body => "--- a/file\n+++ b/file\n" . + "@@ -49, 7 +49,34 @@\n", + ), + ]; + my $mime = Email::MIME->create( + header_str => [ + From => 'a@example.com', + Subject => '[PATCH] asdf', + 'Message-ID' => '', + ], + parts => $parts, + ); + + my $html = PublicInbox::View->as_html($mime); + like($html, qr!see attached patch\n-+ foo\.patch -+\n--- a/file\n!, + "parts split with filename"); } done_testing(); -- cgit v1.2.3-24-ge0c7