]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LeiExportKw.pm
get rid of unnecessary bytes::length usage
[public-inbox.git] / lib / PublicInbox / LeiExportKw.pm
index 82a4db04f987e45287618004ae9a22d17bfe566b..42a5ff2269d0a16a2875ccc0c9188c08ea4d4b8f 100644 (file)
@@ -10,8 +10,7 @@ use Errno qw(EEXIST ENOENT);
 
 sub export_kw_md { # LeiMailSync->each_src callback
        my ($oidbin, $id, $self, $mdir) = @_;
-       my $oidhex = unpack('H*', $oidbin);
-       my $sto_kw = $self->{lse}->oid_keywords($oidhex) or return;
+       my $sto_kw = $self->{lse}->oidbin_keywords($oidbin) or return;
        my $bn = $$id;
        my ($md_kw, $unknown, @try);
        if ($bn =~ s/:2,([a-zA-Z]*)\z//) {
@@ -28,6 +27,7 @@ sub export_kw_md { # LeiMailSync->each_src callback
                PublicInbox::LeiToMail::kw2suffix([keys %$sto_kw], @$unknown);
        my $dst = "$mdir/cur/$bn";
        my @fail;
+       my $lei = $self->{lei};
        for my $d (@try) {
                my $src = "$mdir/$d/$$id";
                next if $src eq $dst;
@@ -39,15 +39,15 @@ sub export_kw_md { # LeiMailSync->each_src callback
                        # unlink(2) may ENOENT from parallel invocation,
                        # ignore it, but not other serious errors
                        if (!unlink($src) and $! != ENOENT) {
-                               $self->{lei}->child_error(1,
-                                                       "E: unlink($src): $!");
+                               $lei->child_error(1, "E: unlink($src): $!");
                        }
-                       $self->{lms}->mv_src("maildir:$mdir",
-                                               $oidbin, $id, $bn) or die;
+                       $lei->{sto}->ipc_do('lms_mv_src', "maildir:$mdir",
+                                               $oidbin, $id, $bn);
                        return; # success anyways if link(2) worked
                }
                if ($! == ENOENT && !-e $src) { # some other process moved it
-                       $self->{lms}->clear_src("maildir:$mdir", $id);
+                       $lei->{sto}->ipc_do('lms_clear_src',
+                                               "maildir:$mdir", $id);
                        next;
                }
                push @fail, $src if $! != EEXIST;
@@ -56,63 +56,31 @@ sub export_kw_md { # LeiMailSync->each_src callback
        # both tries failed
        my $e = $!;
        my $orig = '['.join('|', @fail).']';
-       $self->{lei}->child_error(1, "link($orig, $dst) ($oidhex): $e");
+       my $oidhex = unpack('H*', $oidbin);
+       $lei->child_error(1, "link($orig, $dst) ($oidhex): $e");
 }
 
 sub export_kw_imap { # LeiMailSync->each_src callback
        my ($oidbin, $id, $self, $mic) = @_;
-       my $oidhex = unpack('H*', $oidbin);
-       my $sto_kw = $self->{lse}->oid_keywords($oidhex) or return;
+       my $sto_kw = $self->{lse}->oidbin_keywords($oidbin) or return;
        $self->{imap_mod_kw}->($self->{nwr}, $mic, $id, [ keys %$sto_kw ]);
 }
 
 # overrides PublicInbox::LeiInput::input_path_url
 sub input_path_url {
        my ($self, $input, @args) = @_;
-       my $lms = $self->{lms} //= $self->{lse}->lms;
-       $lms->lms_begin;
+       my $lms = $self->{-lms_ro} //= $self->{lse}->lms;
        if ($input =~ /\Amaildir:(.+)/i) {
                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);
                $mic->expunge;
        } else { die "BUG: $input not supported" }
-       $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;
+       my $wait = $self->{lei}->{sto}->ipc_do('done');
 }
 
 sub lei_export_kw {
@@ -125,70 +93,18 @@ EOM
 lei mail_sync uninitialized, see lei-import(1)
 EOM
        my $opt = $lei->{opt};
-       my $all = $opt->{all};
-       my @all = $lms->folders;
-       if (defined $all) { # --all=<local|remote>
-               my %x = map { $_ => $_ } split(/,/, $all);
-               my @ok = grep(defined, delete(@x{qw(local remote), ''}));
-               my @no = keys %x;
-               if (@no) {
-                       @no = (join(',', @no));
-                       return $lei->fail(<<EOM);
---all=@no not accepted (must be `local' and/or `remote')
-EOM
-               }
-               my (%seen, @inc);
-               for my $ok (@ok) {
-                       if ($ok eq 'local') {
-                               @inc = grep(!m!\A[a-z0-9\+]+://!i, @all);
-                       } elsif ($ok eq 'remote') {
-                               @inc = grep(m!\A[a-z0-9\+]+://!i, @all);
-                       } elsif ($ok ne '') {
-                               return $lei->fail("--all=$all not understood");
-                       } else {
-                               @inc = @all;
-                       }
-                       for (@inc) {
-                               push(@folders, $_) unless $seen{$_}++;
-                       }
-               }
-               return $lei->fail(<<EOM) if !@folders;
-no --mail-sync folders known to lei
-EOM
+       if (defined(my $all = $opt->{all})) { # --all=<local|remote>
+               $lms->group2folders($lei, $all, \@folders) or return;
        } else {
-               my %all = map { $_ => 1 } @all;
-               my @no;
-               for (@folders) {
-                       next if $all{$_}; # ok
-                       if (-d "$_/new" && -d "$_/cur") {
-                               my $d = 'maildir:'.$lei->rel2abs($_);
-                               push(@no, $_) unless $all{$d};
-                               $_ = $d;
-                       } elsif (m!\Aimaps?://!i) {
-                               my $orig = $_;
-                               if (my $canon = match_imap_url(\@all, $orig)) {
-                                       $lei->qerr(<<EOM);
-# using `$canon' instead of `$orig'
-EOM
-                                       $_ = $canon;
-                               } else {
-                                       push @no, $orig;
-                               }
-                       } else {
-                               push @no, $_;
-                       }
-               }
-               my $no = join("\n\t", @no);
-               return $lei->fail(<<EOF) if @no;
-No sync information for: $no
-Run `lei ls-mail-sync' to display valid choices
-EOF
+               my $err = $lms->arg2folder($lei, \@folders);
+               $lei->qerr(@{$err->{qerr}}) if $err->{qerr};
+               return $lei->fail($err->{fail}) if $err->{fail};
        }
        my $self = bless { lse => $lse }, __PACKAGE__;
        $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';
@@ -206,15 +122,16 @@ EOM
                $self->{imap_mod_kw} = $net->can($self->{-merge_kw} ?
                                        'imap_add_kw' : 'imap_set_kw');
        }
-       undef $lms;
+       undef $lms; # for fork
        my $ops = {};
+       $sto->write_prepare($lei);
        $lei->{auth}->op_merge($ops, $self) if $lei->{auth};
        $self->{-wq_nr_workers} = $j // 1; # locked
        (my $op_c, $ops) = $lei->workers_start($self, $j, $ops);
        $lei->{wq1} = $self;
        $lei->{-err_type} = 'non-fatal';
        net_merge_all_done($self) unless $lei->{auth};
-       $op_c->op_wait_event($ops); # calls net_merge_all_done if $lei->{auth}
+       $lei->wait_wq_events($op_c, $ops); # net_merge_all_done if !{auth}
 }
 
 sub _complete_export_kw {