user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 5/5] lei: add "lei up" to complement "lei q --save"
Date: Tue, 13 Apr 2021 10:54:46 +0000	[thread overview]
Message-ID: <20210413105446.7245-6-e@80x24.org> (raw)
In-Reply-To: <20210413105446.7245-1-e@80x24.org>

The command isn't finalized, yet, but it's intended to update
an existing saved search.
---
 MANIFEST                          |  1 +
 lib/PublicInbox/LEI.pm            |  2 ++
 lib/PublicInbox/LeiQuery.pm       |  2 +-
 lib/PublicInbox/LeiSavedSearch.pm | 24 ++++++++++------
 lib/PublicInbox/LeiToMail.pm      | 12 ++++----
 lib/PublicInbox/LeiUp.pm          | 46 +++++++++++++++++++++++++++++++
 t/lei-q-save.t                    | 17 ++++++++++--
 7 files changed, 88 insertions(+), 16 deletions(-)
 create mode 100644 lib/PublicInbox/LeiUp.pm

diff --git a/MANIFEST b/MANIFEST
index 20615abc..1b7d16ee 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -208,6 +208,7 @@ lib/PublicInbox/LeiStoreErr.pm
 lib/PublicInbox/LeiSucks.pm
 lib/PublicInbox/LeiTag.pm
 lib/PublicInbox/LeiToMail.pm
+lib/PublicInbox/LeiUp.pm
 lib/PublicInbox/LeiXSearch.pm
 lib/PublicInbox/Linkify.pm
 lib/PublicInbox/Listener.pm
diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index 7292d0f2..4b87c104 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -135,6 +135,8 @@ our %CMD = ( # sorted in order of importance/use:
 	sort|s=s reverse|r offset=i pretty jobs|j=s globoff|g augment|a
 	import-before! lock=s@ rsyncable alert=s@ mua=s verbose|v+), @c_opt,
 	opt_dash('limit|n=i', '[0-9]+') ],
