]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/View.pm
handle "multipart/mixed" messages which are not multipart
[public-inbox.git] / lib / PublicInbox / View.pm
index 58851edc59f5226bc47a4c6ba3f7627a19ba3e00..bb49c035d976db7a65b83924a594e4b16c407b99 100644 (file)
@@ -119,6 +119,9 @@ sub msg_reply {
 
        my ($arg, $link, $reply_to_all) =
                        PublicInbox::Reply::mailto_arg_link($ibx, $hdr);
+       if (ref($arg) eq 'SCALAR') {
+               return '<pre id=R>'.ascii_html($$arg).'</pre>';
+       }
 
        # mailto: link only works if address obfuscation is disabled
        if ($link) {
@@ -365,7 +368,7 @@ sub walk_thread {
        while (@q) {
                my ($level, $node, $i) = splice(@q, 0, 3);
                defined $node or next;
-               $cb->($ctx, $level, $node, $i);
+               $cb->($ctx, $level, $node, $i) or return;
                ++$level;
                $i = 0;
                unshift @q, map { ($level, $_, $i++) } @{$node->{children}};
@@ -540,33 +543,14 @@ sub add_text_body {
        my ($part, $depth) = @$p; # attachment @idx is unused
        my $ct = $part->content_type || 'text/plain';
        my $fn = $part->filename;
+       my ($s, $err) = msg_part_text($part, $ct);
 
-       if ($ct =~ m!\btext/x?html\b!i) {
-               return attach_link($upfx, $ct, $p, $fn);
-       }
-
-       my $s = eval { $part->body_str };
-
-       # badly-encoded message? tell the world about it!
-       my $err = $@;
-       if ($err) {
-               if ($ct =~ m!\btext/plain\b!i) {
-                       # Try to assume UTF-8 because Alpine seems to
-                       # do wacky things and set charset=X-UNKNOWN
-                       $part->charset_set('UTF-8');
-                       $s = eval { $part->body_str };
-
-                       # If forcing charset=UTF-8 failed,
-                       # attach_link will warn further down...
-                       $s = $part->body if $@;
-               } else {
-                       return attach_link($upfx, $ct, $p, $fn);
-               }
-       }
+       return attach_link($upfx, $ct, $p, $fn) unless defined $s;
 
        my @lines = split(/^/m, $s);
        $s = '';
        if (defined($fn) || $depth > 0 || $err) {
+               # badly-encoded message with $err? tell the world about it!
                $s .= attach_link($upfx, $ct, $p, $fn, $err);
                $s .= "\n";
        }
@@ -818,10 +802,56 @@ sub indent_for {
        $level ? INDENT x ($level - 1) : '';
 }
 
+sub find_mid_root {
+       my ($ctx, $level, $node, $idx) = @_;
+       ++$ctx->{root_idx} if $level == 0;
+       if ($node->{id} eq $ctx->{mid}) {
+               $ctx->{found_mid_at} = $ctx->{root_idx};
+               return 0;
+       }
+       1;
+}
+
+sub strict_loose_note ($) {
+       my ($nr) = @_;
+       my $msg =
+"  -- strict thread matches above, loose matches on Subject: below --\n";
+
+       if ($nr > PublicInbox::Over::DEFAULT_LIMIT()) {
+               $msg .=
+"  -- use mbox.gz link to download all $nr messages --\n";
+       }
+       $msg;
+}
+
 sub thread_results {
        my ($ctx, $msgs) = @_;
        require PublicInbox::SearchThread;
-       PublicInbox::SearchThread::thread($msgs, *sort_ds, $ctx->{-inbox});
+       my $ibx = $ctx->{-inbox};
+       my $rootset = PublicInbox::SearchThread::thread($msgs, *sort_ds, $ibx);
+
+       # FIXME: `tid' is broken on --reindex, so that needs to be fixed
+       # and preserved in the future.  This bug is hidden by `sid' matches
+       # in get_thread, so we never noticed it until now.  And even when
+       # reindexing is fixed, we'll keep this code until a SCHEMA_VERSION
+       # bump since reindexing is expensive and users may not do it
+
+       # loose threading could've returned too many results,
+       # put the root the message we care about at the top:
+       my $mid = $ctx->{mid};
+       if (defined($mid) && scalar(@$rootset) > 1) {
+               $ctx->{root_idx} = -1;
+               my $nr = scalar @$msgs;
+               walk_thread($rootset, $ctx, *find_mid_root);
+               my $idx = $ctx->{found_mid_at};
+               if (defined($idx) && $idx != 0) {
+                       my $tip = splice(@$rootset, $idx, 1);
+                       @$rootset = reverse @$rootset;
+                       unshift @$rootset, $tip;
+                       $ctx->{sl_note} = strict_loose_note($nr);
+               }
+       }
+       $rootset
 }
 
 sub missing_thread {
@@ -864,6 +894,10 @@ sub skel_dump {
        my $cur = $ctx->{cur};
        my $mid = $smsg->{mid};
 
+       if ($level == 0 && $ctx->{skel_dump_roots}++) {
+               $$dst .= delete $ctx->{sl_note} || '';
+       }
+
        my $f = ascii_html($smsg->from_name);
        my $obfs_ibx = $ctx->{-obfs_ibx};
        obfuscate_addrs($obfs_ibx, $f) if $obfs_ibx;
@@ -882,7 +916,7 @@ sub skel_dump {
                        delete $ctx->{cur};
                        $$dst .= "<b>$d<a\nid=r\nhref=\"#t\">".
                                 "$attr [this message]</a></b>\n";
-                       return;
+                       return 1;
                } else {
                        $ctx->{prev_msg} = $mid;
                }
@@ -922,6 +956,7 @@ sub skel_dump {
                $m = $ctx->{-upfx}.mid_escape($mid).'/';
        }
        $$dst .=  $d . "<a\nhref=\"$m\"$id>" . $end;
+       1;
 }
 
 sub _skel_ghost {
@@ -947,6 +982,7 @@ sub _skel_ghost {
        }
        my $dst = $ctx->{dst};
        $$dst .= $d;
+       1;
 }
 
 sub sort_ds {
@@ -973,7 +1009,7 @@ sub acc_topic {
                        $topic = [ $ds, 1, { $subj => $mid }, $subj ];
                        $ctx->{-cur_topic} = $topic;
                        push @{$ctx->{order}}, $topic;
-                       return;
+                       return 1;
                }
 
                $topic = $ctx->{-cur_topic}; # should never be undef
@@ -987,11 +1023,12 @@ sub acc_topic {
                }
                $seen->{$subj} = $mid; # latest for subject
        } else { # ghost message
-               return if $level != 0; # ignore child ghosts
+               return if $level != 0; # ignore child ghosts
                $topic = [ -666, 0, {} ];
                $ctx->{-cur_topic} = $topic;
                push @{$ctx->{order}}, $topic;
        }
+       1;
 }
 
 sub dump_topics {