# Copyright (C) 2015 all contributors <meta@public-inbox.org>
# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+#
+# Displays search results for the web interface
package PublicInbox::SearchView;
use strict;
use warnings;
use PublicInbox::View;
use PublicInbox::MID qw(mid2path mid_clean);
use Email::MIME;
-use POSIX qw/strftime/;
+require PublicInbox::Git;
our $LIM = 50;
sub sres_top_html {
$total = $mset->get_matches_estimated;
};
my $err = $@;
- my $res = html_start($q, $ctx) . PublicInbox::View::PRE_WRAP;
+ my $res = html_start($q, $ctx) . '<pre>';
if ($err) {
$code = 400;
- $res .= err_txt($err) . "</pre><hr /><pre>" . foot($ctx);
+ $res .= err_txt($ctx, $err) . "</pre><hr /><pre>" . foot($ctx);
} elsif ($total == 0) {
$code = 404;
$res .= "\n\n[No results found]</pre><hr /><pre>".foot($ctx);
my $x = $q->{x};
return sub { adump($_[0], $mset, $q, $ctx) } if ($x eq 'A');
- $res .= search_nav_top($mset, $q);
+ $res .= search_nav_top($mset, $q) . "\n\n";
if ($x eq 't') {
return sub { tdump($_[0], $res, $mset, $q, $ctx) };
}
- $res .= "\n\n";
dump_mset(\$res, $mset);
- $res .= search_nav_bot($mset, $q) . "\n\n" . foot($ctx);
+ $res .= '</pre>' . search_nav_bot($mset, $q) .
+ "\n\n" . foot($ctx);
}
$res .= "</pre></body></html>";
[$code, ['Content-Type'=>'text/html; charset=UTF-8'], [$res]];
}
+# display non-threaded search results similar to what users expect from
+# regular WWW search engines:
sub dump_mset {
my ($res, $mset) = @_;
my $s = PublicInbox::Hval->new_oneline($smsg->subject);
my $f = $smsg->from_name;
$f = PublicInbox::Hval->new_oneline($f)->as_html;
- my $d = strftime('%Y-%m-%d %H:%M', gmtime($smsg->ts));
+ my $ts = PublicInbox::View::fmt_ts($smsg->ts);
my $mid = PublicInbox::Hval->new_msgid($smsg->mid)->as_href;
$$res .= qq{$rank. <b><a\nhref="$mid/">}.
$s->as_html . "</a></b>\n";
- $$res .= "$pfx - by $f @ $d UTC [$pct%]\n\n";
+ $$res .= "$pfx - by $f @ $ts UTC [$pct%]\n\n";
}
}
sub err_txt {
- my ($err) = @_;
- my $u = 'http://xapian.org/docs/queryparser.html';
+ my ($ctx, $err) = @_;
+ my $u = '//xapian.org/docs/queryparser.html';
+ $u = PublicInbox::Hval::prurl($ctx->{cgi}->{env}, $u);
$err =~ s/^\s*Exception:\s*//; # bad word to show users :P
$err = PublicInbox::Hval->new_oneline($err)->as_html;
"\n\nBad query: <b>$err</b>\n" .
my $x = $q->{x};
if ($x eq '') {
my $t = $q->qs_html(x => 't');
- $rv .= qq{<b>summary</b>|};
- $rv .= qq{<a\nhref="?$t">threaded</a>}
+ $rv .= qq{<b>summary</b>|<a\nhref="?$t">threaded</a>}
} elsif ($q->{x} eq 't') {
my $s = $q->qs_html(x => '');
- $rv .= qq{<a\nhref="?$s">summary</a>|};
- $rv .= qq{<b>threaded</b>};
+ $rv .= qq{<a\nhref="?$s">summary</a>|<b>threaded</b>};
}
my $A = $q->qs_html(x => 'A', r => undef);
- $rv .= qq{|<a\nhref="?$A">Atom</a>};
- $rv .= ']';
+ $rv .= qq{|<a\nhref="?$A">Atom feed</a>]};
}
sub search_nav_bot {
sub tdump {
my ($cb, $res, $mset, $q, $ctx) = @_;
my $fh = $cb->([200, ['Content-Type'=>'text/html; charset=UTF-8']]);
- $fh->write($res);
+ $fh->write($res .= '</pre>');
my %pct;
my @m = map {
my $i = $_;
$th->order(*PublicInbox::View::rsort_ts);
}
- require PublicInbox::GitCatFile;
- my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
- my $state = { ctx => $ctx, anchor_idx => 0, pct => \%pct };
+ my $git = $ctx->{git} ||= PublicInbox::Git->new($ctx->{git_dir});
+ my $state = {
+ ctx => $ctx,
+ anchor_idx => 0,
+ pct => \%pct,
+ cur_level => 0
+ };
$ctx->{searchview} = 1;
tdump_ent($fh, $git, $state, $_, 0) for $th->rootset;
- $git = undef;
+ PublicInbox::View::thread_adj_level($fh, $state, 0);
Email::Address->purge_cache;
$fh->write(search_nav_bot($mset, $q). "\n\n" .
};
}
if ($mime) {
+ my $end =
+ PublicInbox::View::thread_adj_level($fh, $state, $level);
PublicInbox::View::index_entry($fh, $mime, $level, $state);
+ $fh->write($end) if $end;
} else {
my $mid = $node->messageid;
- $fh->write(PublicInbox::View::ghost_table('', $mid, $level));
+ PublicInbox::View::ghost_flush($fh, $state, '', $mid, $level);
}
tdump_ent($fh, $git, $state, $node->child, $level + 1);
tdump_ent($fh, $git, $state, $node->next, $level);
my $qh = $query->as_html;
my $A = $q->qs_html(x => 'A', r => undef);
- my $res = "<html><head><title>$qh - search results</title>" .
+ my $res = '<html><head>' . PublicInbox::Hval::STYLE .
+ "<title>$qh - search results</title>" .
qq{<link\nrel=alternate\ntitle="Atom feed"\n} .
qq!href="?$A"\ntype="application/atom+xml"/></head>! .
qq{<body><form\naction="">} .
sub adump {
my ($cb, $mset, $q, $ctx) = @_;
my $fh = $cb->([ 200, ['Content-Type' => 'application/atom+xml']]);
- require PublicInbox::GitCatFile;
- my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
+ my $git = $ctx->{git} ||= PublicInbox::Git->new($ctx->{git_dir});
my $feed_opts = PublicInbox::Feed::get_feedopts($ctx);
my $x = PublicInbox::Hval->new_oneline($q->{q})->as_html;
$x = qq{$x - search results};
$x = mid2path($x);
PublicInbox::Feed::add_to_feed($feed_opts, $fh, $x, $git);
}
- $git = undef;
PublicInbox::Feed::end_feed($fh);
}
$self = $tmp;
}
- my $q = PublicInbox::Hval->new($self->{q})->as_href;
+ my $q = PublicInbox::Hval->new_oneline($self->{q})->as_href;
$q =~ s/%20/+/g; # improve URL readability
my $qs = "q=$q";