+'up' => [ 'SEARCH_TERMS...', 'update saved search',
+	qw(jobs|j=s lock=s@ alert=s@ mua=s verbose|v+), @c_opt ],
 
 'blob' => [ 'OID', 'show a git blob, reconstructing from mail if necessary',
 	qw(git-dir=s@ cwd! verbose|v+ mail! oid-a|A=s path-a|a=s path-b|b=s),
diff --git a/lib/PublicInbox/LeiQuery.pm b/lib/PublicInbox/LeiQuery.pm
index 8bca1020..7456f7f9 100644
--- a/lib/PublicInbox/LeiQuery.pm
+++ b/lib/PublicInbox/LeiQuery.pm
@@ -12,7 +12,7 @@ sub prep_ext { # externals_each callback
 	$lxs->prepare_external($loc) unless $exclude->{$loc};
 }
 
-sub _start_query {
+sub _start_query { # used by "lei q" and "lei up"
 	my ($self) = @_;
 	PublicInbox::LeiOverview->new($self) or return;
 	my $opt = $self->{opt};
diff --git a/lib/PublicInbox/LeiSavedSearch.pm b/lib/PublicInbox/LeiSavedSearch.pm
index ab9f393b..815008fd 100644
--- a/lib/PublicInbox/LeiSavedSearch.pm
+++ b/lib/PublicInbox/LeiSavedSearch.pm
@@ -17,18 +17,12 @@ use PublicInbox::Hval qw(to_filename);
 sub new {
 	my ($cls, $lei, $dir) = @_;
 	my $self = bless { ale => $lei->ale, -cfg => {} }, $cls;
-	if (defined $dir) { # updating existing saved search
+	if (defined $dir) { # updating existing saved search via "lei up"
 		my $f = $self->{'-f'} = "$dir/lei.saved-search";
 		-f $f && -r _ or
 			return $lei->fail("$f non-existent or unreadable");
 		$self->{-cfg} = PublicInbox::Config::git_config_dump($f);
-		my $q = $lei->{mset_opt}->{q_raw} = $self->{-cfg}->{'lei.q'} //
-					return $lei->fail("lei.q unset in $f");
-		my $lse = $lei->{lse} // die 'BUG: {lse} missing';
-		$lei->{mset_opt}->{qstr} = ref($q) ?
-				$lse->query_argv_to_string($lse->git, $q) :
-				$lse->query_approxidate($lse->git, $q);
-	} else { # new saved search
+	} else { # new saved search "lei q --save"
 		my $saved_dir = $lei->store_path . '/../saved-searches/';
 		my (@name) = ($lei->{ovv}->{dst} =~ m{([\w\-\.]+)/*\z});
 		push @name, to_filename($lei->{mset_opt}->{qstr});
@@ -42,6 +36,20 @@ sub new {
 		} else {
 			cfg_set($self, 'lei.q', $q);
 		}
+		my $fmt = $lei->{opt}->{'format'};
+		cfg_set($self, 'lei.q.format', $fmt) if defined $fmt;
+		cfg_set($self, 'lei.q.output', $lei->{opt}->{output});
+		for my $k (qw(only include exclude)) {
+			my $ary = $lei->{opt}->{$k} // next;
+			for my $x (@$ary) {
+				cfg_set($self, '--add', "lei.q.$k", $x);
+			}
+		}
+		for my $k (qw(external local remote import-remote
+				import-before threads)) {
+			my $val = $lei->{opt}->{$k} // next;
+			cfg_set($self, "lei.q.$k", $val);
+		}
 	}
 	bless $self->{-cfg}, 'PublicInbox::Config';
 	$self->{lock_path} = "$self->{-f}.flock";
diff --git a/lib/PublicInbox/LeiToMail.pm b/lib/PublicInbox/LeiToMail.pm
index bd2b714a..4ebaf8f3 100644
--- a/lib/PublicInbox/LeiToMail.pm
+++ b/lib/PublicInbox/LeiToMail.pm
@@ -349,11 +349,13 @@ sub new {
 		die "bad mail --format=$fmt\n";
 	}
 	$self->{dst} = $dst;
-	my $dd_cls = 'PublicInbox::'.
-		($lei->{opt}->{save} ? 'LeiSavedSearch' : 'LeiDedupe');
-	eval "require $dd_cls";
-	die "$dd_cls: $@" if $@;
-	$lei->{dedupe} = $dd_cls->new($lei);
+	$lei->{dedupe} = $lei->{lss} // do {
+		my $dd_cls = 'PublicInbox::'.
+			($lei->{opt}->{save} ? 'LeiSavedSearch' : 'LeiDedupe');
+		eval "require $dd_cls";
+		die "$dd_cls: $@" if $@;
+		$dd_cls->new($lei);
+	};
 	$self;
 }
 
diff --git a/lib/PublicInbox/LeiUp.pm b/lib/PublicInbox/LeiUp.pm
new file mode 100644
index 00000000..386a7566
--- /dev/null
+++ b/lib/PublicInbox/LeiUp.pm
@@ -0,0 +1,46 @@
+# Copyright (C) 2021 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# "lei up" - updates the result of "lei q --save"
+package PublicInbox::LeiUp;
+use strict;
+use v5.10.1;
+use PublicInbox::LeiSavedSearch;
+use PublicInbox::LeiOverview;
+
+sub lei_up {
+	my ($lei, $dir) = @_;
+	$lei->{lse} = $lei->_lei_store(1)->search;
+	my $lss = PublicInbox::LeiSavedSearch->new($lei, $dir) or return;
+	my $mset_opt = $lei->{mset_opt} = { relevance => -2 };
+	$mset_opt->{limit} = $lei->{opt}->{limit} // 10000;
+	my $q = $mset_opt->{q_raw} = $lss->{-cfg}->{'lei.q'} //
+				return $lei->fail("lei.q unset in $lss->{-f}");
+	my $lse = $lei->{lse} // die 'BUG: {lse} missing';
+	if (ref($q)) {
+		$mset_opt->{qstr} = $lse->query_argv_to_string($lse->git, $q);
+	} else {
+		$lse->query_approxidate($lse->git, $mset_opt->{qstr} = $q);
+	}
+	$lei->{opt}->{output} = $lss->{-cfg}->{'lei.q.output'} //
+		return $lei->fail("lei.q.output unset in $lss->{-f}");
+	$lei->{opt}->{'format'} //= $lss->{-cfg}->{'lei.q.format'}; # optional
+
+	my $to_avref = $lss->{-cfg}->can('_array');
+	for my $k (qw(only include exclude)) {
+		my $v = $lss->{-cfg}->{"lei.q.$k"} // next;
+		$lei->{opt}->{$k} = $to_avref->($v);
+	}
+	for my $k (qw(external local remote
+			import-remote import-before threads)) {
+		my $v = $lss->{-cfg}->{"lei.q.$k"} // next;
+		$lei->{opt}->{$k} = $v;
+	}
+	$lei->{lss} = $lss; # for LeiOverview->new
+	my $lxs = $lei->lxs_prepare or return;
+	$lei->ale->refresh_externals($lxs);
+	$lei->{opt}->{save} = 1;
+	$lei->_start_query;
+}
+
+1;
diff --git a/t/lei-q-save.t b/t/lei-q-save.t
index 56f7cb37..a6d579cf 100644
--- a/t/lei-q-save.t
+++ b/t/lei-q-save.t
@@ -2,11 +2,24 @@
 # Copyright (C) 2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
+my $doc1 = eml_load('t/plack-qp.eml');
+my $doc2 = eml_load('t/utf8.eml');
 test_lei(sub {
 	my $home = $ENV{HOME};
-	lei_ok qw(import t/plack-qp.eml);
-	lei_ok qw(q --save z:0..), '-o', "$home/md/";
+	lei_ok qw(import -q t/plack-qp.eml);
+	lei_ok qw(q -q --save z:0..), '-o', "$home/md/";
+	my %before = map { $_ => 1 } glob("$home/md/cur/*");
+	is_deeply(eml_load((keys %before)[0]), $doc1, 'doc1 matches');
+
 	my @s = glob("$home/.local/share/lei/saved-searches/md-*");
 	is(scalar(@s), 1, 'got one saved search');
+
+	# ensure "lei up" works, since it compliments "lei q --save"
+	lei_ok qw(import t/utf8.eml);
+	lei_ok qw(up), $s[0];
+	my %after = map { $_ => 1 } glob("$home/md/cur/*");
+	is(delete $after{(keys(%before))[0]}, 1, 'original message kept');
+	is(scalar(keys %after), 1, 'one new message added');
+	is_deeply(eml_load((keys %after)[0]), $doc2, 'doc2 matches');
 });
 done_testing;

      parent reply	other threads:[~2021-04-13 10:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-13 10:54 [PATCH 0/5] "lei q --save" + "lei up" Eric Wong
2021-04-13 10:54 ` [PATCH 1/5] lei_xsearch: use per-external queries when not sorting Eric Wong
2021-04-13 10:54 ` [PATCH 2/5] lei_dedupe: adjust to prepare for saved searches Eric Wong
2021-04-13 10:54 ` [PATCH 3/5] lei_query: rearrange internals to capture query early Eric Wong
2021-04-13 10:54 ` [PATCH 4/5] lei q: start wiring up saved search Eric Wong
2021-04-13 11:25   ` Eric Wong
2021-04-13 19:13     ` Eric Wong
2021-04-13 10:54 ` Eric Wong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210413105446.7245-6-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).