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 9     9   62 use strict;
  9         18  
  9         274  
39 9     9   49 use warnings;
  9         19  
  9         244  
40 9     9   41 use Carp;
  9         20  
  9         548  
41 9     9   48 use vars qw($VERSION);
  9         19  
  9         425  
42             $VERSION = "0.921";
43 9     9   61 use Email::MIME::ContentType;
  9         26  
  9         641  
44 9     9   58 use base 'Email::Outlook::Message::Base';
  9         17  
  9         6782  
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 4     4 1 13 my ($class, $pps, $verbosity) = @_;
57 4         30 my $self = $class->SUPER::new($pps, $verbosity);
58 4         26 bless $self, $class;
59 4   50     16 $self->{MIMETYPE} ||= 'application/octet-stream';
60 4   50     26 $self->{ENCODING} ||= 'base64';
61 4   50     21 $self->{DISPOSITION} ||= 'attachment';
62 4 100       12 if ($self->{MIMETYPE} eq 'multipart/signed') {
63 2         6 $self->{ENCODING} = '8bit';
64             }
65 4         12 return $self;
66             }
67              
68             sub to_email_mime {
69 4     4 1 9 my $self = shift;
70              
71 4         15 my $mt = parse_content_type($self->{MIMETYPE});
72             my $m = Email::MIME->create(
73             attributes => {
74             content_type => "$mt->{discrete}/$mt->{composite}",
75 4         79 %{$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 4   66     216 body => $self->{DATA});
      66        
83 4         7050 return $m
84             }
85              
86             sub _property_map {
87 4     4   35 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 4     4   12 sub _property_stream_header_length { return 8; }
136              
137             1;