]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/Mbox.pm
support dumping thread as an mbox
[public-inbox.git] / lib / PublicInbox / Mbox.pm
1 # Copyright (C) 2015, all contributors <meta@public-inbox.org>
2 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
3 # Streaming interface for formatting messages as an mbox
4 package PublicInbox::Mbox;
5 use strict;
6 use warnings;
7 use PublicInbox::MID qw/mid_clean mid_compressed mid2path/;
8 use Fcntl qw(SEEK_SET);
9
10 sub thread_mbox {
11         my ($ctx, $srch) = @_;
12         my $mid = mid_compressed($ctx->{mid});
13         my $res = $srch->get_thread($mid);
14         my $msgs = delete $res->{msgs};
15         require PublicInbox::GitCatFile;
16         require Email::Simple;
17         my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
18
19         sub {
20                 my ($res) = @_; # Plack callback
21                 my $w = $res->([200, [ 'Content-Type' => 'text/plain' ] ]);
22                 while (defined(my $smsg = shift @$msgs)) {
23                         my $msg = eval {
24                                 my $path = 'HEAD:' . mid2path($smsg->mid);
25                                 Email::Simple->new($git->cat_file($path));
26                         };
27                         emit($w, $msg) if $msg;
28                 }
29         }
30 }
31
32 sub emit {
33         my ($fh, $simple) = @_; # Email::Simple object
34
35         # drop potentially confusing headers, ssoma already should've dropped
36         # Lines and Content-Length
37         foreach my $d (qw(Lines Content-Length Status)) {
38                 $simple->header_set($d);
39         }
40
41         my $buf = $simple->header_obj->as_string;
42         unless ($buf =~ /\AFrom /) {
43                 $fh->write("From a\@a Thu Jan  1 00:00:00 1970\n");
44         }
45         $fh->write($buf .= $simple->crlf);
46
47         $buf = $simple->body;
48         $simple->body_set('');
49         $buf =~ s/^(From )/>$1/gm;
50         $buf .= "\n" unless $buf =~ /\n\z/s;
51
52         $fh->write($buf);
53 }
54
55 1;