X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FView.pm;h=0b1ec75b31fd3f297bfcf85fdea29364ba5ede8a;hb=ccb66f35d293d3d0e3f9b119f7bd1fa019b93c75;hp=feac601510ff0d021fa1bc07d52f6dc4f3c0ff14;hpb=275dc15b848eb3f51f10eb62fdec2d3ac8404e15;p=public-inbox.git diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index feac6015..0b1ec75b 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -92,13 +92,13 @@ EOF sub in_reply_to { my ($hdr) = @_; - my $irt = $hdr->header_raw('In-Reply-To'); - - return mid_clean($irt) if defined $irt && $irt ne ''; - - my $refs = $hdr->header_raw('References'); - if ($refs && $refs =~ /<([^>]+)>\s*\z/s) { - return $1; + my %mid = map { $_ => 1 } $hdr->header_raw('Message-ID'); + my @refs = ($hdr->header_raw('References'), + $hdr->header_raw('In-Reply-To')); + @refs = ((join(' ', @refs)) =~ /<([^>]+)>/g); + while (defined(my $irt = pop @refs)) { + next if $mid{"<$irt>"}; + return $irt; } undef; } @@ -201,7 +201,10 @@ sub _th_index_lite { my $rv = ''; my $mapping = $ctx->{mapping} or return $rv; my $pad = ' '; - my ($attr, $node, $idx, $level) = @{$mapping->{$mid_raw}}; + my $mid_map = $mapping->{$mid_raw}; + defined $mid_map or + return 'public-inbox BUG: '.ascii_html($mid_raw).' not mapped'; + my ($attr, $node, $idx, $level) = @$mid_map; my $children = $node->{children}; my $nr_c = scalar @$children; my $nr_s = 0; @@ -260,8 +263,8 @@ sub _th_index_lite { } sub walk_thread { - my ($th, $ctx, $cb) = @_; - my @q = map { (0, $_, -1) } @{$th->{rootset}}; + my ($rootset, $ctx, $cb) = @_; + my @q = map { (0, $_, -1) } @$rootset; while (@q) { my ($level, $node, $i) = splice(@q, 0, 3); defined $node or next; @@ -285,10 +288,10 @@ sub thread_index_entry { } sub stream_thread ($$) { - my ($th, $ctx) = @_; + my ($rootset, $ctx) = @_; my $inbox = $ctx->{-inbox}; my $mime; - my @q = map { (0, $_) } @{$th->{rootset}}; + my @q = map { (0, $_) } @$rootset; my $level; while (@q) { $level = shift @q; @@ -299,7 +302,7 @@ sub stream_thread ($$) { } return missing_thread($ctx) unless $mime; - $mime = Email::MIME->new($mime); + $mime = PublicInbox::MIME->new($mime); $ctx->{-title_html} = ascii_html($mime->header('Subject')); $ctx->{-html_tip} = thread_index_entry($ctx, $level, $mime); PublicInbox::WwwStream->response($ctx, 200, sub { @@ -311,7 +314,7 @@ sub stream_thread ($$) { unshift @q, map { ($cl, $_) } @{$node->{children}}; my $mid = $node->{id}; if ($mime = $inbox->msg_by_smsg($node->{smsg})) { - $mime = Email::MIME->new($mime); + $mime = PublicInbox::MIME->new($mime); return thread_index_entry($ctx, $level, $mime); } else { return ghost_index_entry($ctx, $level, $node); @@ -327,8 +330,9 @@ sub stream_thread ($$) { sub thread_html { my ($ctx) = @_; my $mid = $ctx->{mid}; - my $sres = $ctx->{srch}->get_thread($mid, { asc => 1 }); - my $msgs = load_results($sres); + my $srch = $ctx->{srch}; + my $sres = $srch->get_thread($mid); + my $msgs = load_results($srch, $sres); my $nr = $sres->{total}; return missing_thread($ctx) if $nr == 0; my $skel = '
'; @@ -349,10 +353,10 @@ sub thread_html { $ctx->{mapping} = {}; $ctx->{s_nr} = "$nr+ messages in thread"; - my $th = thread_results($msgs); - walk_thread($th, $ctx, *pre_thread); + my $rootset = thread_results($msgs); + walk_thread($rootset, $ctx, *pre_thread); $skel .= ''; - return stream_thread($th, $ctx) unless $ctx->{flat}; + return stream_thread($rootset, $ctx) unless $ctx->{flat}; # flat display: lazy load the full message from smsg my $inbox = $ctx->{-inbox}; @@ -361,7 +365,7 @@ sub thread_html { $mime = $inbox->msg_by_smsg($mime) and last; } return missing_thread($ctx) unless $mime; - $mime = Email::MIME->new($mime); + $mime = PublicInbox::MIME->new($mime); $ctx->{-title_html} = ascii_html($mime->header('Subject')); $ctx->{-html_tip} = '
'.index_entry($mime, $ctx, scalar @$msgs); $mime = undef; @@ -371,7 +375,7 @@ sub thread_html { $mime = $inbox->msg_by_smsg($mime) and last; } if ($mime) { - $mime = Email::MIME->new($mime); + $mime = PublicInbox::MIME->new($mime); return index_entry($mime, $ctx, scalar @$msgs); } $msgs = undef; @@ -440,7 +444,7 @@ sub attach_link ($$$$;$) { sub add_text_body { my ($upfx, $p) = @_; # from msg_iter: [ Email::MIME, depth, @idx ] - my ($part, $depth, @idx) = @$p; + my ($part, $depth) = @$p; # attachment @idx is unused my $ct = $part->content_type || 'text/plain'; my $fn = $part->filename; @@ -475,29 +479,26 @@ sub add_text_body { } my @quot; my $l = PublicInbox::Linkify->new; - while (defined(my $cur = shift @lines)) { + foreach my $cur (@lines) { if ($cur !~ /^>/) { # show the previously buffered quote inline flush_quote(\$s, $l, \@quot) if @quot; # regular line, OK - $cur = $l->linkify_1($cur); - $cur = ascii_html($cur); - $s .= $l->linkify_2($cur); + $l->linkify_1($cur); + $s .= $l->linkify_2(ascii_html($cur)); } else { push @quot, $cur; } } - my $end = "\n"; - if (@quot) { - $end = ''; + if (@quot) { # ugh, top posted flush_quote(\$s, $l, \@quot); + } elsif ($s =~ /\n\z/s) { # common, last line ends with a newline + $s; + } else { # some editors don't do newlines... + $s .= "\n"; } - $s =~ s/[ \t]+$//sgm; # kill per-line trailing whitespace - $s =~ s/\A\n+//s; # kill leading blank lines - $s =~ s/\s+\z//s; # kill all trailing spaces - $s .= $end; } sub _msg_html_prepare { @@ -574,7 +575,8 @@ sub thread_skel { $ctx->{prev_attr} = ''; $ctx->{prev_level} = 0; $ctx->{dst} = $dst; - walk_thread(thread_results(load_results($sres)), $ctx, *skel_dump); + $sres = load_results($srch, $sres); + walk_thread(thread_results($sres), $ctx, *skel_dump); $ctx->{parent_msg} = $parent; } @@ -733,9 +735,9 @@ sub indent_for { } sub load_results { - my ($sres) = @_; - - [ map { $_->ensure_metadata; $_ } @{delete $sres->{msgs}} ]; + my ($srch, $sres) = @_; + my $msgs = delete $sres->{msgs}; + $srch->retry_reopen(sub { [ map { $_->mid; $_ } @$msgs ] }); } sub msg_timestamp { @@ -747,10 +749,7 @@ sub msg_timestamp { sub thread_results { my ($msgs) = @_; require PublicInbox::SearchThread; - my $th = PublicInbox::SearchThread->new($msgs); - $th->thread; - $th->order(*sort_ts); - $th + PublicInbox::SearchThread::thread($msgs, *sort_ts); } sub missing_thread { @@ -767,8 +766,9 @@ sub _msg_date { sub fmt_ts { POSIX::strftime('%Y-%m-%d %k:%M', gmtime($_[0])) } -sub _skel_header { - my ($ctx, $smsg, $level) = @_; +sub skel_dump { + my ($ctx, $level, $node) = @_; + my $smsg = $node->{smsg} or return _skel_ghost($ctx, $level, $node); my $dst = $ctx->{dst}; my $cur = $ctx->{cur}; @@ -824,32 +824,29 @@ sub _skel_header { $$dst .= $d . "" . $end; } -sub skel_dump { +sub _skel_ghost { my ($ctx, $level, $node) = @_; - if (my $smsg = $node->{smsg}) { - _skel_header($ctx, $smsg, $level); + + my $mid = $node->{id}; + my $d = $ctx->{pct} ? ' [irrelevant] ' # search result + : ' [not found] '; + $d .= indent_for($level) . th_pfx($level); + my $upfx = $ctx->{-upfx}; + my $m = PublicInbox::Hval->new_msgid($mid); + my $href = $upfx . $m->{href} . '/'; + my $html = $m->as_html; + + my $mapping = $ctx->{mapping}; + my $map = $mapping->{$mid} if $mapping; + if ($map) { + my $id = id_compress($mid, 1); + $map->[0] = $d . qq{<$html>\n}; + $d .= qq{<$html>\n}; } else { - my $mid = $node->{id}; - my $dst = $ctx->{dst}; - my $d = $ctx->{pct} ? ' [irrelevant] ' # search result - : ' [not found] '; - $d .= indent_for($level) . th_pfx($level); - my $upfx = $ctx->{-upfx}; - my $m = PublicInbox::Hval->new_msgid($mid); - my $href = $upfx . $m->{href} . '/'; - my $html = $m->as_html; - - my $mapping = $ctx->{mapping}; - my $map = $mapping->{$mid} if $mapping; - if ($map) { - my $id = id_compress($mid, 1); - $map->[0] = $d . qq{<$html>\n}; - $d .= qq{<$html>\n}; - } else { - $d .= qq{<$html>\n}; - } - $$dst .= $d; + $d .= qq{<$html>\n}; } + my $dst = $ctx->{dst}; + $$dst .= $d; } sub sort_ts { @@ -977,10 +974,11 @@ sub index_topics { my $opts = { offset => $off, limit => 200 }; $ctx->{order} = []; - my $sres = $ctx->{srch}->query('', $opts); + my $srch = $ctx->{srch}; + my $sres = $srch->query('', $opts); my $nr = scalar @{$sres->{msgs}}; if ($nr) { - $sres = load_results($sres); + $sres = load_results($srch, $sres); walk_thread(thread_results($sres), $ctx, *acc_topic); } $ctx->{-next_o} = $off+ $nr;