X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FView.pm;h=534f85ef9b8110ca86e992d18118be2499786309;hb=31afda256c813443062e0504213d41732e50ee45;hp=326da4cb1e7efde9bc508ed7e3e6d29b72b431a3;hpb=78042ed9abb2bbe9783adcc485365a8672e4b36f;p=public-inbox.git diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index 326da4cb..534f85ef 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -8,67 +8,70 @@ use strict; use warnings; use URI::Escape qw/uri_escape_utf8/; use Date::Parse qw/str2time/; -use Encode qw/find_encoding/; use Encode::MIME::Header; +use Plack::Util; use PublicInbox::Hval qw/ascii_html/; use PublicInbox::Linkify; use PublicInbox::MID qw/mid_clean id_compress mid2path mid_mime/; use PublicInbox::MsgIter; +use PublicInbox::Address; require POSIX; use constant INDENT => ' '; use constant TCHILD => '` '; sub th_pfx ($) { $_[0] == 0 ? '' : TCHILD }; -# public functions: +# public functions: (unstable) +# TODO: stream this, since threading is expensive but also oh-so-important sub msg_html { my ($ctx, $mime, $footer) = @_; $footer = defined($footer) ? "\n$footer" : ''; my $hdr = $mime->header_obj; - headers_to_html_header($hdr, $ctx) . - multipart_text_as_html($mime, '') . - '
' .
-		html_footer($hdr, 1, $ctx, 'R/') .
-		$footer .
-		'
'; + my $n = 0; + Plack::Util::inline_object( + close => sub {}, # noop + getline => sub { + my $nr = $n++; + if ($nr == 0) { + headers_to_html_header($hdr, $ctx) . + multipart_text_as_html($mime, '') . + '
' + } elsif ($nr == 1) { + '
' .
+					html_footer($hdr, 1, $ctx) .
+					'
' . msg_reply($ctx, $hdr) . + '
'.  $footer .
+					'
' + } else { + undef + } + } + ) } -# /$INBOX/$MESSAGE_ID/R/ +# /$INBOX/$MESSAGE_ID/#R sub msg_reply { - my ($ctx, $hdr, $footer) = @_; - my $s = $hdr->header('Subject'); - $s = '(no subject)' if (!defined $s) || ($s eq ''); - my $f = $hdr->header('From'); - $f = '' unless defined $f; - my $mid = $hdr->header_raw('Message-ID'); - $mid = PublicInbox::Hval->new_msgid($mid); - my $t = ascii_html($s); + my ($ctx, $hdr) = @_; my $se_url = 'https://kernel.org/pub/software/scm/git/docs/git-send-email.html'; my ($arg, $link) = mailto_arg_link($hdr); push @$arg, '/path/to/YOUR_REPLY'; - "replying to \"$t\"
" .
-	"replying to message:\n\n" .
-	"Subject: $t\n" .
-	"From: ". ascii_html($f) .
-	"\nDate: " .  ascii_html($hdr->header('Date')) .
-	"\nMessage-ID: <" . $mid->as_html . ">\n\n" .
-	"There are multiple ways to reply:\n\n" .
+	"
". + "You may reply publically to this message via\n". + "plain-text email using any one of the following methods:\n\n" . "* Save the following mbox file, import it into your mail client,\n" . - " and reply-to-all from there: mbox\n\n" . + " and reply-to-all from there: mbox\n\n" . "* Reply to all the recipients using the --to, --cc,\n" . " and --in-reply-to switches of git-send-email(1):\n\n" . "\tgit send-email \\\n\t\t" . - join(" \\ \n\t\t", @$arg ). "\n\n" . + join(" \\\n\t\t", @$arg ). "\n\n" . qq( $se_url\n\n) . "* If your mail client supports setting the In-Reply-To" . " header\n via mailto: links, try the " . qq(mailto: link\n) . - "\nFor context, the original message or " . - qq(thread) . - '

