]> Sergey Matveev's repositories - public-inbox.git/commitdiff
lei inspect: use LeiMailSync->match_imap_url
authorEric Wong <e@80x24.org>
Sun, 23 May 2021 21:36:50 +0000 (21:36 +0000)
committerEric Wong <e@80x24.org>
Mon, 24 May 2021 22:31:36 +0000 (22:31 +0000)
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
lib/PublicInbox/LeiInspect.pm
lib/PublicInbox/LeiMailSync.pm
t/lei-import-imap.t

index 82a4db04f987e45287618004ae9a22d17bfe566b..404570c5541b4a26fc675d59e4f991ec7698d752 100644 (file)
@@ -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';
index f79ebc9af82e1c7cb1953df73f11d28b010815de..7fd33289c140ffdcc70c97f0a097d1615647a3dd 100644 (file)
@@ -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);
index 32e17c6576da3c269b4dfbf0c268c65d669401c3..b298668658b650a7d269f96896e062e4e8ba835a 100644 (file)
@@ -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;
index d424ebb1f9815411900ba39f8a94005373c859aa..d3935c828514c4895cc4f511419b10be88e7758b 100644 (file)
@@ -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;