# Copyright (C) 2021 all contributors # License: AGPL-3.0+ # "lei ls-search" to display results saved via "lei q --save" package PublicInbox::LeiLsSearch; use strict; use v5.10.1; use PublicInbox::LeiSavedSearch; use parent qw(PublicInbox::IPC); sub do_ls_search_long { my ($self, $pfx) = @_; # TODO: share common JSON output code with LeiOverview my $json = $self->{json}->new->utf8->canonical; my $lei = $self->{lei}; $json->ascii(1) if $lei->{opt}->{ascii}; my $fmt = $lei->{opt}->{'format'}; $lei->{1}->autoflush(0); my $ORS = "\n"; my $pretty = $lei->{opt}->{pretty}; my $EOR; # TODO: compact pretty like "lei q" if ($fmt =~ /\A(concat)?json\z/ && $pretty) { $EOR = ($1//'') eq 'concat' ? "\n}" : "\n},"; } if ($fmt eq 'json') { $lei->out('['); $ORS = ",\n"; } my @x = sort(grep(/\A\Q$pfx/, PublicInbox::LeiSavedSearch::list($lei))); while (my $x = shift @x) { $ORS = '' if !scalar(@x); my $lss = PublicInbox::LeiSavedSearch->up($lei, $x) or next; my $cfg = $lss->{-cfg}; my $ent = { q => $cfg->get_all('lei.q'), output => $cfg->{'lei.q.output'}, }; for my $k ($lss->ARRAY_FIELDS) { my $ary = $cfg->get_all("lei.q.$k") // next; $ent->{$k} = $ary; } for my $k ($lss->BOOL_FIELDS) { my $val = $cfg->{"lei.q.$k"} // next; $ent->{$k} = $val; } if (defined $EOR) { # pretty, but compact $EOR = "\n}" if !scalar(@x); my $buf = "{\n"; $buf .= join(",\n", map {; my $f = $_; if (my $v = $ent->{$f}) { $v = $json->encode([$v]); qq{ "$f": }.substr($v, 1, -1); } else { (); } # key order by importance } (qw(output q), $lss->ARRAY_FIELDS, $lss->BOOL_FIELDS) ); $lei->out($buf .= $EOR); } else { $lei->out($json->encode($ent), $ORS); } } if ($fmt eq 'json') { $lei->out("]\n"); } elsif ($fmt eq 'concatjson') { $lei->out("\n"); } } sub bg_worker ($$$) { my ($lei, $pfx, $json) = @_; my $self = bless { json => $json }, __PACKAGE__; my ($op_c, $ops) = $lei->workers_start($self, 1); $lei->{wq1} = $self; $self->wq_io_do('do_ls_search_long', [], $pfx); $self->wq_close; $lei->wait_wq_events($op_c, $ops); } sub lei_ls_search { my ($lei, $pfx) = @_; my $fmt = $lei->{opt}->{'format'} // ''; if ($lei->{opt}->{l}) { $lei->{opt}->{'format'} //= $fmt = 'json'; } my $json; my $tty = -t $lei->{1}; $lei->start_pager if $tty; if ($fmt =~ /\A(ldjson|ndjson|jsonl|(?:concat)?json)\z/) { $lei->{opt}->{pretty} //= $tty; $json = ref(PublicInbox::Config->json); } elsif ($fmt ne '') { return $lei->fail("unknown format: $fmt"); } my $ORS = "\n"; if ($lei->{opt}->{z}) { return $lei->fail('-z and --format do not mix') if $json; $ORS = "\0"; } $pfx //= ''; return bg_worker($lei, $pfx, $json) if $json; for (sort(grep(/\A\Q$pfx/, PublicInbox::LeiSavedSearch::list($lei)))) { $lei->out($_, $ORS); } } 1;