X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FView.pm;h=52d37a9ff690dbb32cc501ef0867137e0bc3b9fb;hb=5ca29b7f2789517f0a41f1482509f504b8b601e1;hp=446e6bb84ee18dee7a6cc1385211e0d72550ae8c;hpb=a4eba23d05802c6d522ac8d61b781f2f1417a93b;p=public-inbox.git diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index 446e6bb8..52d37a9f 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -38,14 +38,12 @@ sub msg_page_i { : $ctx->gone('over'); $ctx->{mhref} = ($ctx->{nr} || $ctx->{smsg}) ? "../${\mid_href($smsg->{mid})}/" : ''; - my $obuf = _msg_page_prepare_obuf($eml, $ctx); - if (length($$obuf)) { - multipart_text_as_html($eml, $ctx); - $$obuf .= '
' . eml_entry($ctx, $eml) . '' . $end; + $ctx->zmore($beg.'
'); + eml_entry($ctx, $eml) . '' . $end; } sub next_in_queue ($$) { @@ -436,7 +432,7 @@ sub stream_thread_i { # PublicInbox::WwwStream::getline callback sub stream_thread ($$) { my ($rootset, $ctx) = @_; @{$ctx->{-queue}} = map { (0, $_) } @$rootset; - PublicInbox::WwwStream::aresponse($ctx, 200, \&stream_thread_i); + PublicInbox::WwwStream::aresponse($ctx, \&stream_thread_i); } # /$INBOX/$MSGID/t/ and /$INBOX/$MSGID/T/ @@ -487,7 +483,7 @@ EOF # flat display: lazy load the full message from smsg $ctx->{msgs} = $msgs; $ctx->{-html_tip} = '
'; - PublicInbox::WwwStream::aresponse($ctx, 200, \&thread_html_i); + PublicInbox::WwwStream::aresponse($ctx, \&thread_html_i); } sub thread_html_i { # PublicInbox::WwwStream::getline callback @@ -509,26 +505,14 @@ sub thread_html_i { # PublicInbox::WwwStream::getline callback } } -sub multipart_text_as_html { - # ($mime, $ctx) = @_; # each_part may do "$_[0] = undef" - - # scan through all parts, looking for displayable text - $_[0]->each_part(\&add_text_body, $_[1], 1); -} - sub submsg_hdr ($$) { my ($ctx, $eml) = @_; - my $obfs_ibx = $ctx->{-obfs_ibx}; - my $rv = $ctx->{obuf}; - $$rv .= "\n"; + my $s = "\n"; for my $h (qw(From To Cc Subject Date Message-ID X-Alt-Message-ID)) { - my @v = $eml->header($h); - for my $v (@v) { - obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; - $v = ascii_html($v); - $$rv .= "$h: $v\n"; - } + $s .= "$h: $_\n" for $eml->header($h); } + obfuscate_addrs($ctx->{-obfs_ibx}, $s) if $ctx->{-obfs_ibx}; + ascii_html($s); } sub attach_link ($$$$;$) { @@ -539,7 +523,6 @@ sub attach_link ($$$$;$) { # downloads for 0-byte multipart attachments return unless $part->{bdy}; - my $nl = $idx eq '1' ? '' : "\n"; # like join("\n", ...) my $size = length($part->body); delete $part->{bdy}; # save memory @@ -555,23 +538,17 @@ sub attach_link ($$$$;$) { } else { $sfn = 'a.bin'; } - my $rv = $ctx->{obuf}; - $$rv .= qq($nl{mhref}$idx-$sfn">); - if ($err) { - $$rv .= <{mhref}$idx-$sfn">); + $rv .= < \n"; - - submsg_hdr($ctx, $part) if $part->{is_submsg}; - - undef; + $rv .= ascii_html($desc)." --]\n[-- " if $desc ne ''; + $rv .= "Type: $ct, Size: $size bytes --]\n"; + $rv .= submsg_hdr($ctx, $part) if $part->{is_submsg}; + $rv; } sub add_text_body { # callback for each_part @@ -583,12 +560,11 @@ sub add_text_body { # callback for each_part my ($part, $depth, $idx) = @$p; my $ct = $part->content_type || 'text/plain'; my $fn = $part->filename; - my ($s, $err) = msg_part_text($part, $ct); - return attach_link($ctx, $ct, $p, $fn) unless defined $s; - my $rv = $ctx->{obuf}; + my ($s, $err) = msg_part_text($part, $ct); + $s // return $$rv .= (attach_link($ctx, $ct, $p, $fn) // ''); if ($part->{is_submsg}) { - submsg_hdr($ctx, $part); + $$rv .= submsg_hdr($ctx, $part); $$rv .= "\n"; } @@ -638,7 +614,7 @@ sub add_text_body { # callback for each_part undef $s; # free memory if (defined($fn) || ($depth > 0 && !$part->{is_submsg}) || $err) { # badly-encoded message with $err? tell the world about it! - attach_link($ctx, $ct, $p, $fn, $err); + $$rv .= attach_link($ctx, $ct, $p, $fn, $err); $$rv .= "\n"; } delete $part->{bdy}; # save memory @@ -659,94 +635,97 @@ sub add_text_body { # callback for each_part } } -sub _msg_page_prepare_obuf { +sub _msg_page_prepare { my ($eml, $ctx) = @_; my $have_over = !!$ctx->{ibx}->over; - my $obfs_ibx = $ctx->{-obfs_ibx}; - $ctx->{obuf} = \(my $rv = ''); my $mids = mids_for_index($eml); my $nr = $ctx->{nr}++; if ($nr) { # unlikely if ($ctx->{chash} eq content_hash($eml)) { warn "W: BUG? @$mids not deduplicated properly\n"; - return \$rv; + return; } - $rv .= + $ctx->{-html_tip} = "header('Content-Description') // $fn // ''; - $desc = ascii_html($desc); - $$rv .= ($desc eq '') ? "$ts --]" : "$desc --]\n[-- $ts --]"; - $$rv .= " WARNING: multiple messages have this Message-ID\n"; } else { $ctx->{first_hdr} = $eml->header_obj; $ctx->{chash} = content_hash($eml) if $ctx->{smsg}; # reused MID - $rv .= ""; # anchor for body start + $ctx->{-html_tip} = ""; # anchor for body start } $ctx->{-upfx} = '../'; my @title; # (Subject[0], From[0]) + my $hbuf = ''; for my $v ($eml->header('From')) { my @n = PublicInbox::Address::names($v); - $v = ascii_html($v); - $title[1] //= ascii_html(join(', ', @n)); - if ($obfs_ibx) { - obfuscate_addrs($obfs_ibx, $v); - obfuscate_addrs($obfs_ibx, $title[1]); - } - $rv .= "From: $v\n" if $v ne ''; + $title[1] //= join(', ', @n); + $hbuf .= "From: $v\n" if $v ne ''; } - foreach my $h (qw(To Cc)) { + for my $h (qw(To Cc)) { for my $v ($eml->header($h)) { fold_addresses($v); - $v = ascii_html($v); - obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; - $rv .= "$h: $v\n" if $v ne ''; + $hbuf .= "$h: $v\n" if $v ne ''; } } my @subj = $eml->header('Subject'); - if (@subj) { - my $v = ascii_html(shift @subj); - obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; - $rv .= 'Subject: '; - $rv .= $have_over ? qq($v\n) : "$v\n"; - $title[0] = $v; - for $v (@subj) { # multi-Subject message :< - $v = ascii_html($v); - obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; - $rv .= "Subject: $v\n"; - } - } else { # dummy anchor for thread skeleton at bottom of page - $rv .= qq() if $have_over; - $title[0] = '(no subject)'; - } - for my $v ($eml->header('Date')) { - $v = ascii_html($v); - obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; # possible :P - $rv .= qq{Date: $v\n}; + $hbuf .= "Subject: $_\n" for @subj; + $title[0] = $subj[0] // '(no subject)'; + $hbuf .= "Date: $_\n" for $eml->header('Date'); + $hbuf = ascii_html($hbuf); + $ctx->{-title_html} = ascii_html(join(' - ', @title)); + if (my $obfs_ibx = $ctx->{-obfs_ibx}) { + obfuscate_addrs($obfs_ibx, $hbuf); + obfuscate_addrs($obfs_ibx, $ctx->{-title_html}); } + # [thread overview] link is typically added after Date, # but added after Subject, or even nothing. if ($have_over) { - chop $rv; # drop "\n", or noop if $rv eq '' - $rv .= qq{\t[thread overview]\n}; + chop $hbuf; # drop "\n", or noop if $rv eq '' + $hbuf .= qq{\t[thread overview]\n}; + $hbuf =~ s!^Subject:\x20(.*?)(\n[A-Z]|\z) + !Subject: $1$2!msx or + $hbuf .= qq(); + } + if (scalar(@$mids) == 1) { # common case + my $x = ascii_html($mids->[0]); + $hbuf .= qq[Message-ID: <$x> (raw)\n]; } if (!$nr) { # first (and only) message, common case - $ctx->{-title_html} = join(' - ', @title); - $rv = $ctx->html_top . $rv; + $ctx->zmore($ctx->html_top, $hbuf); + } else { + delete $ctx->{-title_html}; + $ctx->zmore($ctx->{-html_tip}, $hbuf); } - $ctx->{-linkify} //= PublicInbox::Linkify->new; - if (scalar(@$mids) == 1) { # common case - my $mhtml = ascii_html($mids->[0]); - $rv .= qq[Message-ID: <$mhtml> (raw)\n]; - } else { + $hbuf = ''; + if (scalar(@$mids) != 1) { # unlikely, but it happens :< # X-Alt-Message-ID can happen if a message is injected from # public-inbox-nntpd because of multiple Message-ID headers. - my $s = ''; for my $h (qw(Message-ID X-Alt-Message-ID)) { - $s .= "$h: $_\n" for ($eml->header_raw($h)); + $hbuf .= "$h: $_\n" for ($eml->header_raw($h)); } - $ctx->{-linkify}->linkify_mids('..', \$s, 1); - $rv .= $s; + $ctx->{-linkify}->linkify_mids('..', \$hbuf, 1); # escapes HTML + $ctx->zmore($hbuf); + $hbuf = ''; } - _parent_headers($ctx, $eml); - $rv .= "\n"; - \$rv; + my @irt = $eml->header_raw('In-Reply-To'); + my $refs; + if (!@irt) { + $refs = references($eml); + $irt[0] = pop(@$refs) if scalar @$refs; + } + $hbuf .= "In-Reply-To: $_\n" for @irt; + + # do not display References: if search is present, + # we show the thread skeleton at the bottom, instead. + if (!$have_over) { + $refs //= references($eml); + $hbuf .= 'References: <'.join(">\n\t<", @$refs).">\n" if @$refs; + } + $ctx->{-linkify}->linkify_mids('..', \$hbuf); # escapes HTML + $ctx->zmore($hbuf .= "\n"); + ${$ctx->{obuf}} = ''; # TODO remove + 1; } sub SKEL_EXPAND () { @@ -795,45 +774,11 @@ sub thread_skel ($$$) { $ctx->{parent_msg} = $parent; } -sub _parent_headers { - my ($ctx, $hdr) = @_; - my @irt = $hdr->header_raw('In-Reply-To'); - my $refs; - if (@irt) { - my $s = ''; - $s .= "In-Reply-To: $_\n" for @irt; - $ctx->{-linkify}->linkify_mids('..', \$s); - ${$ctx->{obuf}} .= $s; - } else { - $refs = references($hdr); - my $irt = pop @$refs; - if (defined $irt) { - my $html = ascii_html($irt); - my $href = mid_href($irt); - ${$ctx->{obuf}} .= <$html> -EOM - } - } - - # do not display References: if search is present, - # we show the thread skeleton at the bottom, instead. - return if $ctx->{ibx}->over; - - $refs //= references($hdr); - if (@$refs) { - $_ = linkify_ref_no_over($_) for @$refs; - ${$ctx->{obuf}} .= 'References: '. join("\n\t", @$refs) . "\n"; - } -} - -# returns a string buffer +# appends to obuf sub html_footer { my ($ctx, $hdr) = @_; my $upfx = '../'; - my $skel; - my $rv = ' '; - my $related; + my ($related, $skel); my $qry = delete $ctx->{-qry}; if ($qry && $ctx->{ibx}->isrch) { my $q = ''; # search for either ancestor or descendent patches @@ -896,22 +841,15 @@ EOF } elsif ($u) { # unlikely $parent = " parent"; } - $rv .= "$next $prev$parent "; + ${$ctx->{obuf}} .= "$next $prev$parent "; } else { # unindexed inboxes w/o over + ${$ctx->{obuf}} .= '' . ($related // ''); + $ctx->zmore($skel .= msg_reply($ctx, $hdr)); # flushes obuf } sub ghost_parent {'; $skel = qq( latest); } - $rv .= qq(reply); - $rv .= $skel; - $rv .= ''; - $rv .= $related // ''; - $rv .= msg_reply($ctx, $hdr); -} - -sub linkify_ref_no_over { - my ($mid) = @_; - my $href = mid_href($mid); - my $html = ascii_html($mid); - "<$html>"; + ${$ctx->{obuf}} .= qq(reply); + # $skel may be big for big threads, don't append it to obuf + $skel .= '