File Coverage

blib/lib/Mail/File.pm
Criterion Covered Total %
statement 60 61 98.3
branch 17 18 94.4
condition 23 23 100.0
subroutine 13 14 92.8
pod 3 3 100.0
total 116 119 97.4


line stmt bran cond sub pod time code
1             package Mail::File;
2              
3 8     8   140270 use warnings;
  8         16  
  8         318  
4 8     8   42 use strict;
  8         13  
  8         302  
5              
6 8     8   36 use vars qw($VERSION $AUTOLOAD);
  8         15  
  8         609  
7             $VERSION = '0.13';
8              
9             #----------------------------------------------------------------------------
10              
11             =head1 NAME
12              
13             Mail::File - mail module which writes to a flat file.
14              
15             =head1 SYNOPSIS
16              
17             use Mail::File;
18              
19             my $mail = Mail::File->new(template => 'mailXXXX.tmp');
20             $mail->From('me@example.com');
21             $mail->To('you@example.com');
22             $mail->Cc('Them ');
23             $mail->Bcc('Us ; anybody@example.com');
24             $mail->Subject('Blah Blah Blah');
25             $mail->Body('Yadda Yadda Yadda');
26             $mail->XHeader('X-Header' => 'Blah Blah Blah');
27             $mail->send;
28              
29             # Or use a hash
30             my %hash = (
31             From => 'me@example.com',
32             To => 'you@example.com',
33             Cc => 'Them ',
34             Bcc => 'Us , anybody@example.com',
35             Subject => 'Blah Blah Blah',
36             Body => 'Yadda Yadda Yadda',
37             'X-Header' => 'Blah Blah Blah',
38             template => 'mailXXXX.tmp'
39             );
40              
41             my $mail = Mail::File->new(%hash);
42             $mail->send;
43              
44             =head1 DESCRIPTION
45              
46             This module was written to overcome the problem of sending mail messages,
47             where there is no mail application available.
48              
49             The aim of the module is to write messages to a text file, that will format
50             the contents to include all the key elements of the message, such that the
51             file can be transported to another machine, which is then capable of sending
52             mail messages.
53              
54             Notes that the filename template defaults to 'mail-XXXXXX.eml'.
55              
56             =cut
57              
58             #----------------------------------------------------------------------------
59             # Library Modules
60              
61 8     8   42 use File::Basename;
  8         10  
  8         770  
62 8     8   42 use File::Path;
  8         14  
  8         460  
63 8     8   6213 use File::Temp qw(tempfile);
  8         150377  
  8         548  
64 8     8   4485 use Time::Piece;
  8         77753  
  8         45  
