X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2FPublicInbox%2FView.pm;h=9c3ef104f1a83ab28edfce75cf2ce2308ad3af76;hb=6c853f5256f3a324c018a37a9e8a6b9fc8fdc063;hp=d7ec4eb0a1a63f2500b911eaa4638bd7565e21a3;hpb=ba212558b86874d197c86e2acd0776b5b095ee5b;p=public-inbox.git diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index d7ec4eb0..9c3ef104 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -7,8 +7,10 @@ package PublicInbox::View; use strict; use warnings; use bytes (); # only for bytes::length +use List::Util qw(max); use PublicInbox::MsgTime qw(msg_datestamp); -use PublicInbox::Hval qw(ascii_html obfuscate_addrs prurl mid_href); +use PublicInbox::Hval qw(ascii_html obfuscate_addrs prurl mid_href + ts2str fmt_ts); use PublicInbox::Linkify; use PublicInbox::MID qw(id_compress mids mids_for_index references $MID_EXTRACT); @@ -18,7 +20,6 @@ use PublicInbox::WwwStream qw(html_oneshot); use PublicInbox::Reply; use PublicInbox::ViewDiff qw(flush_diff); use PublicInbox::Eml; -use POSIX qw(strftime); use Time::Local qw(timegm); use PublicInbox::Smsg qw(subject_normalized); use constant COLS => 72; @@ -33,8 +34,7 @@ sub msg_page_i { $ctx->{smsg} = $ctx->{over}->next_by_mid(@{$ctx->{next_arg}}); $ctx->{mhref} = ($ctx->{nr} || $ctx->{smsg}) ? "../${\mid_href($smsg->{mid})}/" : ''; - my $hdr = $eml->header_obj; - my $obuf = $ctx->{obuf} = _msg_page_prepare_obuf($hdr, $ctx); + my $obuf = $ctx->{obuf} = _msg_page_prepare_obuf($eml, $ctx); multipart_text_as_html($eml, $ctx); delete $ctx->{obuf}; $$obuf .= '
sub eml_entry { @@ -199,16 +201,15 @@ sub eml_entry { # Deleting these fields saves about 400K as we iterate across 1K msgs delete @$smsg{qw(ts blob)}; - my $hdr = $eml->header_obj; - my $from = _hdr_names_html($hdr, 'From'); + my $from = _hdr_names_html($eml, 'From'); obfuscate_addrs($obfs_ibx, $from) if $obfs_ibx; $rv .= "From: $from @ ".fmt_ts($ds)." UTC"; my $upfx = $ctx->{-upfx}; my $mhref = $upfx . mid_href($mid_raw) . '/'; $rv .= qq{ (permalink / }; $rv .= qq{raw)\n}; - my $to = fold_addresses(_hdr_names_html($hdr, 'To')); - my $cc = fold_addresses(_hdr_names_html($hdr, 'Cc')); + my $to = fold_addresses(_hdr_names_html($eml, 'To')); + my $cc = fold_addresses(_hdr_names_html($eml, 'Cc')); my ($tlen, $clen) = (length($to), length($cc)); my $to_cc = ''; if (($tlen + $clen) > COLS) { @@ -227,7 +228,7 @@ sub eml_entry { $rv .= $to_cc; my $mapping = $ctx->{mapping}; - if (!$mapping && (defined($irt) || defined($irt = in_reply_to($hdr)))) { + if (!$mapping && (defined($irt) || defined($irt = in_reply_to($eml)))) { my $href = $upfx . mid_href($irt) . '/'; my $html = ascii_html($irt); $rv .= qq(In-Reply-To: <$html>\n) @@ -423,9 +424,20 @@ sub thread_html { my $ibx = $ctx->{-inbox}; my ($nr, $msgs) = $ibx->over->get_thread($mid); return missing_thread($ctx) if $nr == 0; + + # link $INBOX_DIR/description text to "index_topics" view around + # the newest message in this thread + my $t = ts2str($ctx->{-t_max} = max(map { delete $_->{ts} } @$msgs)); + my $t_fmt = fmt_ts($ctx->{-t_max}); + my $skel = ''; $skel .= $nr == 1 ? 'only message in thread' : 'end of thread'; - $skel .= ", back to index\n\n"; + $skel .= <~$t_fmt UTC | newest] + +EOF $skel .= "Thread overview: "; $skel .= $nr == 1 ? '(only message)' : "$nr+ messages"; $skel .= " (download: mbox.gz"; @@ -626,16 +638,16 @@ sub add_text_body { # callback for each_part } sub _msg_page_prepare_obuf { - my ($hdr, $ctx) = @_; + my ($eml, $ctx) = @_; my $over = $ctx->{-inbox}->over; my $obfs_ibx = $ctx->{-obfs_ibx}; my $rv = ''; - my $mids = mids_for_index($hdr); + my $mids = mids_for_index($eml); my $nr = $ctx->{nr}++; if ($nr) { # unlikely $rv .= ' '; } else { - $ctx->{first_hdr} = $hdr; + $ctx->{first_hdr} = $eml->header_obj; if ($ctx->{smsg}) { $rv .= "WARNING: multiple messages have this Message-ID\n"; @@ -644,7 +656,7 @@ sub _msg_page_prepare_obuf { } $ctx->{-upfx} = '../' if $over; my @title; # (Subject[0], From[0]) - for my $v ($hdr->header('From')) { + for my $v ($eml->header('From')) { my @n = PublicInbox::Address::names($v); $v = ascii_html($v); $title[1] //= ascii_html(join(', ', @n)); @@ -655,14 +667,14 @@ sub _msg_page_prepare_obuf { $rv .= "From: $v\n" if $v ne ''; } foreach my $h (qw(To Cc)) { - for my $v ($hdr->header($h)) { + 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 ''; } } - my @subj = $hdr->header('Subject'); + my @subj = $eml->header('Subject'); if (@subj) { my $v = ascii_html(shift @subj); obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; @@ -678,7 +690,7 @@ sub _msg_page_prepare_obuf { $rv .= qq() if $over; $title[0] = '(no subject)'; } - for my $v ($hdr->header('Date')) { + for my $v ($eml->header('Date')) { $v = ascii_html($v); obfuscate_addrs($obfs_ibx, $v) if $obfs_ibx; # possible :P $rv .= "Date: $v\n"; @@ -697,12 +709,12 @@ sub _msg_page_prepare_obuf { my $lnk = PublicInbox::Linkify->new; my $s = ''; for my $h (qw(Message-ID X-Alt-Message-ID)) { - $s .= "$h: $_\n" for ($hdr->header_raw($h)); + $s .= "$h: $_\n" for ($eml->header_raw($h)); } $lnk->linkify_mids('..', \$s, 1); $rv .= $s; } - $rv .= _parent_headers($hdr, $over); + $rv .= _parent_headers($eml, $over); $rv .= "\n"; \$rv; } @@ -785,15 +797,22 @@ sub _parent_headers { $rv; } -# returns a string buffer via ->getline +# returns a string buffer sub html_footer { my ($ctx, $hdr) = @_; my $ibx = $ctx->{-inbox}; my $upfx = '../'; - my $skel = " index"; + my $skel; my $rv = ''; if ($ibx->over) { - $skel .= "\n"; + my $t = ts2str($ctx->{-t_max}); + my $t_fmt = fmt_ts($ctx->{-t_max}); + $skel .= <~$t_fmt UTC|newest] +EOF + thread_skel(\$skel, $ctx, $hdr); my ($next, $prev); my $parent = ' '; @@ -824,6 +843,8 @@ sub html_footer { $parent = " parent"; } $rv .= "$next $prev$parent "; + } else { # unindexed inboxes w/o over + $skel = qq( latest); } $rv .= qq(reply); $rv .= $skel; @@ -861,7 +882,7 @@ sub find_mid_root { ++$ctx->{root_idx} if $level == 0; if ($node->{mid} eq $ctx->{mid}) { $ctx->{found_mid_at} = $ctx->{root_idx}; - return 0; + return 0; # stop iterating } 1; } @@ -1145,17 +1166,13 @@ sub dump_topics { 200; } -# only for the t= query parameter passed to overview DB -sub ts2str ($) { strftime('%Y%m%d%H%M%S', gmtime($_[0])) }; - sub str2ts ($) { my ($yyyy, $mon, $dd, $hh, $mm, $ss) = unpack('A4A2A2A2A2A2', $_[0]); - timegm($ss, $mm, $hh, $dd, $mon - 1, $yyyy); + timegm($ss || 0, $mm || 0, $hh || 0, $dd, $mon - 1, $yyyy); } sub pagination_footer ($$) { my ($ctx, $latest) = @_; - delete $ctx->{qp} or return; my $next = $ctx->{next_page} || ''; my $prev = $ctx->{prev_page} || ''; if ($prev) { @@ -1207,6 +1224,7 @@ sub paginate_recent ($$) { $msgs; } +# GET /$INBOX - top-level inbox view for indexed inboxes sub index_topics { my ($ctx) = @_; my $msgs = paginate_recent($ctx, 200); # 200 is our window