]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/ExtMsg.pm
extmsg: switch to wwwstream for partial match, too
[public-inbox.git] / lib / PublicInbox / ExtMsg.pm
index 62381e9e5e8c4457c1546919d3c9b9d87dc88edd..019d50a457aa98a609e4bbca0da0c43213d7c0ce 100644 (file)
@@ -8,9 +8,9 @@
 package PublicInbox::ExtMsg;
 use strict;
 use warnings;
-use URI::Escape qw(uri_escape_utf8);
 use PublicInbox::Hval;
 use PublicInbox::MID qw/mid2path/;
+use PublicInbox::WwwStream;
 
 # TODO: user-configurable
 our @EXT_URL = (
@@ -61,19 +61,21 @@ sub ext_msg {
                }
        });
 
-       # TODO: multiple hits
-       return r302($found[0], $mid) if @found;
+       return exact($ctx, \@found, $mid) if @found;
 
        # Xapian not installed or configured for some repos,
-       # do a full MID check:
+       # do a full MID check (this is expensive...):
        if (@nox) {
                my $path = mid2path($mid);
                foreach my $other (@nox) {
                        my (undef, $type, undef) = $other->path_check($path);
 
-                       return r302($other, $mid) if $type && $type eq 'blob';
+                       if ($type && $type eq 'blob') {
+                               push @found, $other;
+                       }
                }
        }
+       return exact($ctx, \@found, $mid) if @found;
 
        # fall back to partial MID matching
        my $n_partial = 0;
@@ -102,14 +104,12 @@ again:
        my $h = PublicInbox::Hval->new_msgid($mid);
        my $href = $h->as_href;
        my $html = $h->as_html;
-       my $title = "Message-ID <$html> not found";
-       my $s = "<html><head><title>$title</title>" .
-               "</head><body><pre><b>$title</b>\n";
-
+       my $title = "&lt;$html&gt; not found";
+       my $s = "<pre>Message-ID &lt;$html&gt;\nnot found\n";
        if ($n_partial) {
                $code = 300;
                my $es = $n_partial == 1 ? '' : 'es';
-               $s.= "\n$n_partial partial match$es found:\n\n";
+               $s .= "\n$n_partial partial match$es found:\n\n";
                foreach my $pair (@partial) {
                        my ($ibx, $res) = @$pair;
                        my $u = $ibx->base_url or next;
@@ -121,31 +121,54 @@ again:
                        }
                }
        }
+       my $ext = ext_urls($ctx, $mid, $href, $html);
+       if ($ext ne '') {
+               $s .= $ext;
+               $code = 300;
+       }
+       $ctx->{-html_tip} = $s .= '</pre>';
+       $ctx->{-title_html} = $title;
+       $ctx->{-upfx} = '../';
+       PublicInbox::WwwStream->response($ctx, $code);
+}
+
+sub ext_urls {
+       my ($ctx, $mid, $href, $html) = @_;
 
        # Fall back to external repos if configured
        if (@EXT_URL && index($mid, '@') >= 0) {
-               $code = 300;
-               $s .= "\nPerhaps try an external site:\n\n";
+               my $env = $ctx->{env};
+               my $e = "\nPerhaps try an external site:\n\n";
                foreach my $url (@EXT_URL) {
                        my $u = PublicInbox::Hval::prurl($env, $url);
                        my $r = sprintf($u, $href);
                        my $t = sprintf($u, $html);
-                       $s .= qq{<a\nhref="$r">$t</a>\n};
+                       $e .= qq{<a\nhref="$r">$t</a>\n};
                }
+               return $e;
        }
-       $s .= '</pre></body></html>';
-
-       [$code, ['Content-Type'=>'text/html; charset=UTF-8'], [$s]];
+       ''
 }
 
-# Redirect to another public-inbox which is mapped by $pi_config
-# TODO: prompt for inbox-switching
-sub r302 {
-       my ($inbox, $mid) = @_;
-       my $url = $inbox->base_url . uri_escape_utf8($mid) . '/';
-       [ 302,
-         [ 'Location' => $url, 'Content-Type' => 'text/plain' ],
-         [ "Redirecting to\n$url\n" ] ]
+sub exact {
+       my ($ctx, $found, $mid) = @_;
+       my $h = PublicInbox::Hval->new_msgid($mid);
+       my $href = $h->as_href;
+       my $html = $h->as_html;
+       my $title = "&lt;$html&gt; found in ";
+       my $end = @$found == 1 ? 'another inbox' : 'other inboxes';
+       $ctx->{-title_html} = $title . $end;
+       $ctx->{-upfx} = '../';
+       my $ext_urls = ext_urls($ctx, $mid, $href, $html);
+       my $code = (@$found == 1 && $ext_urls eq '') ? 200 : 300;
+       $ctx->{-html_tip} = join('',
+                       "<pre>Message-ID: &lt;$html&gt;\nfound in $end:\n\n",
+                               (map {
+                                       my $u = $_->base_url;
+                                       qq(<a\nhref="$u$href/">$u$html/</a>\n)
+                               } @$found),
+                       $ext_urls, '</pre>');
+       PublicInbox::WwwStream->response($ctx, $code);
 }
 
 1;