X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSearchView.pm;h=07fef40ccccc42b34f46da8c83add5bbf1d79a72;hb=1e0709d33ca040b8b1ac6b84e5b07a4cee3a6ced;hp=eeebdfa3137903f64426b0fc96773a58b946a3bd;hpb=55263c56cf41c87f8977cd6a6be65ac07b5cea87;p=public-inbox.git
diff --git a/lib/PublicInbox/SearchView.pm b/lib/PublicInbox/SearchView.pm
index eeebdfa3..07fef40c 100644
--- a/lib/PublicInbox/SearchView.pm
+++ b/lib/PublicInbox/SearchView.pm
@@ -1,37 +1,40 @@
-# Copyright (C) 2015-2020 all contributors
+# Copyright (C) all contributors
# License: AGPL-3.0+
#
# Displays search results for the web interface
package PublicInbox::SearchView;
use strict;
-use warnings;
-use URI::Escape qw(uri_unescape uri_escape);
+use v5.10.1;
+use List::Util qw(min max);
+use URI::Escape qw(uri_unescape);
use PublicInbox::Smsg;
-use PublicInbox::Hval qw(ascii_html obfuscate_addrs mid_href);
+use PublicInbox::Hval qw(ascii_html obfuscate_addrs mid_href fmt_ts);
use PublicInbox::View;
use PublicInbox::WwwAtomStream;
use PublicInbox::WwwStream qw(html_oneshot);
use PublicInbox::SearchThread;
-our $LIM = 200;
+use PublicInbox::SearchQuery;
+use PublicInbox::Search qw(get_pct);
my %rmap_inc;
sub mbox_results {
my ($ctx) = @_;
my $q = PublicInbox::SearchQuery->new($ctx->{qp});
- my $x = $q->{x};
+ if ($ctx->{env}->{'psgi.input'}->read(my $buf, 3)) {
+ $q->{t} = 1 if $buf =~ /\Ax=[^0]/;
+ }
require PublicInbox::Mbox;
- return PublicInbox::Mbox::mbox_all($ctx, $q->{'q'}) if $x eq 'm';
- sres_top_html($ctx);
+ $q->{x} eq 'm' ? PublicInbox::Mbox::mbox_all($ctx, $q) :
+ sres_top_html($ctx);
}
sub sres_top_html {
my ($ctx) = @_;
- my $srch = $ctx->{-inbox}->search or
+ my $srch = $ctx->{ibx}->isrch or
return PublicInbox::WWW::need($ctx, 'Search');
my $q = PublicInbox::SearchQuery->new($ctx->{qp});
my $x = $q->{x};
- my $query = $q->{'q'};
- my $o = $q->{o};
+ my $o = $q->{o} // 0;
my $asc;
if ($o < 0) {
$asc = 1;
@@ -43,14 +46,16 @@ sub sres_top_html {
my $opts = {
limit => $q->{l},
offset => $o,
- mset => 1,
relevance => $q->{r},
+ threads => $q->{t},
asc => $asc,
};
my ($mset, $total, $err, $html);
retry:
eval {
- $mset = $srch->query($query, $opts);
+ my $query = $q->{'q'};
+ $srch->query_approxidate($ctx->{ibx}->git, $query);
+ $mset = $srch->mset($query, $opts);
$total = $mset->get_matches_estimated;
};
$err = $@;
@@ -77,7 +82,7 @@ retry:
mset_summary($ctx, $mset, $q); # appends to {-html_tip}
$html = '';
}
- html_oneshot($ctx, $code);
+ html_oneshot($ctx, $code, $html);
}
# display non-nested search results similar to what users expect from
@@ -89,34 +94,47 @@ sub mset_summary {
my $pad = length("$total");
my $pfx = ' ' x $pad;
my $res = \($ctx->{-html_tip});
- my $ibx = $ctx->{-inbox};
- my $srch = $ibx->search;
+ my $ibx = $ctx->{ibx};
my $obfs_ibx = $ibx->{obfuscate} ? $ibx : undef;
+ my @nums = @{$ibx->isrch->mset_to_artnums($mset)};
+ my %num2msg = map { $_->{num} => $_ } @{$ibx->over->get_all(@nums)};
+ my ($min, $max, %seen);
+
foreach my $m ($mset->items) {
+ my $num = shift @nums;
+ my $smsg = delete($num2msg{$num}) // do {
+ warn "$m $num expired\n";
+ next;
+ };
+ my $mid = $smsg->{mid};
+ next if $seen{$mid}++;
+ $mid = mid_href($mid);
+ $ctx->{-t_max} //= $smsg->{ts};
my $rank = sprintf("%${pad}d", $m->get_rank + 1);
my $pct = get_pct($m);
- my $smsg = PublicInbox::Smsg::from_mitem($m, $srch);
- unless ($smsg) {
- eval {
- $m = "$m ".$m->get_docid . " expired\n";
- $ctx->{env}->{'psgi.errors'}->print($m);
- };
- next;
- }
+
+ # only when sorting by relevance, ->items is always
+ # ordered descending:
+ $max //= $pct;
+ $min = $pct;
+
my $s = ascii_html($smsg->{subject});
- my $f = ascii_html($smsg->{from_name});
+ my $f = ascii_html(delete $smsg->{from_name});
if ($obfs_ibx) {
obfuscate_addrs($obfs_ibx, $s);
obfuscate_addrs($obfs_ibx, $f);
}
- my $date = PublicInbox::View::fmt_ts($smsg->{ds});
- my $mid = mid_href($smsg->{mid});
+ my $date = fmt_ts($smsg->{ds});
$s = '(no subject)' if $s eq '';
$$res .= qq{$rank. }.
$s . "\n";
$$res .= "$pfx - by $f @ $date UTC [$pct%]\n\n";
}
- $$res .= search_nav_bot($mset, $q);
+ if ($q->{r}) { # for descriptions in search_nav_bot
+ $q->{-min_pct} = $min;
+ $q->{-max_pct} = $max;
+ }
+ $$res .= search_nav_bot($ctx, $mset, $q);
undef;
}
@@ -138,7 +156,7 @@ sub path2inc ($) {
sub err_txt {
my ($ctx, $err) = @_;
- my $u = $ctx->{-inbox}->base_url($ctx->{env}) . '_/text/help/';
+ my $u = $ctx->{ibx}->base_url($ctx->{env}) . '_/text/help/';
$err =~ s/^\s*Exception:\s*//; # bad word to show users :P
$err =~ s!(\S+)!path2inc($1)!sge;
$err = ascii_html($err);
@@ -148,8 +166,8 @@ sub err_txt {
sub search_nav_top {
my ($mset, $q, $ctx) = @_;
- my $m = $q->qs_html(x => 'm', r => undef);
- my $rv = qq{
};
+ $rv .= qq{|Atom feed]\n};
+ $rv .= <{t};
+*** "t=1" collapses threads in summary, "full threads" requires mbox.gz ***
+EOM
+ $rv .= <{ibx}->isrch->has_threadid) {
+ $rv .= qq{${pfx}download mbox.gz: } .
+ # we set name=z w/o using it since it seems required for
+ # lynx (but works fine for w3m).
+ qq{} .
+ qq{|};
+ } else { # BOFH needs to --reindex
+ $rv .= qq{${pfx}download: } .
+ qq{}
+ }
+ $rv .= qq{
};
}
-sub search_nav_bot {
- my ($mset, $q) = @_;
+sub search_nav_bot { # also used by WwwListing for searching extindex miscidx
+ my ($ctx, $mset, $q) = @_;
my $total = $mset->get_matches_estimated;
my $l = $q->{l};
my $rv = '