File Coverage

blib/lib/App/winmaildat2tar.pm
Criterion Covered Total %
statement 58 101 57.4
branch 0 20 0.0
condition 0 9 0.0
subroutine 21 31 67.7
pod 0 6 0.0
total 79 167 47.3


line stmt bran cond sub pod time code
1             package App::winmaildat2tar;
2              
3             our $VERSION = "0.9902";
4              
5 1     1   617 use v5.14;
  1         3  
6 1     1   4 use warnings;
  1         2  
  1         20  
7 1     1   533 use Pod::Usage;
  1         40900  
  1         115  
8 1     1   423 use Getopt::EX::Long qw(:DEFAULT Configure ExConfigure);
  1         36303  
  1         208  
9             ExConfigure BASECLASS => [ __PACKAGE__, "Getopt::EX" ];
10             Configure "bundling";
11              
12             my $default_format = $0 =~ /2(\w+)$/ ? $1 : 'tar';
13              
14 1     1   427 use Getopt::EX::Hashed; {
  1         5628  
  1         5  
15             has format => 'f =s' , is => 'ro', default => $default_format;
16             has verbose => 'v ' , is => 'ro';
17              
18             has help => 'h',
19             action => sub { pod2usage -verbose => 99, -sections => [ qw(SYNOPSIS VERSION) ] };
20             has version => ' ',
21             action => sub { say $VERSION; exit };
22             }
23 1     1   147 no Getopt::EX::Hashed;
  1         4  
  1         13  
24              
25             sub run {
26 0     0 0   (my $app, local @ARGV) = splice @_;
27 0 0         $app->getopt or pod2usage();
28              
29 0           my $archive;
30              
31 0 0         @ARGV or usage();
32 0           for my $file (@ARGV) {
33 1     1   573 use Convert::TNEF;
  1         25177  
  1         205  
34 0 0         my $tnef = Convert::TNEF->read_in($file, { output_to_core => 'ALL' })
35             or die $Convert::TNEF::errstr;
36 0 0         my @attachments = $tnef->attachments or do {
37 0           warn "$file: no attachment data\n";
38 0           next;
39             };
40 0           for my $ent (@attachments) {
41 0   0       my $name = $ent->longname // $ent->name // unknown();
      0        
42 0 0         warn "$name\n" if $app->verbose;
43 0   0       ($archive //= App::winmaildat2tar::Archive->new($app->format))
44             ->add($name, $ent->data);
45             }
46             }
47              
48 0 0         print $archive->write if $archive;
49              
50 0           exit;
51             }
52              
53             sub unknown {
54 0     0 0   my $seq = (state $_seq)++;
55 0 0         sprintf "unknown%s.dat", $seq ? "_$seq" : "";
56             }
57              
58             1;
59              
60             ######################################################################
61              
62             package App::winmaildat2tar::Archive {
63 1     1   10 use v5.14;
  1         6  
64 1     1   5 use warnings;
  1         2  
  1         37  
65 1     1   6 use Data::Dumper;
  1         2  
  1         47  
66              
67 1     1   494 use Moo; {
  1         9445  
  1         8  
68             has format => ( is => 'ro', required => 1 );
69             has archive => ( is => 'rw' );
70             around BUILDARGS => sub {
71             my ($orig, $class, $format) = @_;
72             $format =~ s/^([a-z\d])([a-z\d]*)$/\u$1\L$2/i
73             or die "$format: invalid format.\n";
74             $class->$orig(format => $format);
75             };
76             sub BUILD {
77 0     0 0   my($obj, $args) = @_;
78 0           my $class = ref $obj;
79 0           my $format = $obj->format;
80 0           my $subclass = "$class\::$format";
81 0           bless $obj, $subclass;
82 0 0         $obj->can('newarchive') or die "$format: unknown format.\n";
83 0 0         $obj->newarchive or die;
84             }
85 1     1   1478 } no Moo;
  1         9  
  1         6  
86              
87             sub newarchive {
88 0     0 0   my $obj = shift;
89 0           $obj->archive($obj->module->new);
90             }
91             sub module {
92 0     0 0   sprintf "Archive::%s", shift->format;
93             }
94             sub write {
95 0     0 0   shift->archive->write;
96             }
97             }
98              
99             package App::winmaildat2tar::Archive::Tar {
100 1     1   298 use v5.14;
  1         3  
101 1     1   5 use warnings;
  1         2  
  1         32  
102 1     1   630 use Archive::Tar;
  1         73050  
  1         109  
103             our @ISA = qw(App::winmaildat2tar::Archive);
104             sub add {
105 0     0     my $obj = shift;
106 0           my($name, $data) = @_;
107 0           my $option = { uname => 'nobody', gname => 'nogroup' };
108 0           $obj->archive->add_data($name, $data, $option);
109             }
110             }
111              
112             package App::winmaildat2tar::Archive::Ar {
113 1     1   22 use v5.14;
  1         9  
114 1     1   4 use warnings;
  1         2  
  1         23  
115 1     1   1318 use Archive::Ar;
  1         5064  
  1         87  
116             our @ISA = qw(App::winmaildat2tar::Archive);
117             sub add {
118 0     0     my $obj = shift;
119 0           my($name, $data) = @_;
120 0           $obj->archive->add_data($name, $data);
121             }
122             }
123              
124             package App::winmaildat2tar::Archive::Zip {
125 1     1   10 use v5.14;
  1         3  
126 1     1   4 use warnings;
  1         1  
  1         22  
127 1     1   567 use Archive::Zip;
  1         35342  
  1         174  
128             our @ISA = qw(App::winmaildat2tar::Archive);
129             sub add {
130 0     0     my $obj = shift;
131 0           my($name, $data) = @_;
132 0           $obj->archive->addString($data, $name);
133             }
134             sub write {
135 0     0     my $obj = shift;
136 0 0         open my $fh, ">", \my $data or die "open: $!";
137 0           $obj->archive->writeToFileHandle($fh);
138 0           close $fh;
139 0           $data;
140             }
141             }
142              
143             1;
144              
145             __END__