File Coverage

blib/lib/Email/Outlook/Message/Attachment.pm
Criterion Covered Total %
statement 34 65 52.3
branch 2 10 20.0
condition 7 12 58.3
subroutine 10 11 90.9
pod 2 2 100.0
total 55 100 55.0


line stmt bran cond sub pod time code
1             package Email::Outlook::Message::Attachment;
2             =head1 NAME
3              
4             Email::Outlook::Message::Attachment - Handle attachment data in .msg files
5              
6             =head1 DESCRIPTION
7              
8             This is an internal module of Email::Outlook::Message. It is a subclass of
9             Email::Outlook::Message::Base.
10              
11             =head1 METHODS
12              
13             =over 8
14              
15             =item B
16              
17             Create a new attachment object, using $pps as data source. Overrides the base
18             method by setting some default values.
19              
20             =item B
21              
22             Convert the attachment to an Email::MIME object.
23              
24             =back
25              
26             =head1 AUTHOR
27              
28             Matijs van Zuijlen, C
29              
30             =head1 COPYRIGHT AND LICENSE
31              
32             Copyright 2002--2020 by Matijs van Zuijlen
33              
34             This module is free software; you can redistribute it and/or modify
35             it under the same terms as Perl itself.
36              
37             =cut
38 8     8   58 use strict;
  8         20  
  8         255  
39 8     8   50 use warnings;
  8         17  
  8         224  
40 8     8   45 use Carp;
  8         18  
  8         455  
41 8     8   49 use vars qw($VERSION);
  8         14  
  8         464  
42             $VERSION = "0.920";
43 8     8   78 use Email::MIME::ContentType;
  8         28  
  8         581  
44 8     8   54 use base 'Email::Outlook::Message::Base';
  8         21  
  8         6755  
45              
46             our $MAP_ATTACHMENT_FILE = {
47             '3701' => "DATA", # Data
48             '3704' => "SHORTNAME", # Short file name
49             '3707' => "LONGNAME", # Long file name
50             '370E' => "MIMETYPE", # mime type
51             '3712' => "CONTENTID", # content-id
52             '3716' => "DISPOSITION", # disposition
53             };
54              
55             sub new {
56 2     2 1 9 my ($class, $pps, $verbosity) = @_;
57 2         17 my $self = $class->SUPER::new($pps, $verbosity);
58 2         8 bless $self, $class;
59 2   50     8 $self->{MIMETYPE} ||= 'application/octet-stream';
60 2   50     16 $self->{ENCODING} ||= 'base64';
61 2   50     47 $self->{DISPOSITION} ||= 'attachment';
62 2 100       9 if ($self->{MIMETYPE} eq 'multipart/signed') {
63 1         3 $self->{ENCODING} = '8bit';
64             }
65 2         31 return $self;
66             }
67              
68             sub to_email_mime {
69 2     2 1 6 my $self = shift;
70              
71 2         8 my $mt = parse_content_type($self->{MIMETYPE});
72             my $m = Email::MIME->create(
73             attributes => {
74             content_type => "$mt->{discrete}/$mt->{composite}",
75 2         36 %{$mt->{attributes}},
76             encoding => $self->{ENCODING},
77             filename => $self->{LONGNAME} || $self->{SHORTNAME},
78             name => $self->{LONGNAME} || $self->{LONGNAME},
79             disposition => $self->{DISPOSITION},
80             },
81             header => [ 'Content-ID' => $self->{CONTENTID} ],
82 2   66     119 body => $self->{DATA});
      66        
83 2         3809 return $m
84             }
85              
86             sub _property_map {
87 2     2   12 return $MAP_ATTACHMENT_FILE;
88             }
89              
90             sub _process_subdirectory {
91 0     0   0 my ($self, $pps) = @_;
92 0         0 my $name = $self->_get_pps_name($pps);
93 0         0 my ($property, $encoding) = $self->_parse_item_name($name);
94              
95 0 0       0 if ($property eq '3701') { # Nested msg file
96 0         0 my $is_msg = 1;
97 0         0 foreach my $child (@{$pps->{Child}}) {
  0         0  
98 0 0       0 unless ($self->_get_pps_name($child) =~ / ^ ( __recip | __attach
99             | __substg1 | __nameid | __properties ) /x
100             ) {
101 0         0 $is_msg = 0;
102 0         0 last;
103             }
104             }
105 0 0       0 if ($is_msg) {
106 0         0 my $msgp = Email::Outlook::Message->_empty_new();
107 0         0 $msgp->_set_verbosity($self->{VERBOSE});
108 0         0 $msgp->_process_pps($pps);
109              
110 0         0 $self->{DATA} = $msgp->to_email_mime->as_string;
111 0         0 $self->{MIMETYPE} = 'message/rfc822';
112 0         0 $self->{ENCODING} = '8bit';
113             } else {
114 0         0 foreach my $child (@{$pps->{Child}}) {
  0         0  
115 0 0       0 if (eval { $child->isa('OLE::Storage_Lite::PPS::File')}) {
  0         0  
116 0         0 foreach my $prop ("Time1st", "Time2nd") {
117 0         0 $child->{$prop} = undef;
118             }
119             }
120             }
121             my $nPps = OLE::Storage_Lite::PPS::Root->new(
122 0         0 $pps->{Time1st}, $pps->{Time2nd}, $pps->{Child});
123 0         0 my $data;
124 0         0 my $io = IO::String->new($data);
125 0         0 binmode($io);
126 0         0 $nPps->save($io, 1);
127 0         0 $self->{DATA} = $data;
128             }
129             } else {
130 0         0 $self->_warn_about_unknown_directory($pps);
131             }
132 0         0 return;
133             }
134              
135 2     2   8 sub _property_stream_header_length { return 8; }
136              
137             1;