mail 2.8.1 → 2.9.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +76 -31
- data/lib/mail/attachments_list.rb +3 -1
- data/lib/mail/body.rb +28 -28
- data/lib/mail/encodings/quoted_printable.rb +1 -1
- data/lib/mail/encodings/unix_to_unix.rb +1 -1
- data/lib/mail/encodings.rb +2 -2
- data/lib/mail/field.rb +65 -35
- data/lib/mail/field_list.rb +1 -1
- data/lib/mail/fields/bcc_field.rb +0 -1
- data/lib/mail/fields/cc_field.rb +0 -1
- data/lib/mail/fields/comments_field.rb +0 -1
- data/lib/mail/fields/common_address_field.rb +9 -17
- data/lib/mail/fields/common_date_field.rb +0 -2
- data/lib/mail/fields/common_message_id_field.rb +0 -1
- data/lib/mail/fields/content_description_field.rb +0 -1
- data/lib/mail/fields/content_disposition_field.rb +0 -2
- data/lib/mail/fields/content_id_field.rb +0 -1
- data/lib/mail/fields/content_location_field.rb +0 -1
- data/lib/mail/fields/content_transfer_encoding_field.rb +0 -1
- data/lib/mail/fields/content_type_field.rb +5 -6
- data/lib/mail/fields/date_field.rb +0 -1
- data/lib/mail/fields/from_field.rb +0 -1
- data/lib/mail/fields/in_reply_to_field.rb +0 -1
- data/lib/mail/fields/keywords_field.rb +0 -1
- data/lib/mail/fields/message_id_field.rb +0 -1
- data/lib/mail/fields/mime_version_field.rb +1 -2
- data/lib/mail/fields/named_structured_field.rb +0 -1
- data/lib/mail/fields/named_unstructured_field.rb +0 -1
- data/lib/mail/fields/optional_field.rb +0 -1
- data/lib/mail/fields/received_field.rb +0 -1
- data/lib/mail/fields/references_field.rb +0 -1
- data/lib/mail/fields/reply_to_field.rb +0 -1
- data/lib/mail/fields/resent_bcc_field.rb +0 -1
- data/lib/mail/fields/resent_cc_field.rb +0 -1
- data/lib/mail/fields/resent_date_field.rb +0 -1
- data/lib/mail/fields/resent_from_field.rb +0 -1
- data/lib/mail/fields/resent_message_id_field.rb +0 -1
- data/lib/mail/fields/resent_sender_field.rb +0 -1
- data/lib/mail/fields/resent_to_field.rb +0 -1
- data/lib/mail/fields/return_path_field.rb +0 -1
- data/lib/mail/fields/sender_field.rb +0 -1
- data/lib/mail/fields/structured_field.rb +0 -1
- data/lib/mail/fields/subject_field.rb +0 -1
- data/lib/mail/fields/to_field.rb +0 -1
- data/lib/mail/fields/unstructured_field.rb +0 -1
- data/lib/mail/fields.rb +9 -0
- data/lib/mail/header.rb +1 -1
- data/lib/mail/mail.rb +32 -27
- data/lib/mail/message.rb +22 -19
- data/lib/mail/multibyte/chars.rb +1 -1
- data/lib/mail/multibyte/unicode.rb +1 -1
- data/lib/mail/network/delivery_methods/file_delivery.rb +2 -2
- data/lib/mail/network/delivery_methods/sendmail.rb +2 -48
- data/lib/mail/network/delivery_methods/smtp.rb +77 -42
- data/lib/mail/network/delivery_methods/smtp_connection.rb +7 -7
- data/lib/mail/network/delivery_methods/test_mailer.rb +4 -4
- data/lib/mail/network/retriever_methods/base.rb +5 -5
- data/lib/mail/network/retriever_methods/imap.rb +6 -3
- data/lib/mail/network/retriever_methods/pop3.rb +20 -20
- data/lib/mail/parsers/address_lists_parser.rb +8 -5
- data/lib/mail/parsers/address_lists_parser.rl +4 -0
- data/lib/mail/parsers/content_disposition_parser.rb +15 -12
- data/lib/mail/parsers/content_disposition_parser.rl +4 -0
- data/lib/mail/parsers/content_location_parser.rb +9 -6
- data/lib/mail/parsers/content_location_parser.rl +5 -1
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +8 -5
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +4 -0
- data/lib/mail/parsers/content_type_parser.rb +15 -12
- data/lib/mail/parsers/content_type_parser.rl +4 -0
- data/lib/mail/parsers/date_time_parser.rb +8 -5
- data/lib/mail/parsers/date_time_parser.rl +4 -0
- data/lib/mail/parsers/envelope_from_parser.rb +8 -5
- data/lib/mail/parsers/envelope_from_parser.rl +4 -0
- data/lib/mail/parsers/message_ids_parser.rb +8 -5
- data/lib/mail/parsers/message_ids_parser.rl +4 -0
- data/lib/mail/parsers/mime_version_parser.rb +8 -5
- data/lib/mail/parsers/mime_version_parser.rl +4 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +8 -5
- data/lib/mail/parsers/phrase_lists_parser.rl +4 -0
- data/lib/mail/parsers/received_parser.rb +8 -5
- data/lib/mail/parsers/received_parser.rl +4 -0
- data/lib/mail/part.rb +19 -19
- data/lib/mail/smtp_envelope.rb +1 -1
- data/lib/mail/utilities.rb +5 -5
- data/lib/mail/version.rb +3 -3
- data/lib/mail.rb +2 -5
- metadata +3 -4
- data/lib/mail/check_delivery_params.rb +0 -65
@@ -49,12 +49,8 @@ module Mail
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def initialize(values)
|
52
|
-
if values[:arguments].is_a?(String)
|
53
|
-
deprecation_warn.call \
|
54
|
-
'Initializing Mail::Sendmail with :arguments of type String is deprecated.' \
|
55
|
-
' Instead ensure :arguments is an array of strings, e.g. ["-i", "-t"]'
|
56
|
-
end
|
57
52
|
self.settings = self.class::DEFAULTS.merge(values)
|
53
|
+
raise ArgumentError, ":arguments expected to be an Array of individual string args" if settings[:arguments].is_a?(String)
|
58
54
|
end
|
59
55
|
|
60
56
|
def destinations_for(envelope)
|
@@ -64,13 +60,8 @@ module Mail
|
|
64
60
|
def deliver!(mail)
|
65
61
|
envelope = Mail::SmtpEnvelope.new(mail)
|
66
62
|
|
67
|
-
arguments = settings[:arguments]
|
68
|
-
if arguments.is_a? String
|
69
|
-
return old_deliver(envelope)
|
70
|
-
end
|
71
|
-
|
72
63
|
command = [settings[:location]]
|
73
|
-
command.concat Array(arguments)
|
64
|
+
command.concat Array(settings[:arguments])
|
74
65
|
command.concat [ '-f', envelope.from ] if envelope.from
|
75
66
|
|
76
67
|
if destinations = destinations_for(envelope)
|
@@ -92,42 +83,5 @@ module Mail
|
|
92
83
|
end
|
93
84
|
end
|
94
85
|
end
|
95
|
-
|
96
|
-
#+ support for delivery using string arguments (deprecated)
|
97
|
-
def old_deliver(envelope)
|
98
|
-
smtp_from = envelope.from
|
99
|
-
smtp_to = destinations_for(envelope)
|
100
|
-
|
101
|
-
from = "-f #{shellquote(smtp_from)}" if smtp_from
|
102
|
-
destination = smtp_to.map { |to| shellquote(to) }.join(' ')
|
103
|
-
|
104
|
-
arguments = "#{settings[:arguments]} #{from} --"
|
105
|
-
command = "#{settings[:location]} #{arguments} #{destination}"
|
106
|
-
popen command do |io|
|
107
|
-
io.puts ::Mail::Utilities.binary_unsafe_to_lf(envelope.message)
|
108
|
-
io.flush
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# The following is an adaptation of ruby 1.9.2's shellwords.rb file,
|
113
|
-
# with the following modifications:
|
114
|
-
#
|
115
|
-
# - Wraps in double quotes
|
116
|
-
# - Allows '+' to accept email addresses with them
|
117
|
-
# - Allows '~' as it is not unescaped in double quotes
|
118
|
-
def shellquote(address)
|
119
|
-
# Process as a single byte sequence because not all shell
|
120
|
-
# implementations are multibyte aware.
|
121
|
-
#
|
122
|
-
# A LF cannot be escaped with a backslash because a backslash + LF
|
123
|
-
# combo is regarded as line continuation and simply ignored. Strip it.
|
124
|
-
escaped = address.gsub(/([^A-Za-z0-9_\s\+\-.,:\/@~])/n, "\\\\\\1").gsub("\n", '')
|
125
|
-
%("#{escaped}")
|
126
|
-
end
|
127
|
-
#- support for delivery using string arguments
|
128
|
-
|
129
|
-
def deprecation_warn
|
130
|
-
defined?(ActiveSupport::Deprecation.warn) ? ActiveSupport::Deprecation.method(:warn) : Kernel.method(:warn)
|
131
|
-
end
|
132
86
|
end
|
133
87
|
end
|
@@ -3,18 +3,18 @@ require 'mail/smtp_envelope'
|
|
3
3
|
|
4
4
|
module Mail
|
5
5
|
# == Sending Email with SMTP
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Mail allows you to send emails using SMTP. This is done by wrapping Net::SMTP in
|
8
8
|
# an easy to use manner.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# === Sending via SMTP server on Localhost
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Sending locally (to a postfix or sendmail server running on localhost) requires
|
13
13
|
# no special setup. Just to Mail.deliver &block or message.deliver! and it will
|
14
14
|
# be sent in this method.
|
15
|
-
#
|
15
|
+
#
|
16
16
|
# === Sending via MobileMe
|
17
|
-
#
|
17
|
+
#
|
18
18
|
# Mail.defaults do
|
19
19
|
# delivery_method :smtp, { :address => "smtp.me.com",
|
20
20
|
# :port => 587,
|
@@ -22,11 +22,11 @@ module Mail
|
|
22
22
|
# :user_name => '<username>',
|
23
23
|
# :password => '<password>',
|
24
24
|
# :authentication => 'plain',
|
25
|
-
# :
|
25
|
+
# :enable_starttls => :auto }
|
26
26
|
# end
|
27
|
-
#
|
27
|
+
#
|
28
28
|
# === Sending via GMail
|
29
|
-
#
|
29
|
+
#
|
30
30
|
# Mail.defaults do
|
31
31
|
# delivery_method :smtp, { :address => "smtp.gmail.com",
|
32
32
|
# :port => 587,
|
@@ -34,9 +34,17 @@ module Mail
|
|
34
34
|
# :user_name => '<username>',
|
35
35
|
# :password => '<password>',
|
36
36
|
# :authentication => 'plain',
|
37
|
-
# :
|
37
|
+
# :enable_starttls => :auto }
|
38
38
|
# end
|
39
39
|
#
|
40
|
+
# === Configuring TLS/SSL and STARTTLS
|
41
|
+
#
|
42
|
+
# A few remarks:
|
43
|
+
# - when enabling `tls` (or `ssl`), setting (truthy values for) either `enable_starttls` or `enable_starttls_auto` will raise an ArgumentError as TLS and STARTTLS are mutually exclusive.
|
44
|
+
# - to configure STARTTLS, use the `enable_starttls`-flag (instead of a combination of `enable_starttls` and `enable_starttls_auto`). Acceptable values are `:always`, `:auto` and `false`.
|
45
|
+
# - when providing a truthy value for `enable_starttls`, the `enable_starttls_auto`-flag will be ignored.
|
46
|
+
# - when none of `tls`, `ssl`, `enable_starttls` or `enable_starttls_auto` is set, the fallback will be `enable_starttls` `:auto`.
|
47
|
+
#
|
40
48
|
# === Certificate verification
|
41
49
|
#
|
42
50
|
# When using TLS, some mail servers provide certificates that are self-signed
|
@@ -48,30 +56,30 @@ module Mail
|
|
48
56
|
# verify mode constant (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER),
|
49
57
|
# or a string containing the name of an OpenSSL verify mode (none, peer).
|
50
58
|
#
|
51
|
-
# === Others
|
52
|
-
#
|
59
|
+
# === Others
|
60
|
+
#
|
53
61
|
# Feel free to send me other examples that were tricky
|
54
|
-
#
|
62
|
+
#
|
55
63
|
# === Delivering the email
|
56
|
-
#
|
64
|
+
#
|
57
65
|
# Once you have the settings right, sending the email is done by:
|
58
|
-
#
|
66
|
+
#
|
59
67
|
# Mail.deliver do
|
60
68
|
# to 'mikel@test.lindsaar.net'
|
61
69
|
# from 'ada@test.lindsaar.net'
|
62
70
|
# subject 'testing sendmail'
|
63
71
|
# body 'testing sendmail'
|
64
72
|
# end
|
65
|
-
#
|
73
|
+
#
|
66
74
|
# Or by calling deliver on a Mail message
|
67
|
-
#
|
75
|
+
#
|
68
76
|
# mail = Mail.new do
|
69
77
|
# to 'mikel@test.lindsaar.net'
|
70
78
|
# from 'ada@test.lindsaar.net'
|
71
79
|
# subject 'testing sendmail'
|
72
80
|
# body 'testing sendmail'
|
73
81
|
# end
|
74
|
-
#
|
82
|
+
#
|
75
83
|
# mail.deliver!
|
76
84
|
class SMTP
|
77
85
|
attr_accessor :settings
|
@@ -84,7 +92,7 @@ module Mail
|
|
84
92
|
:password => nil,
|
85
93
|
:authentication => nil,
|
86
94
|
:enable_starttls => nil,
|
87
|
-
:enable_starttls_auto =>
|
95
|
+
:enable_starttls_auto => nil,
|
88
96
|
:openssl_verify_mode => nil,
|
89
97
|
:ssl => nil,
|
90
98
|
:tls => nil,
|
@@ -105,39 +113,66 @@ module Mail
|
|
105
113
|
end
|
106
114
|
|
107
115
|
private
|
116
|
+
# `k` is said to be provided when `settings` has a non-nil value for `k`.
|
117
|
+
def setting_provided?(k)
|
118
|
+
!settings[k].nil?
|
119
|
+
end
|
120
|
+
|
121
|
+
# Yields one of `:always`, `:auto` or `false` based on `enable_starttls` and `enable_starttls_auto` flags.
|
122
|
+
# Yields `false` when `smtp_tls?`.
|
123
|
+
# Else defaults to `:auto` when neither `enable_starttls*` flag is provided.
|
124
|
+
# Providing a truthy value for `enable_starttls` will ignore `enable_starttls_auto`.
|
125
|
+
def smtp_starttls
|
126
|
+
return false if smtp_tls?
|
127
|
+
|
128
|
+
if setting_provided?(:enable_starttls) && settings[:enable_starttls]
|
129
|
+
# enable_starttls: provided and truthy
|
130
|
+
case settings[:enable_starttls]
|
131
|
+
when :auto then :auto
|
132
|
+
when :always then :always
|
133
|
+
else
|
134
|
+
:always
|
135
|
+
end
|
136
|
+
else
|
137
|
+
# enable_starttls: not provided or false
|
138
|
+
if setting_provided?(:enable_starttls_auto)
|
139
|
+
settings[:enable_starttls_auto] ? :auto : false
|
140
|
+
else
|
141
|
+
# enable_starttls_auto: not provided
|
142
|
+
# enable_starttls: when provided then false
|
143
|
+
# use :auto when neither enable_starttls* provided
|
144
|
+
setting_provided?(:enable_starttls) ? false : :auto
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def smtp_tls?
|
150
|
+
(setting_provided?(:tls) && settings[:tls]) || (setting_provided?(:ssl) && settings[:ssl])
|
151
|
+
end
|
152
|
+
|
108
153
|
def start_smtp_session(&block)
|
109
154
|
build_smtp_session.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication], &block)
|
110
155
|
end
|
111
156
|
|
112
157
|
def build_smtp_session
|
158
|
+
if smtp_tls? && (settings[:enable_starttls] || settings[:enable_starttls_auto])
|
159
|
+
raise ArgumentError, ":enable_starttls and :tls are mutually exclusive. Set :tls if you're on an SMTPS connection. Set :enable_starttls if you're on an SMTP connection and using STARTTLS for secure TLS upgrade."
|
160
|
+
end
|
161
|
+
|
113
162
|
Net::SMTP.new(settings[:address], settings[:port]).tap do |smtp|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
raise ArgumentError, "Unrecognized :tls value #{settings[:tls].inspect}; expected true, false, or nil"
|
123
|
-
end
|
124
|
-
elsif settings.include?(:enable_starttls) && !settings[:enable_starttls].nil?
|
125
|
-
case settings[:enable_starttls]
|
126
|
-
when true
|
163
|
+
if smtp_tls?
|
164
|
+
smtp.disable_starttls
|
165
|
+
smtp.enable_tls(ssl_context)
|
166
|
+
else
|
167
|
+
smtp.disable_tls
|
168
|
+
|
169
|
+
case smtp_starttls
|
170
|
+
when :always
|
127
171
|
smtp.enable_starttls(ssl_context)
|
128
|
-
when
|
129
|
-
smtp.disable_starttls
|
130
|
-
else
|
131
|
-
raise ArgumentError, "Unrecognized :enable_starttls value #{settings[:enable_starttls].inspect}; expected true, false, or nil"
|
132
|
-
end
|
133
|
-
elsif settings.include?(:enable_starttls_auto) && !settings[:enable_starttls_auto].nil?
|
134
|
-
case settings[:enable_starttls_auto]
|
135
|
-
when true
|
172
|
+
when :auto
|
136
173
|
smtp.enable_starttls_auto(ssl_context)
|
137
|
-
when false
|
138
|
-
smtp.disable_starttls
|
139
174
|
else
|
140
|
-
|
175
|
+
smtp.disable_starttls
|
141
176
|
end
|
142
177
|
end
|
143
178
|
|
@@ -3,39 +3,39 @@ require 'mail/smtp_envelope'
|
|
3
3
|
|
4
4
|
module Mail
|
5
5
|
# == Sending Email with SMTP
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Mail allows you to send emails using an open SMTP connection. This is done by
|
8
8
|
# passing a created Net::SMTP object. This way we can get better performance to
|
9
9
|
# our local mail server by reducing the number of connections at any one time.
|
10
10
|
#
|
11
11
|
# === Sending via SMTP server on Localhost
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# To send mail open a connection with Net::Smtp using any options you like
|
14
14
|
# === Delivering the email
|
15
|
-
#
|
15
|
+
#
|
16
16
|
# Once you have the settings right, sending the email is done by:
|
17
17
|
#
|
18
18
|
# smtp_conn = Net::SMTP.start(settings[:address], settings[:port])
|
19
19
|
# Mail.defaults do
|
20
20
|
# delivery_method :smtp_connection, { :connection => smtp_conn }
|
21
21
|
# end
|
22
|
-
#
|
22
|
+
#
|
23
23
|
# Mail.deliver do
|
24
24
|
# to 'mikel@test.lindsaar.net'
|
25
25
|
# from 'ada@test.lindsaar.net'
|
26
26
|
# subject 'testing sendmail'
|
27
27
|
# body 'testing sendmail'
|
28
28
|
# end
|
29
|
-
#
|
29
|
+
#
|
30
30
|
# Or by calling deliver on a Mail message
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# mail = Mail.new do
|
33
33
|
# to 'mikel@test.lindsaar.net'
|
34
34
|
# from 'ada@test.lindsaar.net'
|
35
35
|
# subject 'testing sendmail'
|
36
36
|
# body 'testing sendmail'
|
37
37
|
# end
|
38
|
-
#
|
38
|
+
#
|
39
39
|
# mail.deliver!
|
40
40
|
class SMTPConnection
|
41
41
|
attr_accessor :smtp, :settings
|
@@ -4,7 +4,7 @@ require 'mail/smtp_envelope'
|
|
4
4
|
module Mail
|
5
5
|
# The TestMailer is a bare bones mailer that does nothing. It is useful
|
6
6
|
# when you are testing.
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# It also provides a template of the minimum methods you require to implement
|
9
9
|
# if you want to make a custom mailer for Mail
|
10
10
|
class TestMailer
|
@@ -14,11 +14,11 @@ module Mail
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# Allows you to over write the default deliveries store from an array to some
|
17
|
-
# other object. If you just want to clear the store,
|
17
|
+
# other object. If you just want to clear the store,
|
18
18
|
# call TestMailer.deliveries.clear.
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# If you place another object here, please make sure it responds to:
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# * << (message)
|
23
23
|
# * clear
|
24
24
|
# * length
|
@@ -17,7 +17,7 @@ module Mail
|
|
17
17
|
options[:count] ||= 1
|
18
18
|
find(options, &block)
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Get the most recent received email(s)
|
22
22
|
#
|
23
23
|
# Possible options:
|
@@ -30,7 +30,7 @@ module Mail
|
|
30
30
|
options[:count] ||= 1
|
31
31
|
find(options, &block)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Get all emails.
|
35
35
|
#
|
36
36
|
# Possible options:
|
@@ -42,7 +42,7 @@ module Mail
|
|
42
42
|
find(options, &block)
|
43
43
|
end
|
44
44
|
|
45
|
-
# Find emails in the mailbox, and then deletes them. Without any options, the
|
45
|
+
# Find emails in the mailbox, and then deletes them. Without any options, the
|
46
46
|
# five last received emails are returned.
|
47
47
|
#
|
48
48
|
# Possible options:
|
@@ -56,8 +56,8 @@ module Mail
|
|
56
56
|
def find_and_delete(options = nil, &block)
|
57
57
|
options = options ? Hash[options] : {}
|
58
58
|
options[:delete_after_find] ||= true
|
59
|
-
find(options, &block)
|
60
|
-
end
|
59
|
+
find(options, &block)
|
60
|
+
end
|
61
61
|
|
62
62
|
end
|
63
63
|
|
@@ -29,7 +29,7 @@ module Mail
|
|
29
29
|
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
30
30
|
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
31
31
|
# instance of Message, not an array of Message instances.
|
32
|
-
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
32
|
+
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
33
33
|
# or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
|
34
34
|
# The default is 'ALL'
|
35
35
|
#
|
@@ -38,7 +38,7 @@ module Mail
|
|
38
38
|
#
|
39
39
|
class IMAP < Retriever
|
40
40
|
require 'net/imap' unless defined?(Net::IMAP)
|
41
|
-
|
41
|
+
|
42
42
|
def initialize(values)
|
43
43
|
self.settings = { :address => "localhost",
|
44
44
|
:port => 143,
|
@@ -65,7 +65,7 @@ module Mail
|
|
65
65
|
# This is helpful when you don't want your messages to be set to read automatically. Default is false.
|
66
66
|
# delete_after_find: flag for whether to delete each retreived email after find. Default
|
67
67
|
# is false. Use #find_and_delete if you would like this to default to true.
|
68
|
-
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
68
|
+
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
69
69
|
# or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
|
70
70
|
# The default is 'ALL'
|
71
71
|
# search_charset: charset to pass to IMAP server search. Omitted by default. Example: 'UTF-8' or 'ASCII'.
|
@@ -75,7 +75,10 @@ module Mail
|
|
75
75
|
|
76
76
|
start do |imap|
|
77
77
|
options[:read_only] ? imap.examine(options[:mailbox]) : imap.select(options[:mailbox])
|
78
|
+
|
78
79
|
uids = imap.uid_search(options[:keys], options[:search_charset])
|
80
|
+
.to_a # older net-imap may return nil, newer may return ESearchResult struct
|
81
|
+
.sort # RFC3501 does _not_ require UIDs to be returned in order
|
79
82
|
uids.reverse! if options[:what].to_sym == :last
|
80
83
|
uids = uids.first(options[:count]) if options[:count].is_a?(Integer)
|
81
84
|
uids.reverse! if (options[:what].to_sym == :last && options[:order].to_sym == :asc) ||
|
@@ -6,9 +6,9 @@ module Mail
|
|
6
6
|
# Each email retrieved (RFC2822) is given as an instance of +Message+.
|
7
7
|
#
|
8
8
|
# While being retrieved, emails can be yielded if a block is given.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# === Example of retrieving Emails from GMail:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Mail.defaults do
|
13
13
|
# retriever_method :pop3, { :address => "pop.gmail.com",
|
14
14
|
# :port => 995,
|
@@ -16,22 +16,22 @@ module Mail
|
|
16
16
|
# :password => '<password>',
|
17
17
|
# :enable_ssl => true }
|
18
18
|
# end
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# Mail.all #=> Returns an array of all emails
|
21
21
|
# Mail.first #=> Returns the first unread email
|
22
22
|
# Mail.last #=> Returns the last unread email
|
23
|
-
#
|
23
|
+
#
|
24
24
|
# You can also pass options into Mail.find to locate an email in your pop mailbox
|
25
25
|
# with the following options:
|
26
|
-
#
|
26
|
+
#
|
27
27
|
# what: last or first emails. The default is :first.
|
28
28
|
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
29
29
|
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
30
30
|
# instance of Message, not an array of Message instances.
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# Mail.find(:what => :first, :count => 10, :order => :asc)
|
33
33
|
# #=> Returns the first 10 emails in ascending order
|
34
|
-
#
|
34
|
+
#
|
35
35
|
class POP3 < Retriever
|
36
36
|
require 'net/pop' unless defined?(Net::POP)
|
37
37
|
|
@@ -44,9 +44,9 @@ module Mail
|
|
44
44
|
:enable_ssl => false,
|
45
45
|
:read_timeout => nil }.merge!(values)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
attr_accessor :settings
|
49
|
-
|
49
|
+
|
50
50
|
# Find emails in a POP3 mailbox. Without any options, the 5 last received emails are returned.
|
51
51
|
#
|
52
52
|
# Possible options:
|
@@ -59,18 +59,18 @@ module Mail
|
|
59
59
|
#
|
60
60
|
def find(options = nil, &block)
|
61
61
|
options = validate_options(options)
|
62
|
-
|
62
|
+
|
63
63
|
start do |pop3|
|
64
64
|
mails = pop3.mails
|
65
65
|
pop3.reset # Clears all "deleted" marks. This prevents non-explicit/accidental deletions due to server settings.
|
66
66
|
mails.sort! { |m1, m2| m2.number <=> m1.number } if options[:what] == :last
|
67
67
|
mails = mails.first(options[:count]) if options[:count].is_a? Integer
|
68
|
-
|
68
|
+
|
69
69
|
if options[:what].to_sym == :last && options[:order].to_sym == :desc ||
|
70
70
|
options[:what].to_sym == :first && options[:order].to_sym == :asc ||
|
71
71
|
mails.reverse!
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
if block_given?
|
75
75
|
mails.each do |mail|
|
76
76
|
new_message = Mail.new(mail.pop)
|
@@ -86,11 +86,11 @@ module Mail
|
|
86
86
|
end
|
87
87
|
emails.size == 1 && options[:count] == 1 ? emails.first : emails
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
93
|
-
# Delete all emails from a POP3 server
|
92
|
+
|
93
|
+
# Delete all emails from a POP3 server
|
94
94
|
def delete_all
|
95
95
|
start do |pop3|
|
96
96
|
unless pop3.mails.empty?
|
@@ -108,9 +108,9 @@ module Mail
|
|
108
108
|
yield pop3
|
109
109
|
end
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
private
|
113
|
-
|
113
|
+
|
114
114
|
# Set default options
|
115
115
|
def validate_options(options)
|
116
116
|
options = options ? Hash[options] : {}
|
@@ -120,18 +120,18 @@ module Mail
|
|
120
120
|
options[:delete_after_find] ||= false
|
121
121
|
options
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
# Start a POP3 session and ensure that it will be closed in any case. Any messages
|
125
125
|
# marked for deletion via #find_and_delete or with the :delete_after_find option
|
126
126
|
# will be deleted when the session is closed.
|
127
127
|
def start(config = Configuration.instance, &block)
|
128
128
|
raise ArgumentError.new("Mail::Retrievable#pop3_start takes a block") unless block_given?
|
129
|
-
|
129
|
+
|
130
130
|
pop3 = Net::POP3.new(settings[:address], settings[:port], false)
|
131
131
|
pop3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if settings[:enable_ssl]
|
132
132
|
pop3.read_timeout = settings[:read_timeout] if settings[:read_timeout]
|
133
133
|
pop3.start(settings[:user_name], settings[:password])
|
134
|
-
|
134
|
+
|
135
135
|
yield pop3
|
136
136
|
ensure
|
137
137
|
if defined?(pop3) && pop3 && pop3.started?
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
require "mail/utilities"
|
4
3
|
require "mail/parser_tools"
|
@@ -32011,10 +32010,10 @@ begin
|
|
32011
32010
|
_trans = if (_slen > 0 &&
|
32012
32011
|
_trans_keys[_keys] <= _wide &&
|
32013
32012
|
_wide <= _trans_keys[_keys + 1])
|
32014
|
-
|
32015
|
-
|
32016
|
-
|
32017
|
-
|
32013
|
+
_indicies[_inds + _wide - _trans_keys[_keys]]
|
32014
|
+
else
|
32015
|
+
_indicies[_inds + _slen]
|
32016
|
+
end
|
32018
32017
|
cs = _trans_targs[_trans]
|
32019
32018
|
if _trans_actions[_trans] != 0
|
32020
32019
|
case _trans_actions[_trans]
|
@@ -33229,6 +33228,10 @@ begin
|
|
33229
33228
|
end
|
33230
33229
|
end
|
33231
33230
|
|
33231
|
+
if false
|
33232
|
+
testEof
|
33233
|
+
end
|
33234
|
+
|
33232
33235
|
if p != eof || cs < 2461
|
33233
33236
|
raise Mail::Field::IncompleteParseError.new(Mail::AddressList, data, p)
|
33234
33237
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
require "mail/utilities"
|
4
3
|
require "mail/parser_tools"
|
@@ -610,10 +609,10 @@ begin
|
|
610
609
|
_trans = if (_slen > 0 &&
|
611
610
|
_trans_keys[_keys] <= _wide &&
|
612
611
|
_wide <= _trans_keys[_keys + 1])
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
612
|
+
_indicies[_inds + _wide - _trans_keys[_keys]]
|
613
|
+
else
|
614
|
+
_indicies[_inds + _slen]
|
615
|
+
end
|
617
616
|
cs = _trans_targs[_trans]
|
618
617
|
if _trans_actions[_trans] != 0
|
619
618
|
case _trans_actions[_trans]
|
@@ -654,7 +653,7 @@ begin
|
|
654
653
|
# Use quoted string value if one exists, otherwise use parameter value
|
655
654
|
value = qstr || chars(data, param_val_s, p - 1)
|
656
655
|
|
657
|
-
content_disposition.parameters << {param_attr => value}
|
656
|
+
content_disposition.parameters << { param_attr => value }
|
658
657
|
param_attr = nil
|
659
658
|
qstr = nil
|
660
659
|
end
|
@@ -712,7 +711,7 @@ begin
|
|
712
711
|
# Use quoted string value if one exists, otherwise use parameter value
|
713
712
|
value = qstr || chars(data, param_val_s, p - 1)
|
714
713
|
|
715
|
-
content_disposition.parameters << {param_attr => value}
|
714
|
+
content_disposition.parameters << { param_attr => value }
|
716
715
|
param_attr = nil
|
717
716
|
qstr = nil
|
718
717
|
end
|
@@ -742,7 +741,7 @@ begin
|
|
742
741
|
# Use quoted string value if one exists, otherwise use parameter value
|
743
742
|
value = qstr || chars(data, param_val_s, p - 1)
|
744
743
|
|
745
|
-
content_disposition.parameters << {param_attr => value}
|
744
|
+
content_disposition.parameters << { param_attr => value }
|
746
745
|
param_attr = nil
|
747
746
|
qstr = nil
|
748
747
|
end
|
@@ -799,7 +798,7 @@ begin
|
|
799
798
|
# Use quoted string value if one exists, otherwise use parameter value
|
800
799
|
value = qstr || chars(data, param_val_s, p - 1)
|
801
800
|
|
802
|
-
content_disposition.parameters << {param_attr => value}
|
801
|
+
content_disposition.parameters << { param_attr => value }
|
803
802
|
param_attr = nil
|
804
803
|
qstr = nil
|
805
804
|
end
|
@@ -823,7 +822,7 @@ begin
|
|
823
822
|
# Use quoted string value if one exists, otherwise use parameter value
|
824
823
|
value = qstr || chars(data, param_val_s, p - 1)
|
825
824
|
|
826
|
-
content_disposition.parameters << {param_attr => value}
|
825
|
+
content_disposition.parameters << { param_attr => value }
|
827
826
|
param_attr = nil
|
828
827
|
qstr = nil
|
829
828
|
end
|
@@ -857,7 +856,7 @@ begin
|
|
857
856
|
# Use quoted string value if one exists, otherwise use parameter value
|
858
857
|
value = qstr || chars(data, param_val_s, p - 1)
|
859
858
|
|
860
|
-
content_disposition.parameters << {param_attr => value}
|
859
|
+
content_disposition.parameters << { param_attr => value }
|
861
860
|
param_attr = nil
|
862
861
|
qstr = nil
|
863
862
|
end
|
@@ -875,7 +874,7 @@ begin
|
|
875
874
|
# Use quoted string value if one exists, otherwise use parameter value
|
876
875
|
value = qstr || chars(data, param_val_s, p - 1)
|
877
876
|
|
878
|
-
content_disposition.parameters << {param_attr => value}
|
877
|
+
content_disposition.parameters << { param_attr => value }
|
879
878
|
param_attr = nil
|
880
879
|
qstr = nil
|
881
880
|
end
|
@@ -888,6 +887,10 @@ begin
|
|
888
887
|
end
|
889
888
|
end
|
890
889
|
|
890
|
+
if false
|
891
|
+
testEof
|
892
|
+
end
|
893
|
+
|
891
894
|
if p != eof || cs < 40
|
892
895
|
raise Mail::Field::IncompleteParseError.new(Mail::ContentDispositionElement, data, p)
|
893
896
|
end
|