mail 2.6.3 → 2.6.4.rc1
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/CHANGELOG.rdoc +22 -0
- data/Gemfile +1 -4
- data/MIT-LICENSE +1 -1
- data/README.md +38 -2
- data/Rakefile +2 -2
- data/lib/mail.rb +8 -2
- data/lib/mail/body.rb +4 -4
- data/lib/mail/check_delivery_params.rb +3 -3
- data/lib/mail/constants.rb +2 -1
- data/lib/mail/core_extensions/nil.rb +0 -6
- data/lib/mail/core_extensions/string.rb +0 -6
- data/lib/mail/elements/address.rb +7 -7
- data/lib/mail/encodings.rb +25 -28
- data/lib/mail/encodings/8bit.rb +5 -0
- data/lib/mail/encodings/base64.rb +5 -0
- data/lib/mail/encodings/quoted_printable.rb +6 -1
- data/lib/mail/encodings/transfer_encoding.rb +26 -17
- data/lib/mail/field.rb +18 -4
- data/lib/mail/fields/bcc_field.rb +14 -3
- data/lib/mail/fields/cc_field.rb +0 -1
- data/lib/mail/fields/common/common_address.rb +7 -7
- data/lib/mail/fields/common/common_date.rb +1 -1
- data/lib/mail/fields/common/common_field.rb +1 -1
- data/lib/mail/fields/common/common_message_id.rb +2 -2
- data/lib/mail/fields/content_disposition_field.rb +11 -11
- data/lib/mail/fields/content_id_field.rb +2 -2
- data/lib/mail/fields/content_location_field.rb +1 -1
- data/lib/mail/fields/content_transfer_encoding_field.rb +1 -1
- data/lib/mail/fields/content_type_field.rb +1 -1
- data/lib/mail/fields/date_field.rb +1 -1
- data/lib/mail/fields/from_field.rb +0 -1
- data/lib/mail/fields/keywords_field.rb +1 -2
- data/lib/mail/fields/message_id_field.rb +1 -1
- data/lib/mail/fields/mime_version_field.rb +2 -2
- data/lib/mail/fields/received_field.rb +3 -3
- 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 +1 -1
- data/lib/mail/fields/resent_from_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/to_field.rb +0 -1
- data/lib/mail/fields/unstructured_field.rb +1 -1
- data/lib/mail/header.rb +3 -3
- data/lib/mail/matchers/attachment_matchers.rb +28 -0
- data/lib/mail/matchers/has_sent_mail.rb +30 -7
- data/lib/mail/message.rb +15 -21
- data/lib/mail/multibyte/unicode.rb +20 -16
- data/lib/mail/parsers/address_lists_parser.rb +1 -1
- data/lib/mail/parsers/content_disposition_parser.rb +1 -1
- data/lib/mail/parsers/content_location_parser.rb +1 -1
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +1 -1
- data/lib/mail/parsers/envelope_from_parser.rb +1 -1
- data/lib/mail/parsers/message_ids_parser.rb +1 -1
- data/lib/mail/parsers/mime_version_parser.rb +1 -1
- data/lib/mail/part.rb +4 -2
- data/lib/mail/parts_list.rb +25 -8
- data/lib/mail/utilities.rb +15 -0
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +2 -2
- data/lib/mail/version_specific/ruby_1_8.rb +10 -4
- data/lib/mail/version_specific/ruby_1_9.rb +39 -10
- metadata +8 -8
- data/lib/mail/core_extensions/object.rb +0 -13
data/lib/mail/fields/to_field.rb
CHANGED
data/lib/mail/header.rb
CHANGED
@@ -136,7 +136,7 @@ module Mail
|
|
136
136
|
case
|
137
137
|
when selected.length > 1
|
138
138
|
selected.map { |f| f }
|
139
|
-
when !
|
139
|
+
when !Utilities.blank?(selected)
|
140
140
|
selected.first
|
141
141
|
else
|
142
142
|
nil
|
@@ -166,11 +166,11 @@ module Mail
|
|
166
166
|
|
167
167
|
case
|
168
168
|
# User wants to delete the field
|
169
|
-
when !
|
169
|
+
when !Utilities.blank?(selected) && value == nil
|
170
170
|
fields.delete_if { |f| selected.include?(f) }
|
171
171
|
|
172
172
|
# User wants to change the field
|
173
|
-
when !
|
173
|
+
when !Utilities.blank?(selected) && limited_field?(fn)
|
174
174
|
selected.first.update(fn, value)
|
175
175
|
|
176
176
|
# User wants to create the field
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Mail
|
2
|
+
module Matchers
|
3
|
+
def any_attachment
|
4
|
+
AnyAttachmentMatcher.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def an_attachment_with_filename(filename)
|
8
|
+
AttachmentFilenameMatcher.new(filename)
|
9
|
+
end
|
10
|
+
|
11
|
+
class AnyAttachmentMatcher
|
12
|
+
def ===(other)
|
13
|
+
other.attachment?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class AttachmentFilenameMatcher
|
18
|
+
attr_reader :filename
|
19
|
+
def initialize(filename)
|
20
|
+
@filename = filename
|
21
|
+
end
|
22
|
+
|
23
|
+
def ===(other)
|
24
|
+
other.attachment? && other.filename == filename
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -42,15 +42,25 @@ module Mail
|
|
42
42
|
|
43
43
|
def bcc(recipient_or_list)
|
44
44
|
@blind_copy_recipients ||= []
|
45
|
+
@blind_copy_recipients.concat(Array(recipient_or_list))
|
46
|
+
self
|
47
|
+
end
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def with_attachments(attachments)
|
50
|
+
@attachments ||= []
|
51
|
+
@attachments.concat(Array(attachments))
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def with_no_attachments
|
56
|
+
@having_attachments = false
|
51
57
|
self
|
52
58
|
end
|
53
59
|
|
60
|
+
def with_any_attachments
|
61
|
+
@having_attachments = true
|
62
|
+
self
|
63
|
+
end
|
54
64
|
|
55
65
|
def with_subject(subject)
|
56
66
|
@subject = subject
|
@@ -95,8 +105,10 @@ module Mail
|
|
95
105
|
|
96
106
|
def filter_matched_deliveries(deliveries)
|
97
107
|
candidate_deliveries = deliveries
|
98
|
-
|
99
|
-
|
108
|
+
modifiers =
|
109
|
+
%w(sender recipients copy_recipients blind_copy_recipients subject
|
110
|
+
subject_matcher body body_matcher having_attachments attachments)
|
111
|
+
modifiers.each do |modifier_name|
|
100
112
|
next unless instance_variable_defined?("@#{modifier_name}")
|
101
113
|
candidate_deliveries = candidate_deliveries.select{|matching_delivery| self.send("matches_on_#{modifier_name}?", matching_delivery)}
|
102
114
|
end
|
@@ -128,6 +140,17 @@ module Mail
|
|
128
140
|
@subject_matcher.match delivery.subject
|
129
141
|
end
|
130
142
|
|
143
|
+
def matches_on_having_attachments?(delivery)
|
144
|
+
@having_attachments && delivery.attachments.any? ||
|
145
|
+
(!@having_attachments && delivery.attachments.none?)
|
146
|
+
end
|
147
|
+
|
148
|
+
def matches_on_attachments?(delivery)
|
149
|
+
@attachments.each_with_index.inject( true ) do |sent_attachments, (attachment, index)|
|
150
|
+
sent_attachments &&= (attachment === delivery.attachments[index])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
131
154
|
def matches_on_body?(delivery)
|
132
155
|
delivery.body == @body
|
133
156
|
end
|
data/lib/mail/message.rb
CHANGED
@@ -1415,7 +1415,7 @@ module Mail
|
|
1415
1415
|
end
|
1416
1416
|
|
1417
1417
|
def has_content_transfer_encoding?
|
1418
|
-
header[:content_transfer_encoding] && header[:content_transfer_encoding].errors
|
1418
|
+
header[:content_transfer_encoding] && Utilities.blank?(header[:content_transfer_encoding].errors)
|
1419
1419
|
end
|
1420
1420
|
|
1421
1421
|
def has_transfer_encoding? # :nodoc:
|
@@ -1669,6 +1669,8 @@ module Mail
|
|
1669
1669
|
def html_part=(msg)
|
1670
1670
|
# Assign the html part and set multipart/alternative if there's a text part.
|
1671
1671
|
if msg
|
1672
|
+
msg = Mail::Part.new(:body => msg) unless msg.kind_of?(Mail::Message)
|
1673
|
+
|
1672
1674
|
@html_part = msg
|
1673
1675
|
@html_part.content_type = 'text/html' unless @html_part.has_content_type?
|
1674
1676
|
add_multipart_alternate_header if text_part
|
@@ -1691,6 +1693,8 @@ module Mail
|
|
1691
1693
|
def text_part=(msg)
|
1692
1694
|
# Assign the text part and set multipart/alternative if there's an html part.
|
1693
1695
|
if msg
|
1696
|
+
msg = Mail::Part.new(:body => msg) unless msg.kind_of?(Mail::Message)
|
1697
|
+
|
1694
1698
|
@text_part = msg
|
1695
1699
|
@text_part.content_type = 'text/plain' unless @text_part.has_content_type?
|
1696
1700
|
add_multipart_alternate_header if html_part
|
@@ -1709,7 +1713,7 @@ module Mail
|
|
1709
1713
|
|
1710
1714
|
# Adds a part to the parts list or creates the part list
|
1711
1715
|
def add_part(part)
|
1712
|
-
if !body.multipart? && !self.body.decoded
|
1716
|
+
if !body.multipart? && !Utilities.blank?(self.body.decoded)
|
1713
1717
|
@text_part = Mail::Part.new('Content-Type: text/plain;')
|
1714
1718
|
@text_part.body = body.decoded
|
1715
1719
|
self.body << @text_part
|
@@ -1765,14 +1769,17 @@ module Mail
|
|
1765
1769
|
#
|
1766
1770
|
# See also #attachments
|
1767
1771
|
def add_file(values)
|
1768
|
-
convert_to_multipart unless self.multipart? || self.body.decoded
|
1772
|
+
convert_to_multipart unless self.multipart? || Utilities.blank?(self.body.decoded)
|
1769
1773
|
add_multipart_mixed_header
|
1770
1774
|
if values.is_a?(String)
|
1771
1775
|
basename = File.basename(values)
|
1772
1776
|
filedata = File.open(values, 'rb') { |f| f.read }
|
1773
1777
|
else
|
1774
1778
|
basename = values[:filename]
|
1775
|
-
filedata = values
|
1779
|
+
filedata = values
|
1780
|
+
unless filedata[:content]
|
1781
|
+
filedata = values.merge(:content=>File.open(values[:filename], 'rb') { |f| f.read })
|
1782
|
+
end
|
1776
1783
|
end
|
1777
1784
|
self.attachments[basename] = filedata
|
1778
1785
|
end
|
@@ -1857,7 +1864,7 @@ module Mail
|
|
1857
1864
|
case
|
1858
1865
|
when k == 'delivery_handler'
|
1859
1866
|
begin
|
1860
|
-
m.delivery_handler = Object.const_get(v) unless
|
1867
|
+
m.delivery_handler = Object.const_get(v) unless Utilities.blank?(v)
|
1861
1868
|
rescue NameError
|
1862
1869
|
end
|
1863
1870
|
when k == 'transport_encoding'
|
@@ -2020,7 +2027,7 @@ module Mail
|
|
2020
2027
|
raw_string = raw_source.to_s
|
2021
2028
|
if match_data = raw_source.to_s.match(/\AFrom\s(#{TEXT}+)#{CRLF}/m)
|
2022
2029
|
set_envelope(match_data[1])
|
2023
|
-
self.raw_source = raw_string.sub(match_data[0], "")
|
2030
|
+
self.raw_source = raw_string.sub(match_data[0], "")
|
2024
2031
|
end
|
2025
2032
|
end
|
2026
2033
|
|
@@ -2046,7 +2053,7 @@ module Mail
|
|
2046
2053
|
add_required_message_fields
|
2047
2054
|
add_multipart_mixed_header if body.multipart?
|
2048
2055
|
add_content_type unless has_content_type?
|
2049
|
-
add_charset
|
2056
|
+
add_charset if text? && !has_charset?
|
2050
2057
|
add_content_transfer_encoding unless has_content_transfer_encoding?
|
2051
2058
|
end
|
2052
2059
|
|
@@ -2146,20 +2153,7 @@ module Mail
|
|
2146
2153
|
end
|
2147
2154
|
|
2148
2155
|
def decode_body_as_text
|
2149
|
-
|
2150
|
-
if charset
|
2151
|
-
if RUBY_VERSION < '1.9'
|
2152
|
-
require 'iconv'
|
2153
|
-
return Iconv.conv("UTF-8//TRANSLIT//IGNORE", charset, body_text)
|
2154
|
-
else
|
2155
|
-
if encoding = Encoding.find(charset) rescue nil
|
2156
|
-
body_text.force_encoding(encoding)
|
2157
|
-
return body_text.encode(Encoding::UTF_8, :undef => :replace, :invalid => :replace, :replace => '')
|
2158
|
-
end
|
2159
|
-
end
|
2160
|
-
end
|
2161
|
-
body_text
|
2156
|
+
Encodings.transcode_charset decode_body, charset, 'UTF-8'
|
2162
2157
|
end
|
2163
|
-
|
2164
2158
|
end
|
2165
2159
|
end
|
@@ -1,6 +1,26 @@
|
|
1
1
|
module Mail
|
2
2
|
module Multibyte
|
3
3
|
module Unicode
|
4
|
+
# Adapted from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/multibyte/unicode.rb
|
5
|
+
# under the MIT license
|
6
|
+
# The Unicode version that is supported by the implementation
|
7
|
+
UNICODE_VERSION = '7.0.0'
|
8
|
+
|
9
|
+
# Holds data about a codepoint in the Unicode database.
|
10
|
+
class Codepoint
|
11
|
+
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
|
12
|
+
|
13
|
+
# Initializing Codepoint object with default values
|
14
|
+
def initialize
|
15
|
+
@combining_class = 0
|
16
|
+
@uppercase_mapping = 0
|
17
|
+
@lowercase_mapping = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def swapcase_mapping
|
21
|
+
uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
|
22
|
+
end
|
23
|
+
end
|
4
24
|
|
5
25
|
extend self
|
6
26
|
|
@@ -8,9 +28,6 @@ module Mail
|
|
8
28
|
# information about normalization.
|
9
29
|
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
10
30
|
|
11
|
-
# The Unicode version that is supported by the implementation
|
12
|
-
UNICODE_VERSION = '5.2.0'
|
13
|
-
|
14
31
|
# The default normalization used for operations that require normalization. It can be set to any of the
|
15
32
|
# normalizations in NORMALIZATION_FORMS.
|
16
33
|
#
|
@@ -308,11 +325,6 @@ module Mail
|
|
308
325
|
end.pack('U*')
|
309
326
|
end
|
310
327
|
|
311
|
-
# Holds data about a codepoint in the Unicode database
|
312
|
-
class Codepoint
|
313
|
-
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
|
314
|
-
end
|
315
|
-
|
316
328
|
# Holds static data from the Unicode database
|
317
329
|
class UnicodeDatabase
|
318
330
|
ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
|
@@ -390,11 +402,3 @@ module Mail
|
|
390
402
|
end
|
391
403
|
end
|
392
404
|
end
|
393
|
-
|
394
|
-
unless defined?(ActiveSupport)
|
395
|
-
module ActiveSupport
|
396
|
-
unless const_defined?(:Multibyte)
|
397
|
-
Multibyte = Mail::Multibyte
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
data/lib/mail/part.rb
CHANGED
@@ -34,7 +34,7 @@ module Mail
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def inline?
|
37
|
-
header[:content_disposition].disposition_type == 'inline' if header[:content_disposition]
|
37
|
+
header[:content_disposition].disposition_type == 'inline' if header[:content_disposition].respond_to?(:disposition_type)
|
38
38
|
end
|
39
39
|
|
40
40
|
def add_required_fields
|
@@ -94,8 +94,10 @@ module Mail
|
|
94
94
|
def get_return_values(key)
|
95
95
|
if delivery_status_data[key].is_a?(Array)
|
96
96
|
delivery_status_data[key].map { |a| a.value }
|
97
|
-
|
97
|
+
elsif !delivery_status_data[key].nil?
|
98
98
|
delivery_status_data[key].value
|
99
|
+
else
|
100
|
+
nil
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|