Default: C<0>
+=item publicinbox.<name>.sortorder
+
+Integer controlling the display order of this inbox on the main
+listing page. Lower values appear first. Inboxes without this
+setting are listed after all sorted inboxes, ordered by last
+modification time (descending). This is useful for pinning
+important or frequently-accessed inboxes to the top of the list.
+
+Default: none (sorted by modification time descending)
+
=item publicinbox.<name>.indexSequentialShard
See L<public-inbox-index(1)/publicInbox.indexSequentialShard>
$ibx->{$k} = $v if defined $v;
}
for my $k (qw(filter newsgroup replyto httpbackendmax feedmax
- indexlevel indexsequentialshard boost)) {
+ indexlevel indexsequentialshard boost sortorder)) {
my $v = get_1($self, "$pfx.$k") // next;
$ibx->{$k} = $v;
}
use PublicInbox::WwwStream;
use URI::Escape qw(uri_escape_utf8);
use PublicInbox::MID qw(mid_escape);
+use POSIX qw(Inf);
sub ibx_entry {
my ($ctx, $ibx, $ce) = @_;
$url = ascii_html(prurl($ctx->{env}, $url));
$tmp .= qq( <a\nhref="$url">$url</a>\n);
}
+ my $so = $ibx->{sortorder} // Inf;
push(@{$ctx->{-list}}, (scalar(@_) == 3 ? # $misc in use, already sorted
- $tmp : [ $ce->{-modified}, $tmp ] ));
+ [$so, $tmp] : [$so, $ce->{-modified}, $tmp] ));
}
sub list_match_i { # ConfigIter callback
$code = 200;
if ($mset) { # already sorted, so search bar:
print $zfh mset_nav_top($ctx, $mset);
- } else { # sort config dump by ->modified
+ # FIXME: make PublicInbox::MiscIdx index sortorder
+ # then use Xapian::MultiValueKeyMaker or
+ # Search::Xapian::MultiValueSorter (old) in
+ # PublicInbox::MiscSearch
@$list = map { $_->[1] }
- sort { $b->[0] <=> $a->[0] } @$list;
+ sort { $a->[0] <=> $b->[0] } @$list;
+ } else { # sort by sortorder (asc), then modified (desc)
+ my $so; # outside of sort block to reduce allocations
+ # $list = [ [$sortorder, {-modified}, $raw_html], ... ]
+ @$list = map { $_->[2] }
+ sort {
+ $so = $a->[0] <=> $b->[0];
+ $so ? $so : $b->[1] <=> $a->[1]
+ } @$list;
}
print $zfh '<pre>', join("\n", @$list); # big
print $zfh mset_footer($ctx, $mset) if $mset;
undef $sock;
tiny_test($json, $host, $port, 1);
+ # test sortorder config
+ undef $td;
+ open $fh, '>>', $cfgfile;
+ print $fh <<"";
+[publicinbox "bare"]
+ sortorder = 1
+[publicinbox "v2"]
+ sortorder = 2
+
+ close $fh;
+ my $sock_so = tcp_server();
+ my ($host_so, $port_so) = tcp_host_port($sock_so);
+ $td = start_script($cmd, $env, { 3 => $sock_so });
+ {
+ my $http = HTTP::Tiny->new;
+ my $res = $http->get("http://$host_so:$port_so/");
+ is($res->{status}, 200, 'got listing with sortorder');
+ my $c = $res->{content};
+ my $bare_pos = index($c, '/bare');
+ my $v2_pos = index($c, '/v2');
+ my $alt_pos = index($c, '/alt');
+ ok($bare_pos < $v2_pos,
+ 'bare (sortorder=1) before v2 (sortorder=2)');
+ ok($v2_pos < $alt_pos,
+ 'v2 (sortorder=2) before alt (no sortorder)');
+ }
+
# grok-pull sleeps a long while some places:
# https://lore.kernel.org/tools/20211013110344.GA10632@dcvr/
skip 'TEST_GROK unset', 12 unless $ENV{TEST_GROK};