about summary refs log tree commit homepage
path: root/lib/PublicInbox/SearchView.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/SearchView.pm')
-rw-r--r--lib/PublicInbox/SearchView.pm75
1 files changed, 44 insertions, 31 deletions
diff --git a/lib/PublicInbox/SearchView.pm b/lib/PublicInbox/SearchView.pm
index 2d3e942c..f056dddf 100644
--- a/lib/PublicInbox/SearchView.pm
+++ b/lib/PublicInbox/SearchView.pm
@@ -30,10 +30,9 @@ sub mbox_results {
 
 sub sres_top_html {
         my ($ctx) = @_;
-        my $srch = $ctx->{ibx}->isrch or
+        my $srch = $ctx->{srch} = $ctx->{ibx}->isrch or
                 return PublicInbox::WWW::need($ctx, 'Search');
         my $q = PublicInbox::SearchQuery->new($ctx->{qp});
-        my $x = $q->{x};
         my $o = $q->{o} // 0;
         my $asc;
         if ($o < 0) {
@@ -41,48 +40,57 @@ sub sres_top_html {
                 $o = -($o + 1); # so [-1] is the last element, like Perl lists
         }
 
-        my $code = 200;
         # double the limit for expanded views:
-        my $opts = {
+        my $opt = {
                 limit => $q->{l},
                 offset => $o,
                 relevance => $q->{r},
                 threads => $q->{t},
                 asc => $asc,
         };
-        my ($mset, $total, $err, $html);
-retry:
-        eval {
-                my $query = $q->{'q'};
-                $srch->query_approxidate($ctx->{ibx}->git, $query);
-                $mset = $srch->mset($query, $opts);
-                $total = $mset->get_matches_estimated;
-        };
-        $err = $@;
+        my $qs = $q->{'q'};
+        $srch->query_approxidate($ctx->{ibx}->git, $qs);
+        sub {
+                $ctx->{wcb} = $_[0]; # PSGI server supplied write cb
+                $srch->async_mset($qs, $opt, \&sres_html_cb, $ctx, $opt, $q);
+        }
+}
+
+sub sres_html_cb { # async_mset cb
+        my ($ctx, $opt, $q, $mset, $err) = @_;
+        my $code = 200;
+        my $total = $mset ? $mset->get_matches_estimated : undef;
         ctx_prepare($q, $ctx);
+        my ($res, $html);
         if ($err) {
                 $code = 400;
                 $html = '<pre>'.err_txt($ctx, $err).'</pre><hr>';
         } elsif ($total == 0) {
-                if (defined($ctx->{-uxs_retried})) {
-                        # undo retry damage:
+                if (defined($ctx->{-uxs_retried})) { # undo retry damage:
                         $q->{'q'} = $ctx->{-uxs_retried};
-                } elsif (index($q->{'q'}, '%') >= 0) {
+                } elsif (index($q->{'q'}, '%') >= 0) { # retry unescaped
                         $ctx->{-uxs_retried} = $q->{'q'};
-                        $q->{'q'} = uri_unescape($q->{'q'});
-                        goto retry;
+                        my $qs = $q->{'q'} = uri_unescape($q->{'q'});
+                        $ctx->{srch}->query_approxidate($ctx->{ibx}->git, $qs);
+                        return $ctx->{srch}->async_mset($qs, $opt,
+                                                \&sres_html_cb, $ctx, $opt, $q);
                 }
                 $code = 404;
                 $html = "<pre>\n[No results found]</pre><hr>";
+        } elsif ($q->{x} eq 'A') {
+                $res = adump($mset, $q, $ctx);
         } else {
-                return adump($_[0], $mset, $q, $ctx) if $x eq 'A';
-
                 $ctx->{-html_tip} = search_nav_top($mset, $q, $ctx);
-                return mset_thread($ctx, $mset, $q) if $x eq 't';
-                mset_summary($ctx, $mset, $q); # appends to {-html_tip}
-                $html = '';
+                if ($q->{x} eq 't') {
+                        $res = mset_thread($ctx, $mset, $q);
+                } else {
+                        mset_summary($ctx, $mset, $q); # appends to {-html_tip}
+                        $html = '';
+                }
         }
-        html_oneshot($ctx, $code, $html);
+        $res //= html_oneshot($ctx, $code, $html);
+        my $wcb = delete $ctx->{wcb};
+        ref($res) eq 'CODE' ? $res->($wcb) : $wcb->($res);
 }
 
 # display non-nested search results similar to what users expect from
@@ -146,9 +154,15 @@ sub path2inc ($) {
         if (my $short = $rmap_inc{$full}) {
                 return $short;
         } elsif (!scalar(keys %rmap_inc) && -e $full) {
-                %rmap_inc = map {; "$INC{$_}" => $_ } keys %INC;
+                # n.b. $INC{'PublicInbox::Gcf2'} is undef if libgit2-dev
+                # doesn't exist
+                my $f;
+                %rmap_inc = map {;
+                        $f = $INC{$_};
+                        defined $f ? ($f, $_) : ();
+                } keys %INC;
                 # fall back to basename as last resort
-                $rmap_inc{$full} // (split('/', $full))[-1];
+                $rmap_inc{$full} // (split(m'/', $full))[-1];
         } else {
                 $full;
         }
@@ -302,13 +316,12 @@ sub mset_thread {
         my $rootset = PublicInbox::SearchThread::thread($msgs,
                 $r ? \&sort_relevance : \&PublicInbox::View::sort_ds,
                 $ctx);
-        my $skel = search_nav_bot($ctx, $mset, $q).'<pre>'. <<EOM;
+        $ctx->{skel} = [ search_nav_bot($ctx, $mset, $q).'<pre>'. <<EOM ];
 -- pct% links below jump to the message on this page, permalinks otherwise --
 EOM
         $ctx->{-upfx} = '';
         $ctx->{anchor_idx} = 1;
         $ctx->{cur_level} = 0;
-        $ctx->{skel} = \$skel;
         $ctx->{mapping} = {};
         $ctx->{searchview} = 1;
         $ctx->{prev_attr} = '';
@@ -318,7 +331,7 @@ EOM
         # reduce hash lookups in skel_dump
         $ctx->{-obfs_ibx} = $ibx->{obfuscate} ? $ibx : undef;
         PublicInbox::View::walk_thread($rootset, $ctx,
-                \&PublicInbox::View::pre_thread);
+                \&PublicInbox::View::pre_thread); # pushes to ctx->{skel}
 
         # link $INBOX_DIR/description text to "recent" view around
         # the newest message in this result set:
@@ -335,7 +348,7 @@ sub mset_thread_i {
         print { $ctx->zfh } $ctx->html_top if exists $ctx->{-html_tip};
         $eml and return PublicInbox::View::eml_entry($ctx, $eml);
         my $smsg = shift @{$ctx->{msgs}} or
-                print { $ctx->zfh } ${delete($ctx->{skel})};
+                print { $ctx->zfh } @{delete($ctx->{skel})};
         $smsg;
 }
 
@@ -357,7 +370,7 @@ sub ctx_prepare {
 }
 
 sub adump {
-        my ($cb, $mset, $q, $ctx) = @_;
+        my ($mset, $q, $ctx) = @_;
         $ctx->{ids} = $ctx->{ibx}->isrch->mset_to_artnums($mset);
         $ctx->{search_query} = $q; # used by WwwAtomStream::atom_header
         PublicInbox::WwwAtomStream->response($ctx, \&adump_i);