line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
26595
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
35
|
|
2
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
66
|
|
3
|
|
|
|
|
|
|
package Email::Reply; |
4
|
|
|
|
|
|
|
{ |
5
|
|
|
|
|
|
|
$Email::Reply::VERSION = '1.203'; |
6
|
|
|
|
|
|
|
} |
7
|
|
|
|
|
|
|
# ABSTRACT: reply to an email message |
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
807
|
use Email::Abstract 2.01; |
|
1
|
|
|
|
|
36435
|
|
|
1
|
|
|
|
|
37
|
|
10
|
1
|
|
|
1
|
|
823
|
use Email::Address 1.80; |
|
1
|
|
|
|
|
39441
|
|
|
1
|
|
|
|
|
79
|
|
11
|
1
|
|
|
1
|
|
1106
|
use Email::MIME 1.82; |
|
1
|
|
|
|
|
32513
|
|
|
1
|
|
|
|
|
35
|
|
12
|
1
|
|
|
1
|
|
13
|
use Exporter 5.57 'import'; |
|
1
|
|
|
|
|
14
|
|
|
1
|
|
|
|
|
1294
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
my $CLASS = __PACKAGE__; |
15
|
|
|
|
|
|
|
our @EXPORT = qw[reply]; |
16
|
|
|
|
|
|
|
my $CRLF = "\x0d\x0a"; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Want to subclass and still use the functional interface? |
19
|
|
|
|
|
|
|
# That's cool, just add these lines to your package: |
20
|
|
|
|
|
|
|
# use base qw[Exporter]; |
21
|
|
|
|
|
|
|
# use vars qw[@EXPORT $CLASS]; |
22
|
|
|
|
|
|
|
# @EXPORT = qw[reply]; |
23
|
|
|
|
|
|
|
# $CLASS = __PACKAGE__; |
24
|
|
|
|
|
|
|
# *reply = \&Email::Reply::reply; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub reply { |
27
|
3
|
|
|
3
|
1
|
21646
|
my $reply = $CLASS->_new(@_); |
28
|
3
|
|
|
|
|
16
|
$reply->_make_headers; |
29
|
3
|
100
|
|
|
|
15
|
$reply->_encapsulate_message if $reply->{attach}; |
30
|
3
|
50
|
33
|
|
|
1046
|
$reply->_quote_body($reply->{original}) |
31
|
|
|
|
|
|
|
if $reply->{quote} || $reply->{top_post}; |
32
|
3
|
50
|
|
|
|
18
|
$reply->_post_reply if $reply->{body}; |
33
|
3
|
100
|
|
|
|
18
|
return $reply->{message} ? $reply->_mime : $reply->_simple; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub _new { |
37
|
3
|
|
|
3
|
|
22
|
my ($class, %args) = @_; |
38
|
3
|
|
|
|
|
8
|
my $self = {}; |
39
|
3
|
|
|
|
|
29
|
$self->{original} = Email::MIME->new(Email::Abstract->as_string($args{to})); |
40
|
|
|
|
|
|
|
|
41
|
3
|
|
66
|
|
|
6963
|
($self->{from}) = |
42
|
|
|
|
|
|
|
Email::Address->parse($args{from} || $self->{original}->header('To')); |
43
|
|
|
|
|
|
|
|
44
|
3
|
|
33
|
|
|
1845
|
($self->{to}) = Email::Address->parse( |
45
|
|
|
|
|
|
|
$self->{original}->header('Reply-To') |
46
|
|
|
|
|
|
|
|| $self->{original}->header('From') |
47
|
|
|
|
|
|
|
|| $self->{original}->header('Return-Path') |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
3
|
|
66
|
|
|
387
|
$self->{attrib} = $args{attrib} |
51
|
|
|
|
|
|
|
|| (($self->{to}->name || join($self->{to}->address, '<', '>')) . ' wrote:'); |
52
|
|
|
|
|
|
|
|
53
|
3
|
|
100
|
|
|
352
|
$self->{prefix} = $args{prefix} || '> '; |
54
|
3
|
|
|
|
|
10
|
$self->{top_post} = $args{top_post}; |
55
|
3
|
50
|
|
|
|
16
|
$self->{quote} = exists $args{quote} ? $args{quote} : 1; |
56
|
3
|
|
|
|
|
11
|
$self->{all} = $args{all}; |
57
|
3
|
|
|
|
|
10
|
$self->{quoted} = ''; |
58
|
3
|
|
|
|
|
8
|
$self->{body} = $args{body}; |
59
|
3
|
|
|
|
|
7
|
$self->{attach} = $args{attach}; |
60
|
3
|
|
|
|
|
10
|
$self->{keep_sig} = $args{keep_sig}; |
61
|
|
|
|
|
|
|
|
62
|
3
|
|
|
|
|
17
|
return bless $self, $class; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub _make_headers { |
66
|
3
|
|
|
3
|
|
6
|
my $self = shift; |
67
|
|
|
|
|
|
|
|
68
|
3
|
|
|
|
|
19
|
my @header = (From => $self->{from},); |
69
|
|
|
|
|
|
|
|
70
|
3
|
50
|
|
|
|
17
|
$self->{to} |
71
|
|
|
|
|
|
|
->name((Email::Address->parse($self->{original}->header('From')))[0]->name) |
72
|
|
|
|
|
|
|
unless $self->{to}->name; |
73
|
3
|
|
|
|
|
43
|
push @header, To => $self->{to}; |
74
|
|
|
|
|
|
|
|
75
|
3
|
|
50
|
|
|
12
|
my $subject = $self->{original}->header('Subject') || ''; |
76
|
3
|
100
|
|
|
|
140
|
$subject = "Re: $subject" unless $subject =~ /\bRe:/i; |
77
|
3
|
|
|
|
|
10
|
push @header, Subject => $subject; |
78
|
|
|
|
|
|
|
|
79
|
3
|
|
|
|
|
15
|
my ($msg_id) = Email::Address->parse($self->{original}->header('Message-ID')); |
80
|
3
|
|
|
|
|
296
|
push @header, 'In-Reply-To' => $msg_id; |
81
|
|
|
|
|
|
|
|
82
|
3
|
|
|
|
|
13
|
my @refs = Email::Address->parse($self->{original}->header('References')); |
83
|
3
|
100
|
|
|
|
132
|
@refs = Email::Address->parse($self->{original}->header('In-Reply-To')) |
84
|
|
|
|
|
|
|
unless @refs; |
85
|
3
|
100
|
|
|
|
72
|
push @refs, $msg_id if $msg_id; |
86
|
3
|
100
|
|
|
|
89
|
push @header, References => join ' ', @refs if @refs; |
87
|
|
|
|
|
|
|
|
88
|
3
|
100
|
|
|
|
49
|
if ($self->{all}) { |
89
|
1
|
|
|
|
|
6
|
my @addrs = ( |
90
|
|
|
|
|
|
|
Email::Address->parse($self->{original}->header('To')), |
91
|
|
|
|
|
|
|
Email::Address->parse($self->{original}->header('Cc')), |
92
|
|
|
|
|
|
|
); |
93
|
1
|
50
|
|
|
|
247
|
unless ($self->{self}) { |
94
|
1
|
|
|
|
|
3
|
@addrs = grep { $_->address ne $self->{from}->address } @addrs; |
|
3
|
|
|
|
|
26
|
|
95
|
|
|
|
|
|
|
} |
96
|
1
|
50
|
|
|
|
15
|
push @header, Cc => join ', ', @addrs if @addrs; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
3
|
|
|
|
|
41
|
$self->{header} = \@header; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub _encapsulate_message { |
103
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
104
|
1
|
|
|
|
|
9
|
$self->{message} = Email::MIME->create( |
105
|
|
|
|
|
|
|
attributes => { content_type => 'message/rfc822', }, |
106
|
|
|
|
|
|
|
body => $self->{original}->as_string, |
107
|
|
|
|
|
|
|
); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
my $crlf = qr/\x0a\x0d|\x0d\x0a|\x0a|\x0d/; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub _quote_body { |
113
|
5
|
|
|
5
|
|
35
|
my ($self, $part) = @_; |
114
|
5
|
100
|
|
|
|
17
|
return if length $self->{quoted}; |
115
|
4
|
100
|
|
|
|
17
|
return map $self->_quote_body($_), $part->parts if $part->parts > 1; |
116
|
3
|
50
|
33
|
|
|
43
|
return if $part->content_type && $part->content_type !~ m[\btext/plain\b]; |
117
|
|
|
|
|
|
|
|
118
|
3
|
|
|
|
|
141
|
my $body = $part->body; |
119
|
|
|
|
|
|
|
|
120
|
3
|
100
|
33
|
|
|
212
|
$body = ($self->_strip_sig($body) || $body) |
|
|
|
100
|
|
|
|
|
121
|
|
|
|
|
|
|
if !$self->{keep_sig} && $body =~ /$crlf--\s*$crlf/o; |
122
|
|
|
|
|
|
|
|
123
|
3
|
|
|
|
|
53
|
my ($end) = $body =~ /($crlf)/; |
124
|
3
|
|
33
|
|
|
12
|
$end ||= $CRLF; |
125
|
3
|
|
|
|
|
29
|
$body =~ s/[\r\n\s]+$//; |
126
|
3
|
|
|
|
|
13
|
$body = $self->_quote_orig_body($body); |
127
|
3
|
|
|
|
|
11
|
$body = "$self->{attrib}$end$body$end"; |
128
|
|
|
|
|
|
|
|
129
|
3
|
|
|
|
|
9
|
$self->{crlf} = $end; |
130
|
3
|
|
|
|
|
12
|
$self->{quoted} = $body; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# Yes, you are witnessing elitism. |
134
|
1
|
|
|
1
|
|
40
|
sub _strip_sig { reverse +(split /$crlf\s*--$crlf/o, reverse(pop), 2)[1] } |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub _quote_orig_body { |
137
|
3
|
|
|
3
|
|
8
|
my ($self, $body) = @_; |
138
|
3
|
|
|
|
|
84
|
$body =~ s/($crlf)/$1$self->{prefix}/g; |
139
|
3
|
|
|
|
|
16
|
"$self->{prefix}$body"; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub _post_reply { |
143
|
3
|
|
|
3
|
|
6
|
my $self = shift; |
144
|
3
|
50
|
|
|
|
13
|
return $self->{reply_body} = $self->{body} |
145
|
|
|
|
|
|
|
unless length $self->{quoted}; |
146
|
3
|
|
|
|
|
13
|
my @parts = (@{$self}{qw[quoted body]}); |
|
3
|
|
|
|
|
12
|
|
147
|
3
|
100
|
|
|
|
11
|
@parts = reverse @parts if $self->{top_post}; |
148
|
3
|
|
|
|
|
16
|
$self->{reply_body} = join $self->{crlf}, @parts; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub _mime { |
152
|
1
|
|
|
1
|
|
3
|
my $self = shift; |
153
|
1
|
|
|
|
|
7
|
Email::MIME->create( |
154
|
|
|
|
|
|
|
header => $self->{header}, |
155
|
|
|
|
|
|
|
parts => |
156
|
|
|
|
|
|
|
[ Email::MIME->create(body => $self->{reply_body}), $self->{message}, ], |
157
|
|
|
|
|
|
|
); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub _simple { |
161
|
2
|
|
|
2
|
|
4
|
my $self = shift; |
162
|
2
|
|
|
|
|
13
|
Email::Simple->create( |
163
|
|
|
|
|
|
|
header => $self->{header}, |
164
|
|
|
|
|
|
|
body => $self->{reply_body}, |
165
|
|
|
|
|
|
|
); |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
1; |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
__END__ |