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   223255 use warnings;
  8         22  
  8         292  
4 8     8   85 use strict;
  8         17  
  8         302  
5              
6 8     8   44 use vars qw($VERSION $AUTOLOAD);
  8         18  
  8         952  
7             $VERSION = '0.12';
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   45 use File::Basename;
  8         12  
  8         1055  
62 8     8   48 use File::Path;
  8         22  
  8         590  
63 8     8   12281 use File::Temp qw(tempfile);
  8         267725  
  8         1318  
64 8     8   8523 use Time::Piece;
  8         123032  
  8         58  
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 2715 my ($self, %hash) = @_;
111              
112             # create an attributes hash
113 5   100     158 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         31 my @xheaders = grep /^X-/, keys %hash;
125 5         15 foreach my $xhdr (@xheaders) { $atts->{$xhdr} = $hash{$xhdr} }
  1         5  
126              
127             # create the object
128 5         13 bless $atts, $self;
129 5         21 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   3940 no strict 'refs';
  8         22  
  8         4914  
156 17     17   1802 my $name = $AUTOLOAD;
157 17         88 $name =~ s/^.*:://;
158 17 100       61 die "Unknown sub $AUTOLOAD\n" unless($autosubs{$name});
159            
160 16 100   30   88 *$name = sub { @_==2 ? $_[0]->{$name} = $_[1] : $_[0]->{$name}; };
  30         221  
161 16         50 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 1628 my ($self,$xheader,$value) = @_;
173 6 100       33 return unless($xheader =~ /^X-/);
174 5 100       36 $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 1038 my ($self) = @_;
187              
188             # create output directory if necessary
189 9 100       394 if((my $path = dirname($self->{template})) ne '.') {
190 7         12 eval { mkpath($path) };
  7         447  
191 7 50       24 return if($@);
192             }
193              
194             # we need a basic message fields
195 9 100 100     179 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         36 my $t = localtime;
202 5         772 my $date = $t->strftime();
203              
204             # Build the message
205 5         551 my $msg = "From: $self->{From}\n" .
206             "To: $self->{To}\n" .
207             "Subject: $self->{Subject}\n".
208             "Date: $date\n";
209 5 100       42 $msg .= "Cc: $self->{Cc}\n" if($self->{Cc});
210 5 100       29 $msg .= "Bcc: $self->{Bcc}\n" if($self->{Bcc});
211              
212             # store the x-headers
213 5         39 my @xheaders = grep /^X-/, keys %$self;
214 5         21 foreach my $xhdr (@xheaders) { $msg .= "$xhdr: $self->{$xhdr}\n"; }
  3         17  
215              
216 5         15 $msg .= "\n$self->{Body}\n";
217              
218 5         39 my ($template,$suffix) = ($self->{template} =~ /(.*)(\.\w+)$/);
219 5         31 my ($fh, $filename) = tempfile( $template, SUFFIX => $suffix, UNLINK => 0 );
220 5         2277 print $fh $msg;
221 5         11 undef $fh;
222              
223 5         311 return $filename;
224             }
225              
226             1;
227              
228             __END__