]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LeiInput.pm
lei_input: support compressed mboxes
[public-inbox.git] / lib / PublicInbox / LeiInput.pm
index d916249a2e07d1f982078dc7f7af0c8bcd2159ff..505b73ff6df0a8c27ef8c12ed581252e90f93b6d 100644 (file)
@@ -14,9 +14,9 @@ sub check_input_format ($;$) {
                my $err = $files ? "regular file(s):\n@$files" : '--stdin';
                return $lei->fail("--$opt_key unset for $err");
        }
+       return 1 if $fmt eq 'eml';
        require PublicInbox::MboxLock if $files;
        require PublicInbox::MboxReader;
-       return 1 if $fmt eq 'eml';
        # XXX: should this handle {gz,bz2,xz}? that's currently in LeiToMail
        PublicInbox::MboxReader->reads($fmt) or
                return $lei->fail("--$opt_key=$fmt unrecognized");
@@ -28,7 +28,6 @@ sub check_input_format ($;$) {
 sub input_fh {
        my ($self, $ifmt, $fh, $name, @args) = @_;
        if ($ifmt eq 'eml') {
-               require PublicInbox::Eml;
                my $buf = do { local $/; <$fh> } //
                        return $self->{lei}->child_error(1 << 8, <<"");
 error reading $name: $!
@@ -46,12 +45,6 @@ error reading $name: $!
        }
 }
 
-sub input_stdin {
-       my ($self) = @_;
-       my $in = delete $self->{0} or return;
-       $self->input_fh($self->{lei}->{opt}->{'in-format'}, $in, '<stdin>');
-}
-
 sub input_path_url {
        my ($self, $input, @args) = @_;
        my $lei = $self->{lei};
@@ -66,14 +59,29 @@ sub input_path_url {
                                        $self, @args);
                return;
        }
-       $input =~ s!\A([a-z0-9]+):!!i and $ifmt = lc($1);
+       if ($input =~ s!\A([a-z0-9]+):!!i) {
+               $ifmt = lc($1);
+       } elsif ($input =~ /\.(?:patch|eml)\z/i) {
+               $ifmt = 'eml';
+       }
        my $devfd = $lei->path_to_fd($input) // return;
        if ($devfd >= 0) {
                $self->input_fh($ifmt, $lei->{$devfd}, $input, @args);
-       } elsif (-f $input) {
-               my $m = $lei->{opt}->{'lock'} // ($ifmt eq 'eml' ? ['none'] :
-                               PublicInbox::MboxLock->defaults);
+       } elsif (-f $input && $ifmt eq 'eml') {
+               open my $fh, '<', $input or
+                                       return $lei->fail("open($input): $!");
+               $self->input_fh($ifmt, $fh, $input, @args);
+       } elsif (-f _) {
+               my $m = $lei->{opt}->{'lock'} //
+                       PublicInbox::MboxLock->defaults;
                my $mbl = PublicInbox::MboxLock->acq($input, 0, $m);
+               my $zsfx = PublicInbox::MboxReader::zsfx($input);
+               if ($zsfx) {
+                       my $in = delete $mbl->{fh};
+                       $mbl->{fh} =
+                            PublicInbox::MboxReader::zsfxcat($in, $zsfx, $lei);
+               }
+               local $PublicInbox::DS::in_loop = 0 if $zsfx; # dwaitpid
                $self->input_fh($ifmt, $mbl->{fh}, $input, @args);
        } elsif (-d _ && (-d "$input/cur" || -d "$input/new")) {
                return $lei->fail(<<EOM) if $ifmt && $ifmt ne 'maildir';
@@ -94,10 +102,9 @@ sub prepare_inputs { # returns undef on error
                @$inputs and return
                        $lei->fail("--stdin and @$inputs do not mix");
                check_input_format($lei) or return;
-               $self->{0} = $lei->{0};
+               push @$inputs, '/dev/stdin';
        }
        my $net = $lei->{net}; # NetWriter may be created by l2m
-       my $fmt = $lei->{opt}->{'in-format'};
        my (@f, @d);
        # e.g. Maildir:/home/user/Mail/ or imaps://example.com/INBOX
        for my $input (@$inputs) {
@@ -126,6 +133,11 @@ sub prepare_inputs { # returns undef on error
                        } else {
                                return $lei->fail("Unable to handle $input");
                        }
+               } elsif ($input =~ /\.(eml|patch)\z/i && -f $input) {
+                       lc($in_fmt//'eml') eq 'eml' or return $lei->fail(<<"");
+$input is `eml', not --in-format=$in_fmt
+
+                       require PublicInbox::Eml;
                } else {
                        my $devfd = $lei->path_to_fd($input) // return;
                        if ($devfd >= 0 || -f $input || -p _) {