X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSearchView.pm;h=78f2bd8b20d43edc0de2fdfd1c33c4206a27396e;hb=9bd675d33ad1e49bd2ebe12a1d216216e61380de;hp=b089de9c91412cb1e4e42a431256b97c8ebafa63;hpb=e56b908c0e97c2f479b350dfb0868bc463413b89;p=public-inbox.git diff --git a/lib/PublicInbox/SearchView.pm b/lib/PublicInbox/SearchView.pm index b089de9c..78f2bd8b 100644 --- a/lib/PublicInbox/SearchView.pm +++ b/lib/PublicInbox/SearchView.pm @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2018 all contributors +# Copyright (C) 2015-2019 all contributors # License: AGPL-3.0+ # # Displays search results for the web interface @@ -15,6 +15,7 @@ use PublicInbox::MIME; require PublicInbox::Git; require PublicInbox::SearchThread; our $LIM = 200; +my %rmap_inc; sub noop {} @@ -34,14 +35,21 @@ sub sres_top_html { my $q = PublicInbox::SearchQuery->new($ctx->{qp}); my $x = $q->{x}; my $query = $q->{'q'}; + my $o = $q->{o}; + my $asc; + if ($o < 0) { + $asc = 1; + $o = -($o + 1); # so [-1] is the last element, like Perl lists + } my $code = 200; # double the limit for expanded views: my $opts = { limit => $q->{l}, - offset => $q->{o}, + offset => $o, mset => 1, relevance => $q->{r}, + asc => $asc, }; my ($mset, $total, $err, $cb); retry: @@ -131,10 +139,27 @@ sub mset_summary { *noop; } +# shorten "/full/path/to/Foo/Bar.pm" to "Foo/Bar.pm" so error +# messages don't reveal FS layout info in case people use non-standard +# installation paths +sub path2inc ($) { + my $full = $_[0]; + if (my $short = $rmap_inc{$full}) { + return $short; + } elsif (!scalar(keys %rmap_inc) && -e $full) { + %rmap_inc = map {; "$INC{$_}" => $_ } keys %INC; + # fall back to basename as last resort + $rmap_inc{$full} // (split('/', $full))[-1]; + } else { + $full; + } +} + sub err_txt { my ($ctx, $err) = @_; my $u = $ctx->{-inbox}->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); "\nBad query: $err\n" . qq{See $u for help on using search}; @@ -184,30 +209,50 @@ sub search_nav_top { sub search_nav_bot { my ($mset, $q) = @_; my $total = $mset->get_matches_estimated; - my $o = $q->{o}; my $l = $q->{l}; - my $end = $o + $mset->size; - my $beg = $o + 1; my $rv = '
';
+	my $o = $q->{o};
+	my $off = $o < 0 ? -($o + 1) : $o;
+	my $end = $off + $mset->size;
+	my $beg = $off + 1;
+
 	if ($beg <= $end) {
 		$rv .= "Results $beg-$end of $total";
 		$rv .= ' (estimated)' if $end != $total;
 	} else {
 		$rv .= "No more results, only $total";
 	}
-	my $n = $o + $l;
+	my ($next, $join, $prev);
 
-	if ($n < $total) {
-		my $qs = $q->qs_html(o => $n, l => $l);
-		$rv .= qq{  next}
-	}
-	if ($o > 0) {
-		$rv .= $n < $total ? '/' : '       ';
-		my $p = $o - $l;
-		my $qs = $q->qs_html(o => ($p > 0 ? $p : 0));
-		$rv .= qq{prev};
+	if ($o >= 0) { # sort descending
+		my $n = $o + $l;
+		if ($n < $total) {
+			$next = $q->qs_html(o => $n, l => $l);
+		}
+		if ($o > 0) {
+			$join = $n < $total ? '/' : '       ';
+			my $p = $o - $l;
+			$prev = $q->qs_html(o => ($p > 0 ? $p : 0));
+		}
+	} else { # o < 0, sort ascending
+		my $n = $o - $l;
+
+		if (-$n < $total) {
+			$next = $q->qs_html(o => $n, l => $l);
+		}
+		if ($o < -1) {
+			$join = -$n < $total ? '/' : '       ';
+			my $p = $o + $l;
+			$prev = $q->qs_html(o => ($p < 0 ? $p : 0));
+		}
 	}
-	$rv .= '
'; + + $rv .= qq{ next} if $next; + $rv .= $join if $join; + $rv .= qq{prev} if $prev; + + my $rev = $q->qs_html(o => $o < 0 ? 0 : -1); + $rv .= qq{ | reverse results}; } sub sort_relevance { @@ -313,7 +358,7 @@ sub new { bless { q => $qp->{'q'}, x => $qp->{x} || '', - o => (($qp->{o} || '0') =~ /([0-9]+)/), + o => (($qp->{o} || '0') =~ /(-?[0-9]+)/), l => $l, r => (defined $r && $r ne '0'), }, $class;