From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 1/2] lei inspect: use LeiMailSync->match_imap_url
Date: Sun, 23 May 2021 21:36:50 +0000 [thread overview]
Message-ID: <20210523213651.24941-2-e@80x24.org> (raw)
In-Reply-To: <20210523213651.24941-1-e@80x24.org>
Move match_imap_url into LeiMailSync so it can be used in more
places, such as "lei inspect". Upcoming commands such as
"lei forget-mail-sync" and {add,forget,pause,resume}-watch will
also support relaxed IMAP matching rules since there's
no reasonable way to expect users use ";UIDVALIDITY=" on the
command-line.
---
lib/PublicInbox/LeiExportKw.pm | 43 ++++++----------------------------
lib/PublicInbox/LeiInspect.pm | 13 +---------
lib/PublicInbox/LeiMailSync.pm | 32 +++++++++++++++++++++++++
t/lei-import-imap.t | 10 ++++++--
4 files changed, 48 insertions(+), 50 deletions(-)
diff --git a/lib/PublicInbox/LeiExportKw.pm b/lib/PublicInbox/LeiExportKw.pm
index 82a4db04..404570c5 100644
--- a/lib/PublicInbox/LeiExportKw.pm
+++ b/lib/PublicInbox/LeiExportKw.pm
@@ -75,7 +75,7 @@ sub input_path_url {
my $mdir = $1;
require PublicInbox::LeiToMail; # kw2suffix
$lms->each_src($input, \&export_kw_md, $self, $mdir);
- } elsif ($input =~ m!\Aimaps?://!) {
+ } elsif ($input =~ m!\Aimaps?://i!) {
my $uri = PublicInbox::URIimap->new($input);
my $mic = $self->{nwr}->mic_for_folder($uri);
$lms->each_src($$uri, \&export_kw_imap, $self, $mic);
@@ -84,37 +84,6 @@ sub input_path_url {
$lms->lms_commit;
}
-sub match_imap_url ($$) {
- my ($all, $url) = @_; # $all = [ $lms->folders ];
- require PublicInbox::URIimap;
- my $cli = PublicInbox::URIimap->new($url)->canonical;
- my ($s, $h, $mb) = ($cli->scheme, $cli->host, $cli->mailbox);
- my @uri = map { PublicInbox::URIimap->new($_)->canonical }
- grep(m!\A\Q$s\E://.*?\Q$h\E\b.*?/\Q$mb\E\b!, @$all);
- my @match;
- for my $x (@uri) {
- next if $x->mailbox ne $cli->mailbox;
- next if $x->host ne $cli->host;
- next if $x->port != $cli->port;
- my $x_uidval = $x->uidvalidity;
- next if ($cli->uidvalidity // $x_uidval) != $x_uidval;
-
- # allow nothing in CLI to possibly match ";AUTH=ANONYMOUS"
- if (defined($x->auth) && !defined($cli->auth) &&
- !defined($cli->user)) {
- push @match, $x;
- # or maybe user was forgotten on CLI:
- } elsif (defined($x->user) && !defined($cli->user)) {
- push @match, $x;
- } elsif (($x->user//"\0") eq ($cli->user//"\0")) {
- push @match, $x;
- }
- }
- return $match[0] if scalar(@match) <= 1;
- warn "E: `$url' is ambiguous:\n\t", join("\n\t", @match), "\n";
- undef;
-}
-
sub lei_export_kw {
my ($lei, @folders) = @_;
my $sto = $lei->_lei_store or return $lei->fail(<<EOM);
@@ -166,12 +135,14 @@ EOM
$_ = $d;
} elsif (m!\Aimaps?://!i) {
my $orig = $_;
- if (my $canon = match_imap_url(\@all, $orig)) {
+ my $res = $lms->match_imap_url($orig, $all);
+ if (ref $res) {
+ $_ = $$res;
$lei->qerr(<<EOM);
-# using `$canon' instead of `$orig'
+# using `$res' instead of `$orig'
EOM
- $_ = $canon;
} else {
+ $lei->err($res) if defined $res;
push @no, $orig;
}
} else {
@@ -188,7 +159,7 @@ EOF
$lei->{opt}->{'mail-sync'} = 1; # for prepare_inputs
$self->prepare_inputs($lei, \@folders) or return;
my $j = $opt->{jobs} // scalar(@{$self->{inputs}}) || 1;
- if (my @ro = grep(!/\A(?:maildir|imaps?):/, @folders)) {
+ if (my @ro = grep(!/\A(?:maildir|imaps?):/i, @folders)) {
return $lei->fail("cannot export to read-only folders: @ro");
}
my $m = $opt->{mode} // 'merge';
diff --git a/lib/PublicInbox/LeiInspect.pm b/lib/PublicInbox/LeiInspect.pm
index f79ebc9a..7fd33289 100644
--- a/lib/PublicInbox/LeiInspect.pm
+++ b/lib/PublicInbox/LeiInspect.pm
@@ -31,18 +31,7 @@ sub inspect_sync_folder ($$) {
my $lms = $lse->lms or return $ent;
my @folders;
if ($folder =~ m!\Aimaps?://!i) {
- require PublicInbox::URIimap;
- my $uri = PublicInbox::URIimap->new($folder)->canonical;
- if (defined($uri->uidvalidity)) {
- $folders[0] = $$uri;
- } else {
- my @maybe = $lms->folders($$uri);
- @folders = grep {
- my $u = PublicInbox::URIimap->new($_);
- $uri->uidvalidity($u->uidvalidity);
- $$uri eq $$u;
- } @maybe;
- }
+ @folders = map { $_->as_string } $lms->match_imap_url($folder);
} elsif ($folder =~ m!\A(maildir|mh):(.+)!i) {
my $type = lc $1;
$folders[0] = "$type:".$lei->abs_path($2);
diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm
index 32e17c65..b2986686 100644
--- a/lib/PublicInbox/LeiMailSync.pm
+++ b/lib/PublicInbox/LeiMailSync.pm
@@ -265,4 +265,36 @@ WHERE b.oidbin = ?
undef;
}
+sub match_imap_url {
+ my ($self, $url, $all) = @_; # $all = [ $lms->folders ];
+ $all //= [ $self->folders ];
+ require PublicInbox::URIimap;
+ my $want = PublicInbox::URIimap->new($url)->canonical;
+ my ($s, $h, $mb) = ($want->scheme, $want->host, $want->mailbox);
+ my @uri = map { PublicInbox::URIimap->new($_)->canonical }
+ grep(m!\A\Q$s\E://.*?\Q$h\E\b.*?/\Q$mb\E\b!, @$all);
+ my @match;
+ for my $x (@uri) {
+ next if $x->mailbox ne $want->mailbox;
+ next if $x->host ne $want->host;
+ next if $x->port != $want->port;
+ my $x_uidval = $x->uidvalidity;
+ next if ($want->uidvalidity // $x_uidval) != $x_uidval;
+
+ # allow nothing in want to possibly match ";AUTH=ANONYMOUS"
+ if (defined($x->auth) && !defined($want->auth) &&
+ !defined($want->user)) {
+ push @match, $x;
+ # or maybe user was forgotten on CLI:
+ } elsif (defined($x->user) && !defined($want->user)) {
+ push @match, $x;
+ } elsif (($x->user//"\0") eq ($want->user//"\0")) {
+ push @match, $x;
+ }
+ }
+ return @match if wantarray;
+ scalar(@match) <= 1 ? $match[0] :
+ "E: `$url' is ambiguous:\n\t".join("\n\t", @match)."\n";
+}
+
1;
diff --git a/t/lei-import-imap.t b/t/lei-import-imap.t
index d424ebb1..d3935c82 100644
--- a/t/lei-import-imap.t
+++ b/t/lei-import-imap.t
@@ -22,9 +22,15 @@ test_lei({ tmpdir => $tmpdir }, sub {
is_deeply(json_utf8->decode($lei_out), {}, 'no inspect stats, yet');
lei_ok('import', $url);
+ lei_ok('inspect', $url);
+ my $res = json_utf8->decode($lei_out);
+ is(scalar keys %$res, 1, 'got one key in inspect URL');
+ my $re = qr!\Aimap://;AUTH=ANONYMOUS\@\Q$host_port\E
+ /t\.v2\.0;UIDVALIDITY=\d+!x;
+ like((keys %$res)[0], qr/$re\z/, 'got expanded key');
+
lei_ok 'ls-mail-sync';
- like($lei_out, qr!\Aimap://;AUTH=ANONYMOUS\@\Q$host_port\E
- /t\.v2\.0;UIDVALIDITY=\d+\n\z!x, 'ls-mail-sync');
+ like($lei_out, qr!$re\n\z!, 'ls-mail-sync');
chomp(my $u = $lei_out);
lei_ok('import', $u, \'UIDVALIDITY match in URL');
$url = $u;
next prev parent reply other threads:[~2021-05-23 21:36 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-23 21:36 [PATCH 0/2] lei IMAP usability stuff Eric Wong
2021-05-23 21:36 ` Eric Wong [this message]
2021-05-23 21:36 ` [PATCH 2/2] lei_mail_sync: reject IMAP URLs w/o UIDVALIDITY Eric Wong
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=20210523213651.24941-2-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.
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).