diff options
author | Eric Wong <e@80x24.org> | 2021-05-04 09:49:12 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2021-05-04 23:08:01 +0000 |
commit | 40f3f2a2c805fc37c7ed35a60948856bd962b493 (patch) | |
tree | 0fe4d70c7a50a0122f92d48b832ada31a3b5a0bf /lib/PublicInbox/LeiBlob.pm | |
parent | 4481b372ba150c669b2fefe2d6ec5dccb5da1d40 (diff) | |
download | public-inbox-40f3f2a2c805fc37c7ed35a60948856bd962b493.tar.gz |
Since completely purging blobs from git is slow, users may wish to index messages in Maildirs (and eventually other local storage) without storing data in git. Much code from LeiImport and LeiInput is reused, and a new dummy FakeImport class supplies a non-storing $im->add and minimize changes to LeiStore. The tricky part of this command is to support "lei import" after a message has gone through "lei index". Relying on $smsg->{bytes} == 0 (as we do for external-only vmd storage) does not work here, since it would break searching for "z:" byte-ranges when not using externals. This eventually required PublicInbox::Import::add to use a SharedKV to keep track of imported blobs and prevent duplication.
Diffstat (limited to 'lib/PublicInbox/LeiBlob.pm')
-rw-r--r-- | lib/PublicInbox/LeiBlob.pm | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/lib/PublicInbox/LeiBlob.pm b/lib/PublicInbox/LeiBlob.pm index 710430a2..8de86565 100644 --- a/lib/PublicInbox/LeiBlob.pm +++ b/lib/PublicInbox/LeiBlob.pm @@ -87,6 +87,16 @@ sub cat_attach_i { # Eml->each_part callback $lei->out($part->body); } +sub extract_attach ($$$) { + my ($lei, $blob, $bref) = @_; + my $eml = PublicInbox::Eml->new($bref); + $eml->each_part(\&cat_attach_i, $lei, 1); + my $idx = delete $lei->{-attach_idx}; + defined($idx) and return $lei->fail(<<EOM); +E: attachment $idx not found in $blob +EOM +} + sub lei_blob { my ($lei, $blob) = @_; $lei->start_pager if -t $lei->{1}; @@ -106,7 +116,7 @@ sub lei_blob { } my $rdr = {}; if ($opt->{mail}) { - $rdr->{2} = $lei->{2}; + open $rdr->{2}, '+>', undef or die "open: $!"; } else { open $rdr->{2}, '>', '/dev/null' or die "open: $!"; } @@ -115,21 +125,25 @@ sub lei_blob { if (defined $lei->{-attach_idx}) { my $fh = popen_rd($cmd, $lei->{env}, $rdr); require PublicInbox::Eml; - my $str = do { local $/; <$fh> }; - if (close $fh) { - my $eml = PublicInbox::Eml->new(\$str); - $eml->each_part(\&cat_attach_i, $lei, 1); - my $idx = delete $lei->{-attach_idx}; - defined($idx) and return $lei->fail(<<EOM); -E: attachment $idx not found in $blob -EOM - } + my $buf = do { local $/; <$fh> }; + return extract_attach($lei, $blob, \$buf) if close($fh); } else { $rdr->{1} = $lei->{1}; waitpid(spawn($cmd, $lei->{env}, $rdr), 0); } - return if $? == 0; - return $lei->child_error($?) if $opt->{mail}; + my $ce = $?; + return if $ce == 0; + my $sto = $lei->_lei_store; + my $lms = $sto ? $sto->search->lms : undef; + if (my $bref = $lms ? $lms->local_blob($blob, 1) : undef) { + defined($lei->{-attach_idx}) and + return extract_attach($lei, $blob, $bref); + return $lei->out($$bref); + } elsif ($opt->{mail}) { + my $eh = $rdr->{2}; + seek($eh, 0, 0); + return $lei->child_error($ce, do { local $/; <$eh> }); + } # else: fall through to solver below } # maybe it's a non-email (code) blob from a coderepo |