]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/ExtMsg.pm
extmsg: remove expensive git path checks
[public-inbox.git] / lib / PublicInbox / ExtMsg.pm
index 019d50a457aa98a609e4bbca0da0c43213d7c0ce..a6f516df7bd4d3cfb9532fbf504f6d0c2b55f3cd 100644 (file)
@@ -1,5 +1,5 @@
-# Copyright (C) 2015 all contributors <meta@public-inbox.org>
-# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+# Copyright (C) 2015-2018 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 #
 # Used by the web interface to link to messages outside of the our
 # public-inboxes.  Mail threads may cross projects/threads; so
@@ -14,44 +14,36 @@ use PublicInbox::WwwStream;
 
 # TODO: user-configurable
 our @EXT_URL = (
-       'http://mid.gmane.org/%s',
-       'https://lists.debian.org/msgid-search/%s',
        # leading "//" denotes protocol-relative (http:// or https://)
-       '//mid.mail-archive.com/%s',
        '//marc.info/?i=%s',
+       '//www.mail-archive.com/search?l=mid&q=%s',
+       'http://mid.gmane.org/%s',
+       'https://lists.debian.org/msgid-search/%s',
+       '//docs.FreeBSD.org/cgi/mid.cgi?db=mid&id=%s',
+       'https://www.w3.org/mid/%s',
+       'http://www.postgresql.org/message-id/%s',
+       'https://lists.debconf.org/cgi-lurker/keyword.cgi?'.
+               'doc-url=/lurker&format=en.html&query=id:%s'
 );
 
 sub ext_msg {
        my ($ctx) = @_;
-       my $pi_config = $ctx->{pi_config};
        my $cur = $ctx->{-inbox};
        my $mid = $ctx->{mid};
-       my $env = $ctx->{env};
 
-       eval { require PublicInbox::Search };
-       my $have_xap = $@ ? 0 : 1;
-       my (@nox, @ibx, @found);
+       eval { require PublicInbox::Msgmap };
+       my $have_mm = $@ ? 0 : 1;
+       my (@ibx, @found);
 
-       $pi_config->each_inbox(sub {
+       $ctx->{www}->{pi_config}->each_inbox(sub {
                my ($other) = @_;
                return if $other->{name} eq $cur->{name} || !$other->base_url;
 
-               my $s = $other->search;
-               if (!$s) {
-                       push @nox, $other;
-                       return;
-               }
-
-               # try to find the URL with Xapian to avoid forking
-               my $doc_id = eval { $s->find_unique_doc_id('mid', $mid) };
-               if ($@) {
-                       # xapian not configured properly for this repo
-                       push @nox, $other;
-                       return;
-               }
+               my $mm = $other->mm or return;
 
-               # maybe we found it!
-               if (defined $doc_id) {
+               # try to find the URL with Msgmap to avoid forking
+               my $num = $mm->num_for($mid);
+               if (defined $num) {
                        push @found, $other;
                } else {
                        # no point in trying the fork fallback if we
@@ -63,35 +55,37 @@ sub ext_msg {
 
        return exact($ctx, \@found, $mid) if @found;
 
-       # Xapian not installed or configured for some repos,
-       # 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);
+       # fall back to partial MID matching
+       my $n_partial = 0;
+       my @partial;
 
-                       if ($type && $type eq 'blob') {
-                               push @found, $other;
+       if (my $mm = $cur->mm) {
+               my $tmp_mid = $mid;
+               my $res = $mm->mid_prefixes($tmp_mid, 100);
+               if ($res && scalar(@$res)) {
+                       $n_partial += scalar(@$res);
+                       push @partial, [ $cur, $res ];
+               # fixup common errors:
+               } elsif ($tmp_mid =~ s,/[tTf],,) {
+                       $res = $mm->mid_prefixes($tmp_mid, 100);
+                       if ($res && scalar(@$res)) {
+                               $n_partial += scalar(@$res);
+                               push @partial, [ $cur, $res ];
                        }
                }
        }
-       return exact($ctx, \@found, $mid) if @found;
 
-       # fall back to partial MID matching
-       my $n_partial = 0;
-       my @partial;
-
-       eval { require PublicInbox::Msgmap };
-       my $have_mm = $@ ? 0 : 1;
-       if ($have_mm) {
+       # can't find a partial match in current inbox, try the others:
+       if (!$n_partial && length($mid) >= 16) {
                my $tmp_mid = $mid;
 again:
-               unshift @ibx, $cur;
                foreach my $ibx (@ibx) {
                        my $mm = $ibx->mm or next;
-                       if (my $res = $mm->mid_prefixes($tmp_mid)) {
+                       my $res = $mm->mid_prefixes($tmp_mid, 100);
+                       if ($res && scalar(@$res)) {
                                $n_partial += scalar(@$res);
                                push @partial, [ $ibx, $res ];
+                               last if $n_partial >= 100;
                        }
                }
                # fixup common errors:
@@ -102,7 +96,7 @@ again:
 
        my $code = 404;
        my $h = PublicInbox::Hval->new_msgid($mid);
-       my $href = $h->as_href;
+       my $href = $h->{href};
        my $html = $h->as_html;
        my $title = "&lt;$html&gt; not found";
        my $s = "<pre>Message-ID &lt;$html&gt;\nnot found\n";
@@ -110,12 +104,14 @@ again:
                $code = 300;
                my $es = $n_partial == 1 ? '' : 'es';
                $s .= "\n$n_partial partial match$es found:\n\n";
+               my $cur_name = $cur->{name};
                foreach my $pair (@partial) {
                        my ($ibx, $res) = @$pair;
-                       my $u = $ibx->base_url or next;
+                       my $env = $ctx->{env} if $ibx->{name} eq $cur_name;
+                       my $u = $ibx->base_url($env) or next;
                        foreach my $m (@$res) {
                                my $p = PublicInbox::Hval->new_msgid($m);
-                               my $r = $p->as_href;
+                               my $r = $p->{href};
                                my $t = $p->as_html;
                                $s .= qq{<a\nhref="$u$r/">$u$t/</a>\n};
                        }
@@ -153,7 +149,7 @@ sub ext_urls {
 sub exact {
        my ($ctx, $found, $mid) = @_;
        my $h = PublicInbox::Hval->new_msgid($mid);
-       my $href = $h->as_href;
+       my $href = $h->{href};
        my $html = $h->as_html;
        my $title = "&lt;$html&gt; found in ";
        my $end = @$found == 1 ? 'another inbox' : 'other inboxes';