' . $footer .  '
'; + ''; } sub in_reply_to { @@ -99,9 +102,7 @@ sub index_entry { $seen->{$id} = "#$id"; # save the anchor for children, later my $mid = PublicInbox::Hval->new_msgid($mid_raw); - my $from = $hdr->header('From'); - my @from = Email::Address->parse($from); - $from = $from[0]->name; + my $from = PublicInbox::Address::from_name($hdr->header('From')); my $root_anchor = $state->{root_anchor} || ''; my $path = $root_anchor ? '../../' : ''; @@ -125,7 +126,7 @@ sub index_entry { # scan through all parts, looking for displayable text msg_iter($mime, sub { index_walk($fh, $mhref, $_[0]) }); - $rv = "\n" . html_footer($hdr, 0, $ctx, "$path$href/R/"); + $rv = "\n" . html_footer($hdr, 0, $ctx, "$path$href/#R"); if (defined $irt) { unless (defined $parent_anchor) { @@ -191,7 +192,6 @@ sub emit_thread_html { ('' x ($max - 1)) . ''); } } - Email::Address->purge_cache; # there could be a race due to a message being deleted in git # but still being in the Xapian index: @@ -260,17 +260,18 @@ sub attach_link ($$$$) { my $desc = $part->header('Content-Description'); $desc = $fn unless defined $desc; $desc = '' unless defined $desc; - $desc = ': '.$desc if $desc; my $sfn; - if (defined $fn && $fn =~ /\A[\w-]+\.[a-z0-9]+\z/) { + if (defined $fn && $fn =~ /\A[[:alnum:]][\w\.-]+[[:alnum:]]\z/) { $sfn = $fn; } elsif ($ct eq 'text/plain') { $sfn = 'a.txt'; } else { $sfn = 'a.bin'; } - qq($nl[-- Attachment #$idx$desc --]\n) . - "[-- Type: $ct, Size: $size bytes --]" + my @ret = qq($nl[-- Attachment #$idx: ); + my $ts = "Type: $ct, Size: $size bytes"; + push(@ret, ($desc eq '') ? "$ts --]" : "$desc --]\n[-- $ts --]"); + join('', @ret, ''); } sub add_text_body { @@ -338,8 +339,8 @@ sub headers_to_html_header { $v = PublicInbox::Hval->new($v); if ($h eq 'From') { - my @from = Email::Address->parse($v->raw); - $title[1] = ascii_html($from[0]->name); + my $n = PublicInbox::Address::from_name($v->raw); + $title[1] = ascii_html($n); } elsif ($h eq 'Subject') { $title[0] = $v->as_html; if ($srch) { @@ -448,15 +449,13 @@ sub mailto_arg_link { foreach my $h (qw(From To Cc)) { my $v = $hdr->header($h); defined($v) && ($v ne '') or next; - my @addrs = Email::Address->parse($v); - foreach my $recip (@addrs) { - my $address = $recip->address; + my @addrs = PublicInbox::Address::emails($v); + foreach my $address (@addrs) { my $dst = lc($address); $cc{$dst} ||= $address; $to ||= $dst; } } - Email::Address->purge_cache; my @arg; my $subj = $hdr->header('Subject') || ''; @@ -506,8 +505,9 @@ sub html_footer { } else { $irt = ''; } - - $irt . qq(reply) . $idx; + $rhref ||= '#R'; + $irt .= qq(reply); + $irt .= $idx; } sub linkify_ref_nosrch { @@ -839,13 +839,12 @@ sub emit_topics { sub emit_index_topics { my ($state) = @_; - my $off = $state->{ctx}->{cgi}->param('o'); - $off = 0 unless defined $off; + my ($off) = (($state->{ctx}->{cgi}->param('o') || '0') =~ /(\d+)/); $state->{order} = []; $state->{subjs} = {}; $state->{latest} = {}; my $max = 25; - my %opts = ( offset => int $off, limit => $max * 4 ); + my %opts = ( offset => $off, limit => $max * 4 ); while (scalar @{$state->{order}} < $max) { my $sres = $state->{srch}->query('', \%opts); my $nr = scalar @{$sres->{msgs}} or last;