File Coverage

blib/lib/Emailesque.pm
Criterion Covered Total %
statement 73 375 19.4
branch 20 324 6.1
condition 9 45 20.0
subroutine 13 145 8.9
pod 133 136 97.7
total 248 1025 24.2


line stmt bran cond sub pod time code
1             # ABSTRACT: Lightweight To-The-Point Email
2             package Emailesque;
3              
4 2     2   20964 use Carp;
  2         4  
  2         160  
5 2     2   1556 use File::Slurp;
  2         27747  
  2         124  
6 2     2   1313 use Email::AddressParser;
  2         1808  
  2         88  
7 2     2   1423 use Email::Sender::Transport::Sendmail;
  2         209440  
  2         66  
8 2     2   1520 use Email::Sender::Transport::SMTP;
  2         105649  
  2         70  
9 2     2   1692 use Email::Stuffer;
  2         94517  
  2         70  
10 2     2   1532 use Hash::Merge::Simple;
  2         851  
  2         92  
11              
12 2     2   10 use Exporter 'import';
  2         4  
  2         126  
13             our @EXPORT_OK = qw(email);
14              
15 2     2   10 use Moo;
  2         3  
  2         14  
16              
17             our $VERSION = '1.26'; # VERSION
18              
19             my %headers = map {
20             my $name = lc $_;
21             $name =~ s/\W+/_/g;
22             $name => $_;
23             }
24             my @headers = (
25             my @kheaders = (
26             'Accept-Language',
27             'Alternate-Recipient',
28             'Apparently-To',
29             'Archived-At',
30             'Authentication-Results',
31             'Auto-Submitted',
32             'Autoforwarded',
33             'Autosubmitted',
34             'Bcc',
35             'Cc',
36             'Comments',
37             'Content-Identifier',
38             'Content-Return',
39             'Conversion-With-Loss',
40             'Conversion',
41             'DKIM-Signature',
42             'DL-Expansion-History',
43             'Date',
44             'Deferred-Delivery',
45             'Delivery-Date',
46             'Discarded-X400-IPMS-Extensions',
47             'Discarded-X400-MTS-Extensions',
48             'Disclose-Recipients',
49             'Disposition-Notification-Options',
50             'Disposition-Notification-To',
51             'Downgraded-Bcc',
52             'Downgraded-Cc',
53             'Downgraded-Disposition-Notification-To',
54             'Downgraded-Final-Recipient',
55             'Downgraded-From',
56             'Downgraded-In-Reply-To',
57             'Downgraded-Mail-From',
58             'Downgraded-Message-Id',
59             'Downgraded-Original-Recipient',
60             'Downgraded-Rcpt-To',
61             'Downgraded-References',
62             'Downgraded-Reply-To',
63             'Downgraded-Resent-Bcc',
64             'Downgraded-Resent-Cc',
65             'Downgraded-Resent-From',
66             'Downgraded-Resent-Reply-To',
67             'Downgraded-Resent-Sender',
68             'Downgraded-Resent-To',
69             'Downgraded-Return-Path',
70             'Downgraded-Sender',
71             'Downgraded-To',
72             'EDIINT-Features',
73             'Encoding',
74             'Encrypted',
75             'Errors-To',
76             'Expires',
77             'Expiry-Date',
78             'From',
79             'Generate-Delivery-Report',
80             'Importance',
81             'In-Reply-To',
82             'Incomplete-Copy',
83             'Jabber-ID',
84             'Keywords',
85             'Language',
86             'Latest-Delivery-Time',
87             'List-Archive',
88             'List-Help',
89             'List-ID',
90             'List-Owner',
91             'List-Post',
92             'List-Subscribe',
93             'List-Unsubscribe',
94             'MMHS-Acp127-Message-Identifier',
95             'MMHS-Codress-Message-Indicator',
96             'MMHS-Copy-Precedence',
97             'MMHS-Exempted-Address',
98             'MMHS-Extended-Authorisation-Info',
99             'MMHS-Handling-Instructions',
100             'MMHS-Message-Instructions',
101             'MMHS-Message-Type',
102             'MMHS-Originator-PLAD',
103             'MMHS-Originator-Reference',
104             'MMHS-Other-Recipients-Indicator-CC',
105             'MMHS-Other-Recipients-Indicator-To',
106             'MMHS-Primary-Precedence',
107             'MMHS-Subject-Indicator-Codes',
108             'MT-Priority',
109             'Message-Context',
110             'Message-ID',
111             'Message-Type',
112             'Obsoletes',
113             'Original-Encoded-Information-Types',
114             'Original-From',
115             'Original-Message-ID',
116             'Original-Recipient',
117             'Original-Subject',
118             'Originator-Return-Address',
119             'PICS-Label',
120             'Prevent-NonDelivery-Report',
121             'Priority',
122             'Privicon',
123             'Received-SPF',
124             'Received',
125             'References',
126             'Reply-By',
127             'Reply-To',
128             'Require-Recipient-Valid-Since',
129             'Resent-Bcc',
130             'Resent-Cc',
131             'Resent-Date',
132             'Resent-From',
133             'Resent-Message-ID',
134             'Resent-Reply-To',
135             'Resent-Sender',
136             'Resent-To',
137             'Return-Path',
138             'SIO-Label-History',
139             'SIO-Label',
140             'Sender',
141             'Sensitivity',
142             'Solicitation',
143             'Subject',
144             'Supersedes',
145             'To',
146             'VBR-Info',
147             'X-Archived-At',
148             'X400-Content-Identifier',
149             'X400-Content-Return',
150             'X400-Content-Type',
151             'X400-MTS-Identifier',
152             'X400-Originator',
153             'X400-Received',
154             'X400-Recipients',
155             'X400-Trace',
156             ),
157             my @xheaders = (
158             'X-Abuse-Info',
159             'X-Accept-Language',
160             'X-Admin',
161             'X-Article-Creation-Date',
162             'X-Attribution',
163             'X-Authenticated-IP',
164             'X-Authenticated-Sender',
165             'X-Authentication-Warning',
166             'X-Cache',
167             'X-Comments',
168             'X-Complaints-To',
169             'X-Confirm-reading-to',
170             'X-Envelope-From',
171             'X-Envelope-To',
172             'X-Face',
173             'X-Flags',
174             'X-Folder',
175             'X-IMAP',
176             'X-Last-Updated',
177             'X-List-Host',
178             'X-Listserver',
179             'X-Loop',
180             'X-Mailer',
181             'X-Mailer-Info',
182             'X-Mailing-List',
183             'X-MIME-Autoconverted',
184             'X-MimeOLE',
185             'X-MIMETrack',
186             'X-MSMail-Priority',
187             'X-MyDeja-Info',
188             'X-Newsreader',
189             'X-NNTP-Posting-Host',
190             'X-No-Archive',
191             'X-Notice',
192             'X-Orig-Message-ID',
193             'X-Original-Envelope-From',
194             'X-Original-NNTP-Posting-Host',
195             'X-Original-Trace',
196             'X-OriginalArrivalTime',
197             'X-Originating-IP',
198             'X-PMFLAGS',
199             'X-Posted-By',
200             'X-Posting-Agent',
201             'X-Priority',
202             'X-RCPT-TO',
203             'X-Report',
204             'X-Report-Abuse-To',
205             'X-Sender',
206             'X-Server-Date',
207             'X-Trace',
208             'X-URI',
209             'X-URL',
210             'X-X-Sender',
211             ),
212             );
213              
214             around new => sub {
215             my ($orig, $class, @args) = @_;
216             my $data = @args % 2 ? $args[0] : {@args};
217             $data = {} unless ref($data) eq 'HASH';
218             my $self = $class->$orig($data);
219             $self->{$_} //= $data->{$_} for keys %{$data};
220             return $self;
221             };
222              
223             sub email {
224 1 50   1 0 69 unshift @_, __PACKAGE__->new({}) and goto &send;
225             }
226              
227             sub message {
228 0     0 1 0 my ($self, $argument) = @_;
229 0         0 return $self->{message} = $argument;
230             }
231              
232             sub send {
233 3     3 1 6 my ($self, $options, @arguments) = @_;
234 3         11 my $package = $self->prepare_package($options, @arguments);
235 3         13 return $package->send;
236             }
237              
238             sub accept_language {
239 0     0 1 0 my $name = 'Accept-Language';
240 0 0       0 unshift @_, shift, $name and goto &header;
241             }
242              
243             sub alternate_recipient {
244 0     0 1 0 my $name = 'Alternate-Recipient';
245 0 0       0 unshift @_, shift, $name and goto &header;
246             }
247              
248             sub apparently_to {
249 0     0 1 0 my $name = 'Apparently-To';
250 0 0       0 unshift @_, shift, $name and goto &header;
251             }
252              
253             sub archived_at {
254 0     0 1 0 my $name = 'Archived-At';
255 0 0       0 unshift @_, shift, $name and goto &header;
256             }
257              
258             sub authentication_results {
259 0     0 1 0 my $name = 'Authentication-Results';
260 0 0       0 unshift @_, shift, $name and goto &header;
261             }
262              
263             sub auto_submitted {
264 0     0 1 0 my $name = 'Auto-Submitted';
265 0 0       0 unshift @_, shift, $name and goto &header;
266             }
267              
268             sub autoforwarded {
269 0     0 1 0 my $name = 'Autoforwarded';
270 0 0       0 unshift @_, shift, $name and goto &header;
271             }
272              
273             sub autosubmitted {
274 0     0 1 0 my $name = 'Autosubmitted';
275 0 0       0 unshift @_, shift, $name and goto &header;
276             }
277              
278             sub bcc {
279 0     0 1 0 my $name = 'Bcc';
280 0 0       0 unshift @_, shift, $name and goto &header;
281             }
282              
283             sub cc {
284 0     0 1 0 my $name = 'Cc';
285 0 0       0 unshift @_, shift, $name and goto &header;
286             }
287              
288             sub comments {
289 0     0 1 0 my $name = 'Comments';
290 0 0       0 unshift @_, shift, $name and goto &header;
291             }
292              
293             sub content_identifier {
294 0     0 1 0 my $name = 'Content-Identifier';
295 0 0       0 unshift @_, shift, $name and goto &header;
296             }
297              
298             sub content_return {
299 0     0 1 0 my $name = 'Content-Return';
300 0 0       0 unshift @_, shift, $name and goto &header;
301             }
302              
303             sub conversion {
304 0     0 1 0 my $name = 'Conversion';
305 0 0       0 unshift @_, shift, $name and goto &header;
306             }
307              
308             sub conversion_with_loss {
309 0     0 1 0 my $name = 'Conversion-With-Loss';
310 0 0       0 unshift @_, shift, $name and goto &header;
311             }
312              
313             sub dkim_signature {
314 0     0 1 0 my $name = 'DKIM-Signature';
315 0 0       0 unshift @_, shift, $name and goto &header;
316             }
317              
318             sub dl_expansion_history {
319 0     0 1 0 my $name = 'DL-Expansion-History';
320 0 0       0 unshift @_, shift, $name and goto &header;
321             }
322              
323             sub date {
324 0     0 1 0 my $name = 'Date';
325 0 0       0 unshift @_, shift, $name and goto &header;
326             }
327              
328             sub deferred_delivery {
329 0     0 1 0 my $name = 'Deferred-Delivery';
330 0 0       0 unshift @_, shift, $name and goto &header;
331             }
332              
333             sub delivery_date {
334 0     0 1 0 my $name = 'Delivery-Date';
335 0 0       0 unshift @_, shift, $name and goto &header;
336             }
337              
338             sub discarded_x400_ipms_extensions {
339 0     0 1 0 my $name = 'Discarded-X400-IPMS-Extensions';
340 0 0       0 unshift @_, shift, $name and goto &header;
341             }
342              
343             sub discarded_x400_mts_extensions {
344 0     0 1 0 my $name = 'Discarded-X400-MTS-Extensions';
345 0 0       0 unshift @_, shift, $name and goto &header;
346             }
347              
348             sub disclose_recipients {
349 0     0 1 0 my $name = 'Disclose-Recipients';
350 0 0       0 unshift @_, shift, $name and goto &header;
351             }
352              
353             sub disposition_notification_options {
354 0     0 1 0 my $name = 'Disposition-Notification-Options';
355 0 0       0 unshift @_, shift, $name and goto &header;
356             }
357              
358             sub disposition_notification_to {
359 0     0 1 0 my $name = 'Disposition-Notification-To';
360 0 0       0 unshift @_, shift, $name and goto &header;
361             }
362              
363             sub downgraded_bcc {
364 0     0 1 0 my $name = 'Downgraded-Bcc';
365 0 0       0 unshift @_, shift, $name and goto &header;
366             }
367              
368             sub downgraded_cc {
369 0     0 1 0 my $name = 'Downgraded-Cc';
370 0 0       0 unshift @_, shift, $name and goto &header;
371             }
372              
373             sub downgraded_disposition_notification_to {
374 0     0 1 0 my $name = 'Downgraded-Disposition-Notification-To';
375 0 0       0 unshift @_, shift, $name and goto &header;
376             }
377              
378             sub downgraded_final_recipient {
379 0     0 1 0 my $name = 'Downgraded-Final-Recipient';
380 0 0       0 unshift @_, shift, $name and goto &header;
381             }
382              
383             sub downgraded_from {
384 0     0 1 0 my $name = 'Downgraded-From';
385 0 0       0 unshift @_, shift, $name and goto &header;
386             }
387              
388             sub downgraded_in_reply_to {
389 0     0 1 0 my $name = 'Downgraded-In-Reply-To';
390 0 0       0 unshift @_, shift, $name and goto &header;
391             }
392              
393             sub downgraded_mail_from {
394 0     0 1 0 my $name = 'Downgraded-Mail-From';
395 0 0       0 unshift @_, shift, $name and goto &header;
396             }
397              
398             sub downgraded_message_id {
399 0     0 1 0 my $name = 'Downgraded-Message-Id';
400 0 0       0 unshift @_, shift, $name and goto &header;
401             }
402              
403             sub downgraded_original_recipient {
404 0     0 1 0 my $name = 'Downgraded-Original-Recipient';
405 0 0       0 unshift @_, shift, $name and goto &header;
406             }
407              
408             sub downgraded_rcpt_to {
409 0     0 1 0 my $name = 'Downgraded-Rcpt-To';
410 0 0       0 unshift @_, shift, $name and goto &header;
411             }
412              
413             sub downgraded_references {
414 0     0 1 0 my $name = 'Downgraded-References';
415 0 0       0 unshift @_, shift, $name and goto &header;
416             }
417              
418             sub downgraded_reply_to {
419 0     0 1 0 my $name = 'Downgraded-Reply-To';
420 0 0       0 unshift @_, shift, $name and goto &header;
421             }
422              
423             sub downgraded_resent_bcc {
424 0     0 1 0 my $name = 'Downgraded-Resent-Bcc';
425 0 0       0 unshift @_, shift, $name and goto &header;
426             }
427              
428             sub downgraded_resent_cc {
429 0     0 1 0 my $name = 'Downgraded-Resent-Cc';
430 0 0       0 unshift @_, shift, $name and goto &header;
431             }
432              
433             sub downgraded_resent_from {
434 0     0 1 0 my $name = 'Downgraded-Resent-From';
435 0 0       0 unshift @_, shift, $name and goto &header;
436             }
437              
438             sub downgraded_resent_reply_to {
439 0     0 1 0 my $name = 'Downgraded-Resent-Reply-To';
440 0 0       0 unshift @_, shift, $name and goto &header;
441             }
442              
443             sub downgraded_resent_sender {
444 0     0 1 0 my $name = 'Downgraded-Resent-Sender';
445 0 0       0 unshift @_, shift, $name and goto &header;
446             }
447              
448             sub downgraded_resent_to {
449 0     0 1 0 my $name = 'Downgraded-Resent-To';
450 0 0       0 unshift @_, shift, $name and goto &header;
451             }
452              
453             sub downgraded_return_path {
454 0     0 1 0 my $name = 'Downgraded-Return-Path';
455 0 0       0 unshift @_, shift, $name and goto &header;
456             }
457              
458             sub downgraded_sender {
459 0     0 1 0 my $name = 'Downgraded-Sender';
460 0 0       0 unshift @_, shift, $name and goto &header;
461             }
462              
463             sub downgraded_to {
464 0     0 1 0 my $name = 'Downgraded-To';
465 0 0       0 unshift @_, shift, $name and goto &header;
466             }
467              
468             sub ediint_features {
469 0     0 1 0 my $name = 'EDIINT-Features';
470 0 0       0 unshift @_, shift, $name and goto &header;
471             }
472              
473             sub encoding {
474 0     0 1 0 my $name = 'Encoding';
475 0 0       0 unshift @_, shift, $name and goto &header;
476             }
477              
478             sub encrypted {
479 0     0 1 0 my $name = 'Encrypted';
480 0 0       0 unshift @_, shift, $name and goto &header;
481             }
482              
483             sub errors_to {
484 0     0 1 0 my $name = 'Errors-To';
485 0 0       0 unshift @_, shift, $name and goto &header;
486             }
487              
488             sub expires {
489 0     0 1 0 my $name = 'Expires';
490 0 0       0 unshift @_, shift, $name and goto &header;
491             }
492              
493             sub expiry_date {
494 0     0 1 0 my $name = 'Expiry-Date';
495 0 0       0 unshift @_, shift, $name and goto &header;
496             }
497              
498             sub from {
499 0     0 1 0 my $name = 'From';
500 0 0       0 unshift @_, shift, $name and goto &header;
501             }
502              
503             sub generate_delivery_report {
504 0     0 1 0 my $name = 'Generate-Delivery-Report';
505 0 0       0 unshift @_, shift, $name and goto &header;
506             }
507              
508             sub importance {
509 0     0 1 0 my $name = 'Importance';
510 0 0       0 unshift @_, shift, $name and goto &header;
511             }
512              
513             sub in_reply_to {
514 0     0 1 0 my $name = 'In-Reply-To';
515 0 0       0 unshift @_, shift, $name and goto &header;
516             }
517              
518             sub incomplete_copy {
519 0     0 1 0 my $name = 'Incomplete-Copy';
520 0 0       0 unshift @_, shift, $name and goto &header;
521             }
522              
523             sub jabber_id {
524 0     0 1 0 my $name = 'Jabber-ID';
525 0 0       0 unshift @_, shift, $name and goto &header;
526             }
527              
528             sub keywords {
529 0     0 1 0 my $name = 'Keywords';
530 0 0       0 unshift @_, shift, $name and goto &header;
531             }
532              
533             sub language {
534 0     0 1 0 my $name = 'Language';
535 0 0       0 unshift @_, shift, $name and goto &header;
536             }
537              
538             sub latest_delivery_time {
539 0     0 1 0 my $name = 'Latest-Delivery-Time';
540 0 0       0 unshift @_, shift, $name and goto &header;
541             }
542              
543             sub list_archive {
544 0     0 1 0 my $name = 'List-Archive';
545 0 0       0 unshift @_, shift, $name and goto &header;
546             }
547              
548             sub list_help {
549 0     0 1 0 my $name = 'List-Help';
550 0 0       0 unshift @_, shift, $name and goto &header;
551             }
552              
553             sub list_id {
554 0     0 1 0 my $name = 'List-ID';
555 0 0       0 unshift @_, shift, $name and goto &header;
556             }
557              
558             sub list_owner {
559 0     0 1 0 my $name = 'List-Owner';
560 0 0       0 unshift @_, shift, $name and goto &header;
561             }
562              
563             sub list_post {
564 0     0 1 0 my $name = 'List-Post';
565 0 0       0 unshift @_, shift, $name and goto &header;
566             }
567              
568             sub list_subscribe {
569 0     0 1 0 my $name = 'List-Subscribe';
570 0 0       0 unshift @_, shift, $name and goto &header;
571             }
572              
573             sub list_unsubscribe {
574 0     0 1 0 my $name = 'List-Unsubscribe';
575 0 0       0 unshift @_, shift, $name and goto &header;
576             }
577              
578             sub mmhs_acp127_message_identifier {
579 0     0 1 0 my $name = 'MMHS-Acp127-Message-Identifier';
580 0 0       0 unshift @_, shift, $name and goto &header;
581             }
582              
583             sub mmhs_codress_message_indicator {
584 0     0 1 0 my $name = 'MMHS-Codress-Message-Indicator';
585 0 0       0 unshift @_, shift, $name and goto &header;
586             }
587              
588             sub mmhs_copy_precedence {
589 0     0 1 0 my $name = 'MMHS-Copy-Precedence';
590 0 0       0 unshift @_, shift, $name and goto &header;
591             }
592              
593             sub mmhs_exempted_address {
594 0     0 1 0 my $name = 'MMHS-Exempted-Address';
595 0 0       0 unshift @_, shift, $name and goto &header;
596             }
597              
598             sub mmhs_extended_authorisation_info {
599 0     0 1 0 my $name = 'MMHS-Extended-Authorisation-Info';
600 0 0       0 unshift @_, shift, $name and goto &header;
601             }
602              
603             sub mmhs_handling_instructions {
604 0     0 1 0 my $name = 'MMHS-Handling-Instructions';
605 0 0       0 unshift @_, shift, $name and goto &header;
606             }
607              
608             sub mmhs_message_instructions {
609 0     0 1 0 my $name = 'MMHS-Message-Instructions';
610 0 0       0 unshift @_, shift, $name and goto &header;
611             }
612              
613             sub mmhs_message_type {
614 0     0 1 0 my $name = 'MMHS-Message-Type';
615 0 0       0 unshift @_, shift, $name and goto &header;
616             }
617              
618             sub mmhs_originator_plad {
619 0     0 1 0 my $name = 'MMHS-Originator-PLAD';
620 0 0       0 unshift @_, shift, $name and goto &header;
621             }
622              
623             sub mmhs_originator_reference {
624 0     0 1 0 my $name = 'MMHS-Originator-Reference';
625 0 0       0 unshift @_, shift, $name and goto &header;
626             }
627              
628             sub mmhs_other_recipients_indicator_cc {
629 0     0 1 0 my $name = 'MMHS-Other-Recipients-Indicator-CC';
630 0 0       0 unshift @_, shift, $name and goto &header;
631             }
632              
633             sub mmhs_other_recipients_indicator_to {
634 0     0 1 0 my $name = 'MMHS-Other-Recipients-Indicator-To';
635 0 0       0 unshift @_, shift, $name and goto &header;
636             }
637              
638             sub mmhs_primary_precedence {
639 0     0 1 0 my $name = 'MMHS-Primary-Precedence';
640 0 0       0 unshift @_, shift, $name and goto &header;
641             }
642              
643             sub mmhs_subject_indicator_codes {
644 0     0 1 0 my $name = 'MMHS-Subject-Indicator-Codes';
645 0 0       0 unshift @_, shift, $name and goto &header;
646             }
647              
648             sub mt_priority {
649 0     0 1 0 my $name = 'MT-Priority';
650 0 0       0 unshift @_, shift, $name and goto &header;
651             }
652              
653             sub message_context {
654 0     0 1 0 my $name = 'Message-Context';
655 0 0       0 unshift @_, shift, $name and goto &header;
656             }
657              
658             sub message_id {
659 0     0 1 0 my $name = 'Message-ID';
660 0 0       0 unshift @_, shift, $name and goto &header;
661             }
662              
663             sub message_type {
664 0     0 1 0 my $name = 'Message-Type';
665 0 0       0 unshift @_, shift, $name and goto &header;
666             }
667              
668             sub obsoletes {
669 0     0 1 0 my $name = 'Obsoletes';
670 0 0       0 unshift @_, shift, $name and goto &header;
671             }
672              
673             sub original_encoded_information_types {
674 0     0 1 0 my $name = 'Original-Encoded-Information-Types';
675 0 0       0 unshift @_, shift, $name and goto &header;
676             }
677              
678             sub original_from {
679 0     0 1 0 my $name = 'Original-From';
680 0 0       0 unshift @_, shift, $name and goto &header;
681             }
682              
683             sub original_message_id {
684 0     0 1 0 my $name = 'Original-Message-ID';
685 0 0       0 unshift @_, shift, $name and goto &header;
686             }
687              
688             sub original_recipient {
689 0     0 1 0 my $name = 'Original-Recipient';
690 0 0       0 unshift @_, shift, $name and goto &header;
691             }
692              
693             sub original_subject {
694 0     0 1 0 my $name = 'Original-Subject';
695 0 0       0 unshift @_, shift, $name and goto &header;
696             }
697              
698             sub originator_return_address {
699 0     0 1 0 my $name = 'Originator-Return-Address';
700 0 0       0 unshift @_, shift, $name and goto &header;
701             }
702              
703             sub pics_label {
704 0     0 1 0 my $name = 'PICS-Label';
705 0 0       0 unshift @_, shift, $name and goto &header;
706             }
707              
708             sub prevent_nondelivery_report {
709 0     0 1 0 my $name = 'Prevent-NonDelivery-Report';
710 0 0       0 unshift @_, shift, $name and goto &header;
711             }
712              
713             sub priority {
714 0     0 1 0 my $name = 'Priority';
715 0 0       0 unshift @_, shift, $name and goto &header;
716             }
717              
718             sub privicon {
719 0     0 1 0 my $name = 'Privicon';
720 0 0       0 unshift @_, shift, $name and goto &header;
721             }
722              
723             sub received {
724 0     0 1 0 my $name = 'Received';
725 0 0       0 unshift @_, shift, $name and goto &header;
726             }
727              
728             sub received_spf {
729 0     0 1 0 my $name = 'Received-SPF';
730 0 0       0 unshift @_, shift, $name and goto &header;
731             }
732              
733             sub references {
734 0     0 1 0 my $name = 'References';
735 0 0       0 unshift @_, shift, $name and goto &header;
736             }
737              
738             sub reply_by {
739 0     0 1 0 my $name = 'Reply-By';
740 0 0       0 unshift @_, shift, $name and goto &header;
741             }
742              
743             sub reply_to {
744 0     0 1 0 my $name = 'Reply-To';
745 0 0       0 unshift @_, shift, $name and goto &header;
746             }
747              
748             sub require_recipient_valid_since {
749 0     0 1 0 my $name = 'Require-Recipient-Valid-Since';
750 0 0       0 unshift @_, shift, $name and goto &header;
751             }
752              
753             sub resent_bcc {
754 0     0 1 0 my $name = 'Resent-Bcc';
755 0 0       0 unshift @_, shift, $name and goto &header;
756             }
757              
758             sub resent_cc {
759 0     0 1 0 my $name = 'Resent-Cc';
760 0 0       0 unshift @_, shift, $name and goto &header;
761             }
762              
763             sub resent_date {
764 0     0 1 0 my $name = 'Resent-Date';
765 0 0       0 unshift @_, shift, $name and goto &header;
766             }
767              
768             sub resent_from {
769 0     0 1 0 my $name = 'Resent-From';
770 0 0       0 unshift @_, shift, $name and goto &header;
771             }
772              
773             sub resent_message_id {
774 0     0 1 0 my $name = 'Resent-Message-ID';
775 0 0       0 unshift @_, shift, $name and goto &header;
776             }
777              
778             sub resent_reply_to {
779 0     0 1 0 my $name = 'Resent-Reply-To';
780 0 0       0 unshift @_, shift, $name and goto &header;
781             }
782              
783             sub resent_sender {
784 0     0 1 0 my $name = 'Resent-Sender';
785 0 0       0 unshift @_, shift, $name and goto &header;
786             }
787              
788             sub resent_to {
789 0     0 1 0 my $name = 'Resent-To';
790 0 0       0 unshift @_, shift, $name and goto &header;
791             }
792              
793             sub return_path {
794 0     0 1 0 my $name = 'Return-Path';
795 0 0       0 unshift @_, shift, $name and goto &header;
796             }
797              
798             sub sio_label {
799 0     0 1 0 my $name = 'SIO-Label';
800 0 0       0 unshift @_, shift, $name and goto &header;
801             }
802              
803             sub sio_label_history {
804 0     0 1 0 my $name = 'SIO-Label-History';
805 0 0       0 unshift @_, shift, $name and goto &header;
806             }
807              
808             sub sender {
809 0     0 1 0 my $name = 'Sender';
810 0 0       0 unshift @_, shift, $name and goto &header;
811             }
812              
813             sub sensitivity {
814 0     0 1 0 my $name = 'Sensitivity';
815 0 0       0 unshift @_, shift, $name and goto &header;
816             }
817              
818             sub solicitation {
819 0     0 1 0 my $name = 'Solicitation';
820 0 0       0 unshift @_, shift, $name and goto &header;
821             }
822              
823             sub subject {
824 0     0 1 0 my $name = 'Subject';
825 0 0       0 unshift @_, shift, $name and goto &header;
826             }
827              
828             sub supersedes {
829 0     0 1 0 my $name = 'Supersedes';
830 0 0       0 unshift @_, shift, $name and goto &header;
831             }
832              
833             sub to {
834 0     0 1 0 my $name = 'To';
835 0 0       0 unshift @_, shift, $name and goto &header;
836             }
837              
838             sub vbr_info {
839 0     0 1 0 my $name = 'VBR-Info';
840 0 0       0 unshift @_, shift, $name and goto &header;
841             }
842              
843             sub x_archived_at {
844 0     0 1 0 my $name = 'X-Archived-At';
845 0 0       0 unshift @_, shift, $name and goto &header;
846             }
847              
848             sub x400_content_identifier {
849 0     0 1 0 my $name = 'X400-Content-Identifier';
850 0 0       0 unshift @_, shift, $name and goto &header;
851             }
852              
853             sub x400_content_return {
854 0     0 1 0 my $name = 'X400-Content-Return';
855 0 0       0 unshift @_, shift, $name and goto &header;
856             }
857              
858             sub x400_content_type {
859 0     0 1 0 my $name = 'X400-Content-Type';
860 0 0       0 unshift @_, shift, $name and goto &header;
861             }
862              
863             sub x400_mts_identifier {
864 0     0 1 0 my $name = 'X400-MTS-Identifier';
865 0 0       0 unshift @_, shift, $name and goto &header;
866             }
867              
868             sub x400_originator {
869 0     0 1 0 my $name = 'X400-Originator';
870 0 0       0 unshift @_, shift, $name and goto &header;
871             }
872              
873             sub x400_received {
874 0     0 1 0 my $name = 'X400-Received';
875 0 0       0 unshift @_, shift, $name and goto &header;
876             }
877              
878             sub x400_recipients {
879 0     0 1 0 my $name = 'X400-Recipients';
880 0 0       0 unshift @_, shift, $name and goto &header;
881             }
882              
883             sub x400_trace {
884 0     0 1 0 my $name = 'X400-Trace';
885 0 0       0 unshift @_, shift, $name and goto &header;
886             }
887              
888             sub header {
889 0     0 1 0 my ($self, $name) = (shift, shift);
890 0   0     0 $name = $headers{$name} // $name;
891              
892 0   0     0 my $headers = $self->{headers} //= {};
893              
894 0 0       0 return $headers->{$name} = shift if @_;
895 0         0 return $headers->{$name};
896             }
897              
898             sub prepare_address {
899 6     6 0 11 my ($self, $field, @arguments) = @_;
900              
901 6   50     15 my $headers = $self->{headers} //= {};
902 6         12 my $value = $headers->{$field};
903              
904             return join ",", map $_->format, Email::AddressParser->parse(
905 6 50       33 ref($value) eq 'ARRAY' ? join(',',@{$value}) : $value
  0         0  
906             );
907             }
908              
909             sub prepare_package {
910 3     3 0 7 my ($self, $options, @arguments) = @_;
911 3         8 $DB::single=1;
912 3   50     21 $options = Hash::Merge::Simple::merge($self, $options // {});
913              
914 3         139 my $stuff = Email::Stuffer->new;
915 3         5486 my $email = __PACKAGE__->new();
916              
917 3         6 $email->{$_} = $options->{$_} for keys %{$options};
  3         23  
918              
919             # remap references
920 3         6 $_[0] = $self = $email;
921              
922             # configure headers
923 3   50     19 my $headers = $email->{headers} //= {};
924              
925             # extract headers
926 3         118 for my $key (keys %headers) {
927 549         733 my $name = $headers{$key};
928 549 100       1207 my $value = delete $email->{$key} or next;
929 9 50 33     52 $headers->{$name} = $value if $name and not defined $headers->{$name};
930             }
931              
932             # required fields
933 3         43 my @required = @{$headers}{qw(From Subject To)};
  3         10  
934 3 50       9 confess "Can't send email without a to, from, and subject property"
935             unless @required == 3;
936              
937             # process address headers
938 3         12 my @address_headers = qw(
939             Abuse-Reports-To
940             Apparently-To
941             Delivered-To
942             Disposition-Notification-To
943             Errors-To
944             Followup-To
945             In-Reply-To
946             Mail-Copies-To
947             Posted-To
948             Read-Receipt-To
949             Resent-Reply-To
950             Resent-To
951             Return-Receipt-To
952             );
953 3         5 for my $key (qw(Cc Bcc From Reply-To To), @address_headers) {
954             $stuff->header($key => $email->prepare_address($key))
955 54 100       799 if defined $headers->{$key};
956             }
957              
958             # process subject
959 3 50       24 $stuff->subject($headers->{Subject}) if defined $headers->{Subject};
960              
961             # process message
962 3 50       165 if (defined $email->{message}) {
963 3         6 my $type = $email->{type};
964 3         5 my $message = $email->{message};
965              
966 3         6 my $multi = ref($email->{message}) eq 'HASH';
967              
968 3 50       7 my $html_msg = $email->{message}{html} if $multi;
969 3 50       6 my $text_msg = $email->{message}{text} if $multi;
970              
971             # multipart send using plain text and html
972 3 50 33     25 if (($type and lc($type) eq 'multi') or ($html_msg and $text_msg)) {
    50 33        
      33        
      33        
      33        
973 0 0       0 $stuff->html_body("$html_msg") if defined $html_msg;
974 0 0       0 $stuff->text_body("$text_msg") if defined $text_msg;
975             }
976             elsif (($type and lc($type) ne 'multi') and $message) {
977             # standard send using html or plain text
978 0 0 0     0 $stuff->html_body("$message") if $type and $type eq 'html';
979 0 0 0     0 $stuff->text_body("$message") if $type and $type eq 'text';
980             }
981             else {
982 3         13 $stuff->text_body("$message");
983             }
984             }
985              
986             confess "Can't send email without a message property"
987 3 50       3666 unless defined $email->{message};
988              
989             # process additional headers
990 3         8 my %excluded_headers = map { $_ => 1 } @address_headers, qw(
  57         113  
991             Cc
992             Bcc
993             From
994             Reply-To
995             Subject
996             To
997             );
998 3         13 for my $key (grep { !$excluded_headers{$_} } @headers) {
  549         984  
999             $stuff->header($key => $headers->{$key})
1000 513 50       1048 if defined $headers->{$key}
1001             }
1002              
1003             # process attachments - old behavior
1004 3 50       10 if (my $attachments = $email->{attach}) {
1005 0 0       0 if (ref($attachments) eq 'ARRAY') {
1006 0         0 my %files = @{$attachments};
  0         0  
1007 0         0 foreach my $file (keys %files) {
1008 0 0       0 if ($files{$file}) {
1009 0         0 my $data = read_file($files{$file}, binmode => ':raw');
1010 0         0 $stuff->attach($data, name => $file, filename => $file);
1011             }
1012             else {
1013 0         0 $stuff->attach_file($file);
1014             }
1015             }
1016             }
1017             }
1018              
1019             # process attachments - new behavior
1020 3 50       9 if (my $attachments = $email->{files}) {
1021 0 0       0 if (ref($attachments) eq 'ARRAY') {
1022 0         0 $stuff->attach_file($_) for @{$attachments};
  0         0  
1023             }
1024             }
1025              
1026             # transport email explicitly
1027 3 50       18 $stuff->transport(@arguments) if @arguments;
1028 3 50       2176 return $stuff if @arguments;
1029              
1030             # transport email implicitly
1031 0           my $driver = $email->{driver};
1032 0           my $sendmail = lc($driver) eq 'sendmail';
1033 0           my $smtpmail = lc($driver) eq 'smtp';
1034              
1035             # default transport to sendmail
1036 0 0 0       $sendmail = 1 unless $sendmail or $smtpmail;
1037              
1038 0 0         if ($sendmail) {
1039 0           my $path = $email->{path};
1040              
1041 0 0 0       $path ||= '/usr/bin/sendmail' if -f '/usr/bin/sendmail';
1042 0 0 0       $path ||= '/usr/sbin/sendmail' if -f '/usr/sbin/sendmail';
1043              
1044 0           $stuff->transport('Sendmail' => (sendmail => $path));
1045             }
1046              
1047 0 0         if ($smtpmail) {
1048 0           my %map = (
1049             user => 'sasl_username',
1050             pass => 'sasl_password'
1051             );
1052 0           my @keys = qw(
1053             debug
1054             host
1055             pass
1056             password
1057             port
1058             ssl
1059             user
1060             username
1061             );
1062 0           my @params = ();
1063              
1064 0           for my $key (@keys) {
1065             push @params, $map{$key} // $key, $email->{$key}
1066 0 0 0       if defined $email->{$key};
1067             }
1068              
1069 0           push @params, 'proto' => 'tcp'; # no longer used
1070 0           push @params, 'reuse' => 1; # no longer used
1071              
1072 0           $stuff->transport('SMTP' => @params);
1073             }
1074              
1075 0           return $stuff;
1076             }
1077              
1078             1;
1079              
1080             __END__