about summary refs log tree commit homepage
path: root/lib/PublicInbox/WwwListing.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/WwwListing.pm')
-rw-r--r--lib/PublicInbox/WwwListing.pm72
1 files changed, 41 insertions, 31 deletions
diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm
index a9290802..2d6c74da 100644
--- a/lib/PublicInbox/WwwListing.pm
+++ b/lib/PublicInbox/WwwListing.pm
@@ -11,6 +11,7 @@ use PublicInbox::GzipFilter qw(gzf_maybe);
 use PublicInbox::ConfigIter;
 use PublicInbox::WwwStream;
 use URI::Escape qw(uri_escape_utf8);
+use PublicInbox::MID qw(mid_escape);
 
 sub ibx_entry {
         my ($ctx, $ibx, $ce) = @_;
@@ -40,10 +41,7 @@ sub list_match_i { # ConfigIter callback
         if (defined($section)) {
                 return if $section !~ m!\Apublicinbox\.([^/]+)\z!;
                 my $ibx = $cfg->lookup_name($1) or return;
-                if (!$ibx->{-hide}->{$ctx->hide_key} &&
-                                        grep(/$re/, @{$ibx->{url} // []})) {
-                        $ctx->ibx_entry($ibx);
-                }
+                $ctx->ibx_entry($ibx) unless $ctx->hide_inbox($ibx, $re);
         } else { # undef == "EOF"
                 $ctx->{-wcb}->($ctx->psgi_triple);
         }
@@ -53,13 +51,17 @@ sub url_filter {
         my ($ctx, $key, $default) = @_;
         $key //= 'publicInbox.wwwListing';
         $default //= '404';
-        my $v = $ctx->{www}->{pi_cfg}->{lc $key} // $default;
+        my $cfg = $ctx->{www}->{pi_cfg};
+        my $v = $cfg->{lc $key} // $default;
 again:
         if ($v eq 'match=domain') {
                 my $h = $ctx->{env}->{HTTP_HOST} // $ctx->{env}->{SERVER_NAME};
                 $h =~ s/:[0-9]+\z//;
                 (qr!\A(?:https?:)?//\Q$h\E(?::[0-9]+)?/!i, "url:$h");
         } elsif ($v eq 'all') {
+                my $niu = $cfg->{lc 'publicinbox.nameIsUrl'};
+                defined($niu) && $cfg->git_bool($niu) and
+                        $ctx->{-name_is_url} = [ '.' ];
                 (qr/./, undef);
         } elsif ($v eq '404') {
                 (undef, undef);
@@ -75,6 +77,12 @@ EOF
 
 sub hide_key { 'www' }
 
+sub hide_inbox {
+        my ($ctx, $ibx, $re) = @_;
+        $ibx->{'-hide_'.$ctx->hide_key} ||
+                !grep(/$re/, @{$ibx->{url} // $ctx->{-name_is_url} // []})
+}
+
 sub add_misc_ibx { # MiscSearch->retry_reopen callback
         my ($misc, $ctx, $re, $qs) = @_;
         require PublicInbox::SearchQuery;
@@ -103,15 +111,13 @@ sub add_misc_ibx { # MiscSearch->retry_reopen callback
                 $ctx->ibx_entry($pi_cfg->ALL // die('BUG: ->ALL expected'), {});
         }
         my $mset = $misc->mset($qs, $opt); # sorts by $MODIFIED (mtime)
-        my $hide_key = $ctx->hide_key;
 
         for my $mi ($mset->items) {
                 my $doc = $mi->get_document;
                 my ($eidx_key) = PublicInbox::Search::xap_terms('Q', $doc);
                 $eidx_key // next;
                 my $ibx = $pi_cfg->lookup_eidx_key($eidx_key) // next;
-                next if $ibx->{-hide}->{$hide_key};
-                grep(/$re/, @{$ibx->{url} // []}) or next;
+                next if $ctx->hide_inbox($ibx, $re);
                 $ctx->ibx_entry($ibx, $misc->doc2ibx_cache_ent($doc));
                 if ($r) { # for descriptions in search_nav_bot
                         my $pct = PublicInbox::Search::get_pct($mi);
@@ -135,6 +141,13 @@ sub response {
         my ($re, $qs) = $ctx->url_filter;
         $re // return $ctx->psgi_triple;
         if (my $ALL = $ctx->{www}->{pi_cfg}->ALL) { # fast path
+                if ($ctx->{qp}->{a} && # "search all inboxes"
+                                $ctx->{qp}->{'q'}) {
+                        my $u = 'all/?q='.mid_escape($ctx->{qp}->{'q'});
+                        return [ 302, [ 'Location' => $u,
+                                qw(Content-Type text/plain) ],
+                                [ "Redirecting to $u\n" ] ];
+                }
                 # FIXME: test this in t/
                 $ALL->misc->reopen->retry_reopen(\&add_misc_ibx,
                                                 $ctx, $re, $qs);
@@ -154,25 +167,22 @@ sub mset_footer ($$) {
         # no footer if too few matches
         return '' if $mset->get_matches_estimated == $mset->size;
         require PublicInbox::SearchView;
-        PublicInbox::SearchView::search_nav_bot($mset, $ctx->{-sq});
+        PublicInbox::SearchView::search_nav_bot($ctx, $mset, $ctx->{-sq});
 }
 
 sub mset_nav_top {
         my ($ctx, $mset) = @_;
         my $q = $ctx->{-sq};
         my $qh = $q->{'q'} // '';
-        utf8::decode($qh);
-        $qh = ascii_html($qh);
-        $qh = qq[\nvalue="$qh"] if $qh ne '';
-        my $rv = <<EOM;
-<form
-action="./"><pre><input
-name=q
-type=text$qh /><input
-type=submit
-value="locate inbox" /></pre></form><pre>
+        if ($qh ne '') {
+                utf8::decode($qh);
+                $qh = qq[\nvalue="].ascii_html($qh).'"';
+        }
+        chop(my $rv = <<EOM);
+<form action="./"><pre><input name=q type=text$qh/><input
+type=submit value="locate inbox"/><input type=submit name=a
+value="search all inboxes"/></pre></form><pre>
 EOM
-        chomp $rv;
         if (defined($q->{'q'})) {
                 my $initial_q = $ctx->{-uxs_retried};
                 if (defined $initial_q) {
@@ -203,28 +213,28 @@ sub psgi_triple {
         my $h = [ 'Content-Type', 'text/html; charset=UTF-8',
                         'Content-Length', undef ];
         my $gzf = gzf_maybe($h, $ctx->{env});
-        $gzf->zmore('<html><head><title>public-inbox listing</title>' .
-                        $ctx->{www}->style('+/') .
-                        '</head><body>');
+        my $zfh = $gzf->zfh;
+        print $zfh '<html><head><title>public-inbox listing</title>',
+                        $ctx->{www}->style('+/'),
+                        '</head><body>';
         my $code = 404;
         if (my $list = delete $ctx->{-list}) {
                 my $mset = delete $ctx->{-mset};
                 $code = 200;
                 if ($mset) { # already sorted, so search bar:
-                        $gzf->zmore(mset_nav_top($ctx, $mset));
+                        print $zfh mset_nav_top($ctx, $mset);
                 } else { # sort config dump by ->modified
                         @$list = map { $_->[1] }
                                 sort { $b->[0] <=> $a->[0] } @$list;
                 }
-                $gzf->zmore('<pre>');
-                $gzf->zmore(join("\n", @$list));
-                $gzf->zmore(mset_footer($ctx, $mset)) if $mset;
+                print $zfh '<pre>', join("\n", @$list); # big
+                print $zfh mset_footer($ctx, $mset) if $mset;
         } elsif (my $mset = delete $ctx->{-mset}) {
-                $gzf->zmore(mset_nav_top($ctx, $mset));
-                $gzf->zmore('<pre>no matching inboxes');
-                $gzf->zmore(mset_footer($ctx, $mset));
+                print $zfh mset_nav_top($ctx, $mset),
+                                '<pre>no matching inboxes',
+                                mset_footer($ctx, $mset);
         } else {
-                $gzf->zmore('<pre>no inboxes, yet');
+                print $zfh '<pre>no inboxes, yet';
         }
         my $out = $gzf->zflush('</pre><hr><pre>'.
 qq(This is a listing of public inboxes, see the `mirror' link of each inbox