mail 2.7.1 → 2.9.1
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 +135 -59
- data/lib/mail/attachments_list.rb +5 -6
- data/lib/mail/body.rb +51 -74
- data/lib/mail/constants.rb +27 -5
- data/lib/mail/elements/address.rb +27 -27
- data/lib/mail/elements/address_list.rb +1 -1
- data/lib/mail/elements/content_disposition_element.rb +1 -1
- data/lib/mail/elements/content_location_element.rb +1 -1
- data/lib/mail/elements/content_transfer_encoding_element.rb +1 -1
- data/lib/mail/elements/content_type_element.rb +8 -4
- data/lib/mail/elements/date_time_element.rb +1 -1
- data/lib/mail/elements/envelope_from_element.rb +13 -7
- data/lib/mail/elements/message_ids_element.rb +14 -5
- data/lib/mail/elements/mime_version_element.rb +1 -1
- data/lib/mail/elements/phrase_list.rb +7 -2
- data/lib/mail/elements/received_element.rb +20 -6
- data/lib/mail/encodings/7bit.rb +5 -0
- data/lib/mail/encodings/base64.rb +2 -2
- data/lib/mail/encodings/quoted_printable.rb +2 -2
- data/lib/mail/encodings/unix_to_unix.rb +1 -1
- data/lib/mail/encodings.rb +32 -61
- data/lib/mail/envelope.rb +11 -14
- data/lib/mail/field.rb +100 -86
- data/lib/mail/field_list.rb +61 -8
- data/lib/mail/fields/bcc_field.rb +33 -52
- data/lib/mail/fields/cc_field.rb +27 -49
- data/lib/mail/fields/comments_field.rb +26 -37
- data/lib/mail/fields/common_address_field.rb +162 -0
- data/lib/mail/fields/common_date_field.rb +56 -0
- data/lib/mail/fields/common_field.rb +77 -0
- data/lib/mail/fields/common_message_id_field.rb +41 -0
- data/lib/mail/fields/content_description_field.rb +6 -14
- data/lib/mail/fields/content_disposition_field.rb +11 -38
- data/lib/mail/fields/content_id_field.rb +23 -51
- data/lib/mail/fields/content_location_field.rb +10 -25
- data/lib/mail/fields/content_transfer_encoding_field.rb +30 -31
- data/lib/mail/fields/content_type_field.rb +49 -75
- data/lib/mail/fields/date_field.rb +22 -51
- data/lib/mail/fields/from_field.rb +27 -49
- data/lib/mail/fields/in_reply_to_field.rb +37 -49
- data/lib/mail/fields/keywords_field.rb +17 -31
- data/lib/mail/fields/message_id_field.rb +24 -71
- data/lib/mail/fields/mime_version_field.rb +18 -30
- data/lib/mail/fields/named_structured_field.rb +10 -0
- data/lib/mail/fields/named_unstructured_field.rb +10 -0
- data/lib/mail/fields/optional_field.rb +5 -7
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +12 -10
- data/lib/mail/fields/received_field.rb +42 -57
- data/lib/mail/fields/references_field.rb +34 -49
- data/lib/mail/fields/reply_to_field.rb +27 -49
- data/lib/mail/fields/resent_bcc_field.rb +27 -49
- data/lib/mail/fields/resent_cc_field.rb +27 -49
- data/lib/mail/fields/resent_date_field.rb +4 -29
- data/lib/mail/fields/resent_from_field.rb +27 -49
- data/lib/mail/fields/resent_message_id_field.rb +4 -29
- data/lib/mail/fields/resent_sender_field.rb +26 -56
- data/lib/mail/fields/resent_to_field.rb +27 -49
- data/lib/mail/fields/return_path_field.rb +49 -54
- data/lib/mail/fields/sender_field.rb +33 -55
- data/lib/mail/fields/structured_field.rb +2 -30
- data/lib/mail/fields/subject_field.rb +8 -11
- data/lib/mail/fields/to_field.rb +27 -49
- data/lib/mail/fields/unstructured_field.rb +15 -48
- data/lib/mail/fields.rb +9 -0
- data/lib/mail/header.rb +69 -110
- data/lib/mail/mail.rb +32 -27
- data/lib/mail/matchers/attachment_matchers.rb +15 -0
- data/lib/mail/message.rb +67 -78
- data/lib/mail/multibyte/chars.rb +9 -167
- data/lib/mail/multibyte/unicode.rb +1 -1
- data/lib/mail/multibyte/utils.rb +26 -43
- data/lib/mail/multibyte.rb +1 -11
- data/lib/mail/network/delivery_methods/exim.rb +5 -4
- data/lib/mail/network/delivery_methods/file_delivery.rb +13 -12
- data/lib/mail/network/delivery_methods/logger_delivery.rb +2 -5
- data/lib/mail/network/delivery_methods/sendmail.rb +27 -35
- data/lib/mail/network/delivery_methods/smtp.rb +81 -30
- data/lib/mail/network/delivery_methods/smtp_connection.rb +10 -19
- data/lib/mail/network/delivery_methods/test_mailer.rb +8 -6
- data/lib/mail/network/retriever_methods/base.rb +13 -13
- data/lib/mail/network/retriever_methods/imap.rb +8 -5
- data/lib/mail/network/retriever_methods/pop3.rb +22 -22
- data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
- data/lib/mail/parsers/address_lists_parser.rb +33073 -33064
- data/lib/mail/parsers/address_lists_parser.rl +11 -0
- data/lib/mail/parsers/content_disposition_parser.rb +837 -828
- data/lib/mail/parsers/content_disposition_parser.rl +11 -0
- data/lib/mail/parsers/content_location_parser.rb +773 -764
- data/lib/mail/parsers/content_location_parser.rl +12 -1
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +477 -468
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +11 -0
- data/lib/mail/parsers/content_type_parser.rb +974 -965
- data/lib/mail/parsers/content_type_parser.rl +11 -0
- data/lib/mail/parsers/date_time_parser.rb +841 -832
- data/lib/mail/parsers/date_time_parser.rl +11 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3627 -3530
- data/lib/mail/parsers/envelope_from_parser.rl +11 -0
- data/lib/mail/parsers/message_ids_parser.rb +5110 -2800
- data/lib/mail/parsers/message_ids_parser.rl +16 -1
- data/lib/mail/parsers/mime_version_parser.rb +466 -457
- data/lib/mail/parsers/mime_version_parser.rl +11 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +839 -830
- data/lib/mail/parsers/phrase_lists_parser.rl +12 -1
- data/lib/mail/parsers/received_parser.rb +8692 -8683
- data/lib/mail/parsers/received_parser.rl +11 -0
- data/lib/mail/parsers/rfc5322.rl +28 -13
- data/lib/mail/parsers.rb +11 -17
- data/lib/mail/part.rb +24 -28
- data/lib/mail/parts_list.rb +57 -0
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +321 -69
- data/lib/mail/version.rb +1 -1
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +2 -22
- metadata +83 -19
- data/lib/mail/check_delivery_params.rb +0 -60
- data/lib/mail/core_extensions/smtp.rb +0 -28
- data/lib/mail/core_extensions/string.rb +0 -17
- data/lib/mail/fields/common/address_container.rb +0 -17
- data/lib/mail/fields/common/common_address.rb +0 -161
- data/lib/mail/fields/common/common_date.rb +0 -36
- data/lib/mail/fields/common/common_field.rb +0 -52
- data/lib/mail/fields/common/common_message_id.rb +0 -49
- data/lib/mail/version_specific/ruby_1_8.rb +0 -163
- data/lib/mail/version_specific/ruby_1_9.rb +0 -278
data/lib/mail/field.rb
CHANGED
|
@@ -23,8 +23,6 @@ module Mail
|
|
|
23
23
|
# sections 3 and 4 of this standard.
|
|
24
24
|
#
|
|
25
25
|
class Field
|
|
26
|
-
|
|
27
|
-
include Utilities
|
|
28
26
|
include Comparable
|
|
29
27
|
|
|
30
28
|
STRUCTURED_FIELDS = %w[ bcc cc content-description content-disposition
|
|
@@ -38,40 +36,68 @@ module Mail
|
|
|
38
36
|
KNOWN_FIELDS = STRUCTURED_FIELDS + ['comments', 'subject']
|
|
39
37
|
|
|
40
38
|
FIELDS_MAP = {
|
|
41
|
-
"to" => ToField,
|
|
42
|
-
"cc" => CcField,
|
|
43
|
-
"bcc" => BccField,
|
|
44
|
-
"message-id" => MessageIdField,
|
|
45
|
-
"in-reply-to" => InReplyToField,
|
|
46
|
-
"references" => ReferencesField,
|
|
47
|
-
"subject" => SubjectField,
|
|
48
|
-
"comments" => CommentsField,
|
|
49
|
-
"keywords" => KeywordsField,
|
|
50
|
-
"date" => DateField,
|
|
51
|
-
"from" => FromField,
|
|
52
|
-
"sender" => SenderField,
|
|
53
|
-
"reply-to" => ReplyToField,
|
|
54
|
-
"resent-date" => ResentDateField,
|
|
55
|
-
"resent-from" => ResentFromField,
|
|
56
|
-
"resent-sender" =>
|
|
57
|
-
"resent-to" => ResentToField,
|
|
58
|
-
"resent-cc" => ResentCcField,
|
|
59
|
-
"resent-bcc" => ResentBccField,
|
|
60
|
-
"resent-message-id" => ResentMessageIdField,
|
|
61
|
-
"return-path" => ReturnPathField,
|
|
62
|
-
"received" => ReceivedField,
|
|
63
|
-
"mime-version" => MimeVersionField,
|
|
64
|
-
"content-transfer-encoding" => ContentTransferEncodingField,
|
|
65
|
-
"content-description" => ContentDescriptionField,
|
|
66
|
-
"content-disposition" => ContentDispositionField,
|
|
67
|
-
"content-type" => ContentTypeField,
|
|
68
|
-
"content-id" => ContentIdField,
|
|
69
|
-
"content-location" => ContentLocationField,
|
|
39
|
+
"to" => "ToField",
|
|
40
|
+
"cc" => "CcField",
|
|
41
|
+
"bcc" => "BccField",
|
|
42
|
+
"message-id" => "MessageIdField",
|
|
43
|
+
"in-reply-to" => "InReplyToField",
|
|
44
|
+
"references" => "ReferencesField",
|
|
45
|
+
"subject" => "SubjectField",
|
|
46
|
+
"comments" => "CommentsField",
|
|
47
|
+
"keywords" => "KeywordsField",
|
|
48
|
+
"date" => "DateField",
|
|
49
|
+
"from" => "FromField",
|
|
50
|
+
"sender" => "SenderField",
|
|
51
|
+
"reply-to" => "ReplyToField",
|
|
52
|
+
"resent-date" => "ResentDateField",
|
|
53
|
+
"resent-from" => "ResentFromField",
|
|
54
|
+
"resent-sender" => "ResentSenderField",
|
|
55
|
+
"resent-to" => "ResentToField",
|
|
56
|
+
"resent-cc" => "ResentCcField",
|
|
57
|
+
"resent-bcc" => "ResentBccField",
|
|
58
|
+
"resent-message-id" => "ResentMessageIdField",
|
|
59
|
+
"return-path" => "ReturnPathField",
|
|
60
|
+
"received" => "ReceivedField",
|
|
61
|
+
"mime-version" => "MimeVersionField",
|
|
62
|
+
"content-transfer-encoding" => "ContentTransferEncodingField",
|
|
63
|
+
"content-description" => "ContentDescriptionField",
|
|
64
|
+
"content-disposition" => "ContentDispositionField",
|
|
65
|
+
"content-type" => "ContentTypeField",
|
|
66
|
+
"content-id" => "ContentIdField",
|
|
67
|
+
"content-location" => "ContentLocationField",
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
FIELD_NAME_MAP =
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
FIELD_NAME_MAP = {
|
|
71
|
+
"to" => "To",
|
|
72
|
+
"cc" => "Cc",
|
|
73
|
+
"bcc" => "Bcc",
|
|
74
|
+
"message-id" => "Message-ID",
|
|
75
|
+
"in-reply-to" => "In-Reply-To",
|
|
76
|
+
"references" => "References",
|
|
77
|
+
"subject" => "Subject",
|
|
78
|
+
"comments" => "Comments",
|
|
79
|
+
"keywords" => "Keywords",
|
|
80
|
+
"date" => "Date",
|
|
81
|
+
"from" => "From",
|
|
82
|
+
"sender" => "Sender",
|
|
83
|
+
"reply-to" => "Reply-To",
|
|
84
|
+
"resent-date" => "Resent-Date",
|
|
85
|
+
"resent-from" => "Resent-From",
|
|
86
|
+
"resent-sender" => "Resent-Sender",
|
|
87
|
+
"resent-to" => "Resent-To",
|
|
88
|
+
"resent-cc" => "Resent-Cc",
|
|
89
|
+
"resent-bcc" => "Resent-Bcc",
|
|
90
|
+
"resent-message-id" => "Resent-Message-ID",
|
|
91
|
+
"return-path" => "Return-Path",
|
|
92
|
+
"received" => "Received",
|
|
93
|
+
"mime-version" => "MIME-Version",
|
|
94
|
+
"content-transfer-encoding" => "Content-Transfer-Encoding",
|
|
95
|
+
"content-description" => "Content-Description",
|
|
96
|
+
"content-disposition" => "Content-Disposition",
|
|
97
|
+
"content-type" => "Content-Type",
|
|
98
|
+
"content-id" => "Content-ID",
|
|
99
|
+
"content-location" => "Content-Location",
|
|
100
|
+
}
|
|
75
101
|
|
|
76
102
|
# Generic Field Exception
|
|
77
103
|
class FieldError < StandardError
|
|
@@ -121,7 +147,7 @@ module Mail
|
|
|
121
147
|
#
|
|
122
148
|
# Mail::Field.parse("field-name: field data")
|
|
123
149
|
# # => #<Mail::Field …>
|
|
124
|
-
def parse(field, charset =
|
|
150
|
+
def parse(field, charset = 'utf-8')
|
|
125
151
|
name, value = split(field)
|
|
126
152
|
if name && value
|
|
127
153
|
new name, value, charset
|
|
@@ -132,7 +158,7 @@ module Mail
|
|
|
132
158
|
if raw_field.index(Constants::COLON)
|
|
133
159
|
name, value = raw_field.split(Constants::COLON, 2)
|
|
134
160
|
name.rstrip!
|
|
135
|
-
if
|
|
161
|
+
if /\A#{Constants::FIELD_NAME}\z/.match?(name)
|
|
136
162
|
[ name.rstrip, value.strip ]
|
|
137
163
|
else
|
|
138
164
|
Kernel.warn "WARNING: Ignoring unparsable header #{raw_field.inspect}: invalid header name syntax: #{name.inspect}"
|
|
@@ -145,6 +171,11 @@ module Mail
|
|
|
145
171
|
warn "WARNING: Ignoring unparsable header #{raw_field.inspect}: #{error.class}: #{error.message}"
|
|
146
172
|
nil
|
|
147
173
|
end
|
|
174
|
+
|
|
175
|
+
def field_class_for(name) #:nodoc:
|
|
176
|
+
class_name = FIELDS_MAP[name.to_s.downcase]
|
|
177
|
+
Mail.const_get(class_name) if class_name
|
|
178
|
+
end
|
|
148
179
|
end
|
|
149
180
|
|
|
150
181
|
attr_reader :unparsed_value
|
|
@@ -163,10 +194,8 @@ module Mail
|
|
|
163
194
|
# # => #<Mail::Field …>
|
|
164
195
|
def initialize(name, value = nil, charset = 'utf-8')
|
|
165
196
|
case
|
|
166
|
-
when name.index(COLON)
|
|
167
|
-
|
|
168
|
-
@name, @unparsed_value = self.class.split(name)
|
|
169
|
-
@charset = Utilities.blank?(value) ? charset : value
|
|
197
|
+
when name.index(Constants::COLON)
|
|
198
|
+
raise ArgumentError, 'Passing an unparsed header field to Mail::Field.new is not supported in Mail 2.8.0+. Use Mail::Field.parse instead.'
|
|
170
199
|
when Utilities.blank?(value)
|
|
171
200
|
@name = name
|
|
172
201
|
@unparsed_value = nil
|
|
@@ -176,11 +205,12 @@ module Mail
|
|
|
176
205
|
@unparsed_value = value
|
|
177
206
|
@charset = charset
|
|
178
207
|
end
|
|
179
|
-
|
|
208
|
+
klass = self.class.field_class_for(@name)
|
|
209
|
+
@name = klass ? klass::NAME : @name
|
|
180
210
|
end
|
|
181
211
|
|
|
182
|
-
def field=(
|
|
183
|
-
@field =
|
|
212
|
+
def field=(field)
|
|
213
|
+
@field = field
|
|
184
214
|
end
|
|
185
215
|
|
|
186
216
|
def field
|
|
@@ -209,81 +239,65 @@ module Mail
|
|
|
209
239
|
end.join(" ")}>"
|
|
210
240
|
end
|
|
211
241
|
|
|
212
|
-
def
|
|
213
|
-
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def same( other )
|
|
217
|
-
return false unless other.kind_of?(self.class)
|
|
218
|
-
match_to_s(other.name, self.name)
|
|
242
|
+
def same(other)
|
|
243
|
+
other.kind_of?(self.class) && Utilities.match_to_s(other.name, name)
|
|
219
244
|
end
|
|
220
245
|
|
|
221
|
-
def ==(
|
|
222
|
-
|
|
223
|
-
match_to_s(other.name, self.name) && match_to_s(other.value, self.value)
|
|
246
|
+
def ==(other)
|
|
247
|
+
same(other) && Utilities.match_to_s(other.value, value)
|
|
224
248
|
end
|
|
225
249
|
|
|
226
|
-
def responsible_for?(
|
|
227
|
-
name.to_s.casecmp(
|
|
250
|
+
def responsible_for?(field_name)
|
|
251
|
+
name.to_s.casecmp(field_name.to_s) == 0
|
|
228
252
|
end
|
|
229
253
|
|
|
230
|
-
def <=>(
|
|
231
|
-
|
|
254
|
+
def <=>(other)
|
|
255
|
+
field_order_id <=> other.field_order_id
|
|
232
256
|
end
|
|
233
257
|
|
|
234
258
|
def field_order_id
|
|
235
|
-
@field_order_id ||= (
|
|
259
|
+
@field_order_id ||= FIELD_ORDER_LOOKUP.fetch(self.name.to_s.downcase, 100)
|
|
236
260
|
end
|
|
237
261
|
|
|
238
262
|
def method_missing(name, *args, &block)
|
|
239
263
|
field.send(name, *args, &block)
|
|
240
264
|
end
|
|
241
265
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
field.respond_to?(method_name, include_private) || super
|
|
245
|
-
end
|
|
246
|
-
else
|
|
247
|
-
def respond_to?(method_name, include_private = false)
|
|
248
|
-
field.respond_to?(method_name, include_private) || super
|
|
249
|
-
end
|
|
266
|
+
def respond_to_missing?(method_name, include_private)
|
|
267
|
+
field.respond_to?(method_name, include_private) || super
|
|
250
268
|
end
|
|
251
269
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
FIELD_ORDER_LOOKUP = Hash[%w[
|
|
271
|
+
return-path received
|
|
272
|
+
resent-date resent-from resent-sender resent-to
|
|
273
|
+
resent-cc resent-bcc resent-message-id
|
|
274
|
+
date from sender reply-to to cc bcc
|
|
275
|
+
message-id in-reply-to references
|
|
276
|
+
subject comments keywords
|
|
277
|
+
mime-version content-type content-transfer-encoding
|
|
278
|
+
content-location content-disposition content-description
|
|
279
|
+
].each_with_index.to_a]
|
|
262
280
|
|
|
263
281
|
private
|
|
264
282
|
|
|
265
283
|
def create_field(name, value, charset)
|
|
266
|
-
|
|
284
|
+
parse_field(name, value, charset)
|
|
267
285
|
rescue Mail::Field::ParseError => e
|
|
268
286
|
field = Mail::UnstructuredField.new(name, value)
|
|
269
287
|
field.errors << [name, value, e]
|
|
270
288
|
field
|
|
271
289
|
end
|
|
272
290
|
|
|
273
|
-
def
|
|
291
|
+
def parse_field(name, value, charset)
|
|
274
292
|
value = unfold(value) if value.is_a?(String)
|
|
275
293
|
|
|
276
|
-
if klass = field_class_for(name)
|
|
277
|
-
klass.
|
|
294
|
+
if klass = self.class.field_class_for(name)
|
|
295
|
+
klass.parse(value, charset)
|
|
278
296
|
else
|
|
279
|
-
OptionalField.
|
|
297
|
+
OptionalField.parse(name, value, charset)
|
|
280
298
|
end
|
|
281
299
|
end
|
|
282
300
|
|
|
283
|
-
def field_class_for(name)
|
|
284
|
-
FIELDS_MAP[name.to_s.downcase]
|
|
285
|
-
end
|
|
286
|
-
|
|
287
301
|
# 2.2.3. Long Header Fields
|
|
288
302
|
#
|
|
289
303
|
# The process of moving from this folded multiple-line representation
|
|
@@ -293,7 +307,7 @@ module Mail
|
|
|
293
307
|
# treated in its unfolded form for further syntactic and semantic
|
|
294
308
|
# evaluation.
|
|
295
309
|
def unfold(string)
|
|
296
|
-
string.gsub(
|
|
310
|
+
string.gsub(Constants::UNFOLD_WS, '\1')
|
|
297
311
|
end
|
|
298
312
|
end
|
|
299
313
|
end
|
data/lib/mail/field_list.rb
CHANGED
|
@@ -2,12 +2,40 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
module Mail
|
|
4
4
|
|
|
5
|
-
# Field List class provides an enhanced array that keeps a list of
|
|
5
|
+
# Field List class provides an enhanced array that keeps a list of
|
|
6
6
|
# email fields in order. And allows you to insert new fields without
|
|
7
7
|
# having to worry about the order they will appear in.
|
|
8
8
|
class FieldList < Array
|
|
9
|
+
def has_field?(field_name)
|
|
10
|
+
any? { |f| f.responsible_for? field_name }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_field(field_name)
|
|
14
|
+
fields = select_fields(field_name)
|
|
15
|
+
case fields.size
|
|
16
|
+
when 0; nil
|
|
17
|
+
when 1; fields.first
|
|
18
|
+
else fields
|
|
19
|
+
end
|
|
20
|
+
end
|
|
9
21
|
|
|
10
|
-
|
|
22
|
+
def add_field(field)
|
|
23
|
+
if field.singular?
|
|
24
|
+
replace_field field
|
|
25
|
+
else
|
|
26
|
+
insert_field field
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
alias_method :<<, :add_field
|
|
30
|
+
|
|
31
|
+
def replace_field(field)
|
|
32
|
+
if first_offset = index { |f| f.responsible_for? field.name }
|
|
33
|
+
delete_field field.name
|
|
34
|
+
insert first_offset, field
|
|
35
|
+
else
|
|
36
|
+
insert_field field
|
|
37
|
+
end
|
|
38
|
+
end
|
|
11
39
|
|
|
12
40
|
# Insert the field in sorted order.
|
|
13
41
|
#
|
|
@@ -15,20 +43,45 @@ module Mail
|
|
|
15
43
|
# Copyright (C) 2001-2013 Python Software Foundation.
|
|
16
44
|
# Licensed under <http://docs.python.org/license.html>
|
|
17
45
|
# From <http://hg.python.org/cpython/file/2.7/Lib/bisect.py>
|
|
18
|
-
def
|
|
19
|
-
lo = 0
|
|
20
|
-
hi = size
|
|
21
|
-
|
|
46
|
+
def insert_field(field)
|
|
47
|
+
lo, hi = 0, size
|
|
22
48
|
while lo < hi
|
|
23
49
|
mid = (lo + hi).div(2)
|
|
24
|
-
if
|
|
50
|
+
if field < self[mid]
|
|
25
51
|
hi = mid
|
|
26
52
|
else
|
|
27
53
|
lo = mid + 1
|
|
28
54
|
end
|
|
29
55
|
end
|
|
30
56
|
|
|
31
|
-
insert
|
|
57
|
+
insert lo, field
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def delete_field(name)
|
|
61
|
+
delete_if { |f| f.responsible_for? name }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def summary
|
|
65
|
+
map { |f| "<#{f.name}: #{f.value}>" }.join(", ")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def select_fields(field_name)
|
|
71
|
+
fields = select { |f| f.responsible_for? field_name }
|
|
72
|
+
if fields.size > 1 && singular?(field_name)
|
|
73
|
+
Array(fields.detect { |f| f.errors.size == 0 } || fields.first)
|
|
74
|
+
else
|
|
75
|
+
fields
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def singular?(field_name)
|
|
80
|
+
if klass = Mail::Field.field_class_for(field_name)
|
|
81
|
+
klass.singular?
|
|
82
|
+
else
|
|
83
|
+
false
|
|
84
|
+
end
|
|
32
85
|
end
|
|
33
86
|
end
|
|
34
87
|
end
|
|
@@ -1,68 +1,49 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
#
|
|
4
|
-
# = Blind Carbon Copy Field
|
|
5
|
-
#
|
|
6
|
-
# The Bcc field inherits from StructuredField and handles the Bcc: header
|
|
7
|
-
# field in the email.
|
|
8
|
-
#
|
|
9
|
-
# Sending bcc to a mail message will instantiate a Mail::Field object that
|
|
10
|
-
# has a BccField as its field type. This includes all Mail::CommonAddress
|
|
11
|
-
# module instance metods.
|
|
12
|
-
#
|
|
13
|
-
# Only one Bcc field can appear in a header, though it can have multiple
|
|
14
|
-
# addresses and groups of addresses.
|
|
15
|
-
#
|
|
16
|
-
# == Examples:
|
|
17
|
-
#
|
|
18
|
-
# mail = Mail.new
|
|
19
|
-
# mail.bcc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
20
|
-
# mail.bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
21
|
-
# mail[:bcc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::BccField:0x180e1c4
|
|
22
|
-
# mail['bcc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::BccField:0x180e1c4
|
|
23
|
-
# mail['Bcc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::BccField:0x180e1c4
|
|
24
|
-
#
|
|
25
|
-
# mail[:bcc].encoded #=> '' # Bcc field does not get output into an email
|
|
26
|
-
# mail[:bcc].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
27
|
-
# mail[:bcc].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
28
|
-
# mail[:bcc].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
29
|
-
#
|
|
30
|
-
require 'mail/fields/common/common_address'
|
|
31
3
|
|
|
32
4
|
module Mail
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
5
|
+
# = Blind Carbon Copy Field
|
|
6
|
+
#
|
|
7
|
+
# The Bcc field inherits from StructuredField and handles the Bcc: header
|
|
8
|
+
# field in the email.
|
|
9
|
+
#
|
|
10
|
+
# Sending bcc to a mail message will instantiate a Mail::Field object that
|
|
11
|
+
# has a BccField as its field type. This includes all Mail::CommonAddress
|
|
12
|
+
# module instance metods.
|
|
13
|
+
#
|
|
14
|
+
# Only one Bcc field can appear in a header, though it can have multiple
|
|
15
|
+
# addresses and groups of addresses.
|
|
16
|
+
#
|
|
17
|
+
# == Examples:
|
|
18
|
+
#
|
|
19
|
+
# mail = Mail.new
|
|
20
|
+
# mail.bcc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
21
|
+
# mail.bcc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
22
|
+
# mail[:bcc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::BccField:0x180e1c4
|
|
23
|
+
# mail['bcc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::BccField:0x180e1c4
|
|
24
|
+
# mail['Bcc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::BccField:0x180e1c4
|
|
25
|
+
#
|
|
26
|
+
# mail[:bcc].encoded #=> '' # Bcc field does not get output into an email
|
|
27
|
+
# mail[:bcc].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
28
|
+
# mail[:bcc].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
29
|
+
# mail[:bcc].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
30
|
+
class BccField < CommonAddressField #:nodoc:
|
|
31
|
+
NAME = 'Bcc'
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
|
|
33
|
+
attr_accessor :include_in_headers
|
|
34
|
+
|
|
35
|
+
def initialize(value = nil, charset = nil)
|
|
36
|
+
super
|
|
37
|
+
self.include_in_headers = false
|
|
52
38
|
end
|
|
53
39
|
|
|
54
40
|
# Bcc field should not be :encoded by default
|
|
55
41
|
def encoded
|
|
56
42
|
if include_in_headers
|
|
57
|
-
|
|
43
|
+
super
|
|
58
44
|
else
|
|
59
45
|
''
|
|
60
46
|
end
|
|
61
47
|
end
|
|
62
|
-
|
|
63
|
-
def decoded
|
|
64
|
-
do_decode
|
|
65
|
-
end
|
|
66
|
-
|
|
67
48
|
end
|
|
68
49
|
end
|
data/lib/mail/fields/cc_field.rb
CHANGED
|
@@ -1,55 +1,33 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
#
|
|
4
|
-
# = Carbon Copy Field
|
|
5
|
-
#
|
|
6
|
-
# The Cc field inherits from StructuredField and handles the Cc: header
|
|
7
|
-
# field in the email.
|
|
8
|
-
#
|
|
9
|
-
# Sending cc to a mail message will instantiate a Mail::Field object that
|
|
10
|
-
# has a CcField as its field type. This includes all Mail::CommonAddress
|
|
11
|
-
# module instance metods.
|
|
12
|
-
#
|
|
13
|
-
# Only one Cc field can appear in a header, though it can have multiple
|
|
14
|
-
# addresses and groups of addresses.
|
|
15
|
-
#
|
|
16
|
-
# == Examples:
|
|
17
|
-
#
|
|
18
|
-
# mail = Mail.new
|
|
19
|
-
# mail.cc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
20
|
-
# mail.cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
21
|
-
# mail[:cc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CcField:0x180e1c4
|
|
22
|
-
# mail['cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CcField:0x180e1c4
|
|
23
|
-
# mail['Cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CcField:0x180e1c4
|
|
24
|
-
#
|
|
25
|
-
# mail[:cc].encoded #=> 'Cc: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
26
|
-
# mail[:cc].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
27
|
-
# mail[:cc].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
28
|
-
# mail[:cc].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
29
|
-
#
|
|
30
|
-
require 'mail/fields/common/common_address'
|
|
31
3
|
|
|
32
4
|
module Mail
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
5
|
+
# = Carbon Copy Field
|
|
6
|
+
#
|
|
7
|
+
# The Cc field inherits from StructuredField and handles the Cc: header
|
|
8
|
+
# field in the email.
|
|
9
|
+
#
|
|
10
|
+
# Sending cc to a mail message will instantiate a Mail::Field object that
|
|
11
|
+
# has a CcField as its field type. This includes all Mail::CommonAddress
|
|
12
|
+
# module instance metods.
|
|
13
|
+
#
|
|
14
|
+
# Only one Cc field can appear in a header, though it can have multiple
|
|
15
|
+
# addresses and groups of addresses.
|
|
16
|
+
#
|
|
17
|
+
# == Examples:
|
|
18
|
+
#
|
|
19
|
+
# mail = Mail.new
|
|
20
|
+
# mail.cc = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
21
|
+
# mail.cc #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
22
|
+
# mail[:cc] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CcField:0x180e1c4
|
|
23
|
+
# mail['cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CcField:0x180e1c4
|
|
24
|
+
# mail['Cc'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CcField:0x180e1c4
|
|
25
|
+
#
|
|
26
|
+
# mail[:cc].encoded #=> 'Cc: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
27
|
+
# mail[:cc].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
28
|
+
# mail[:cc].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
29
|
+
# mail[:cc].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
30
|
+
class CcField < CommonAddressField #:nodoc:
|
|
31
|
+
NAME = 'Cc'
|
|
54
32
|
end
|
|
55
33
|
end
|
|
@@ -1,42 +1,31 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# = Comments Field
|
|
5
|
-
#
|
|
6
|
-
# The Comments field inherits from UnstructuredField and handles the Comments:
|
|
7
|
-
# header field in the email.
|
|
8
|
-
#
|
|
9
|
-
# Sending comments to a mail message will instantiate a Mail::Field object that
|
|
10
|
-
# has a CommentsField as its field type.
|
|
11
|
-
#
|
|
12
|
-
# An email header can have as many comments fields as it wants. There is no upper
|
|
13
|
-
# limit, the comments field is also optional (that is, no comment is needed)
|
|
14
|
-
#
|
|
15
|
-
# == Examples:
|
|
16
|
-
#
|
|
17
|
-
# mail = Mail.new
|
|
18
|
-
# mail.comments = 'This is a comment'
|
|
19
|
-
# mail.comments #=> 'This is a comment'
|
|
20
|
-
# mail[:comments] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CommentsField:0x180e1c4
|
|
21
|
-
# mail['comments'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CommentsField:0x180e1c4
|
|
22
|
-
# mail['comments'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CommentsField:0x180e1c4
|
|
23
|
-
#
|
|
24
|
-
# mail.comments = "This is another comment"
|
|
25
|
-
# mail[:comments].map { |c| c.to_s }
|
|
26
|
-
# #=> ['This is a comment', "This is another comment"]
|
|
27
|
-
#
|
|
3
|
+
|
|
28
4
|
module Mail
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
5
|
+
# = Comments Field
|
|
6
|
+
#
|
|
7
|
+
# The Comments field inherits from UnstructuredField and handles the Comments:
|
|
8
|
+
# header field in the email.
|
|
9
|
+
#
|
|
10
|
+
# Sending comments to a mail message will instantiate a Mail::Field object that
|
|
11
|
+
# has a CommentsField as its field type.
|
|
12
|
+
#
|
|
13
|
+
# An email header can have as many comments fields as it wants. There is no upper
|
|
14
|
+
# limit, the comments field is also optional (that is, no comment is needed)
|
|
15
|
+
#
|
|
16
|
+
# == Examples:
|
|
17
|
+
#
|
|
18
|
+
# mail = Mail.new
|
|
19
|
+
# mail.comments = 'This is a comment'
|
|
20
|
+
# mail.comments #=> 'This is a comment'
|
|
21
|
+
# mail[:comments] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CommentsField:0x180e1c4
|
|
22
|
+
# mail['comments'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CommentsField:0x180e1c4
|
|
23
|
+
# mail['comments'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::CommentsField:0x180e1c4
|
|
24
|
+
#
|
|
25
|
+
# mail.comments = "This is another comment"
|
|
26
|
+
# mail[:comments].map { |c| c.to_s }
|
|
27
|
+
# #=> ['This is a comment', "This is another comment"]
|
|
28
|
+
class CommentsField < NamedUnstructuredField #:nodoc:
|
|
29
|
+
NAME = 'Comments'
|
|
41
30
|
end
|
|
42
31
|
end
|