65              
66             #----------------------------------------------------------------------------
67             # Variables
68              
69             my %autosubs = map {$_ => 1} qw( From To Cc Bcc Subject Body );
70              
71             #----------------------------------------------------------------------------
72             # Interface Functions
73              
74             =head1 METHODS
75              
76             =over 4
77              
78             =item new()
79              
80             Create a new mailer object. Returns the object on success or undef on
81             failure.
82              
83             All the following can be passed as part of an anonymous hash:
84              
85             From
86             To
87             Cc
88             Bcc
89             Subject
90             Body
91             template
92              
93             The template entry is optional, and is only supplied when you call the
94             constructor. The format of the string to template follows the format as
95             for File::Temp. However, a suffix is automatically extracted. An example
96             template would be:
97              
98             mail-XXXX.tmp
99              
100             Where the temnplate to File::Temp would be 'mail-XXXX' and the suffix
101             would be '.tmp'.
102              
103             The default template, if none is supplied is:
104            
105             mail-XXXXXX.eml
106              
107             =cut
108              
109             sub new {
110 5     5 1 1868 my ($self, %hash) = @_;
111              
112             # create an attributes hash
113 5   100     124 my $atts = {
      100        
      100        
      100        
      100        
      100        
      100        
114             'From' => $hash{From} || '',
115             'To' => $hash{To} || '',
116             'Cc' => $hash{Cc} || '',
117             'Bcc' => $hash{Bcc} || '',
118             'Subject' => $hash{Subject} || '',
119             'Body' => $hash{Body} || '',
120             'template' => $hash{template} || 'mail-XXXXXX.eml',
121             };
122              
123             # store the x-headers
124 5         26 my @xheaders = grep /^X-/, keys %hash;
125 5         12 foreach my $xhdr (@xheaders) { $atts->{$xhdr} = $hash{$xhdr} }
  1         3  
126              
127             # create the object
128 5         11 bless $atts, $self;
129 5         15 return $atts;
130             }
131              
132 0     0   0 sub DESTROY {}
133              
134             #----------------------------------------------------------------------------
135             # The Get & Set Methods Interface Subs
136              
137             =item Accessor Methods
138              
139             The following accessor methods are available:
140              
141             From
142             To
143             Cc
144             Bcc
145             Subject
146             Body
147              
148             All functions can be called to return the current value of the associated
149             object variable, or be called with a parameter to set a new value for the
150             object variable.
151              
152             =cut
153              
154             sub AUTOLOAD {
155 8     8   2024 no strict 'refs';
  8         28  
  8         4039  
156 17     17   1362 my $name = $AUTOLOAD;
157 17         78 $name =~ s/^.*:://;
158 17 100       48 die "Unknown sub $AUTOLOAD\n" unless($autosubs{$name});
159            
160 16 100   30   71 *$name = sub { @_==2 ? $_[0]->{$name} = $_[1] : $_[0]->{$name}; };
  30         175  
161 16         35 goto &$name;
162             }
163              
164             =item XHeader($xheader,$value)
165              
166             Adds a header in the style of 'X-Header' to the headers of the message.
167             Returns undef if header cannot be added.
168              
169             =cut
170              
171             sub XHeader {
172 6     6 1 1182 my ($self,$xheader,$value) = @_;
173 6 100       27 return unless($xheader =~ /^X-/);
174 5 100       28 $value ? $self->{$xheader} = $value : $self->{$xheader};
175             }
176              
177             =item send()
178              
179             Sends the message. Returns the filename on success, 0 on failure.
180              
181             Really just writes to a file.
182              
183             =cut
184              
185             sub send {
186 9     9 1 770 my ($self) = @_;
187              
188             # create output directory if necessary
189 9 100       313 if((my $path = dirname($self->{template})) ne '.') {
190 7         11 eval { mkpath($path) };
  7         356  
191 7 50       19 return if($@);
192             }
193              
194             # we need a basic message fields
195 9 100 100     95 return unless( $self->{From} &&
      100        
      100        
196             $self->{To} &&
197             $self->{Subject} &&
198             $self->{Body});
199              
200             # use the date we write the file
201 5         23 my $t = localtime;
202 5         347 my $date = $t->strftime();
203              
204             # Build the message
205 5         455 my $msg = "From: $self->{From}\n" .
206             "To: $self->{To}\n" .
207             "Subject: $self->{Subject}\n".
208             "Date: $date\n";
209 5 100       32 $msg .= "Cc: $self->{Cc}\n" if($self->{Cc});
210 5 100       15 $msg .= "Bcc: $self->{Bcc}\n" if($self->{Bcc});
211              
212             # store the x-headers
213 5         38 my @xheaders = grep /^X-/, keys %$self;
214 5         12 foreach my $xhdr (@xheaders) { $msg .= "$xhdr: $self->{$xhdr}\n"; }
  3         12  
215              
216 5         14 $msg .= "\n$self->{Body}\n";
217              
218 5         28 my ($template,$suffix) = ($self->{template} =~ /(.*)(\.\w+)$/);
219 5         27 my ($fh, $filename) = tempfile( $template, SUFFIX => $suffix, UNLINK => 0 );
220 5         1571 print $fh $msg;
221 5         10 undef $fh;
222              
223 5         188 return $filename;
224             }
225              
226             1;
227              
228             __END__