mail 2.6.3 → 2.7.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 +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +91 -79
- data/lib/mail/attachments_list.rb +11 -5
- data/lib/mail/body.rb +54 -41
- data/lib/mail/check_delivery_params.rb +50 -10
- data/lib/mail/configuration.rb +3 -0
- data/lib/mail/constants.rb +5 -3
- data/lib/mail/core_extensions/smtp.rb +20 -16
- data/lib/mail/core_extensions/string.rb +1 -30
- data/lib/mail/elements/address.rb +43 -32
- data/lib/mail/elements/address_list.rb +11 -18
- data/lib/mail/elements/content_disposition_element.rb +9 -15
- data/lib/mail/elements/content_location_element.rb +8 -12
- data/lib/mail/elements/content_transfer_encoding_element.rb +6 -10
- data/lib/mail/elements/content_type_element.rb +9 -19
- data/lib/mail/elements/date_time_element.rb +7 -14
- data/lib/mail/elements/envelope_from_element.rb +15 -21
- data/lib/mail/elements/message_ids_element.rb +12 -14
- data/lib/mail/elements/mime_version_element.rb +7 -14
- data/lib/mail/elements/phrase_list.rb +7 -9
- data/lib/mail/elements/received_element.rb +10 -15
- data/lib/mail/elements.rb +1 -0
- data/lib/mail/encodings/7bit.rb +6 -15
- data/lib/mail/encodings/8bit.rb +5 -18
- data/lib/mail/encodings/base64.rb +15 -10
- data/lib/mail/encodings/binary.rb +4 -22
- data/lib/mail/encodings/identity.rb +24 -0
- data/lib/mail/encodings/quoted_printable.rb +13 -7
- data/lib/mail/encodings/transfer_encoding.rb +47 -28
- data/lib/mail/encodings/unix_to_unix.rb +4 -1
- data/lib/mail/encodings.rb +114 -60
- data/lib/mail/envelope.rb +2 -1
- data/lib/mail/field.rb +114 -62
- data/lib/mail/field_list.rb +1 -0
- data/lib/mail/fields/bcc_field.rb +17 -5
- data/lib/mail/fields/cc_field.rb +2 -2
- data/lib/mail/fields/comments_field.rb +2 -1
- data/lib/mail/fields/common/address_container.rb +3 -2
- data/lib/mail/fields/common/common_address.rb +40 -14
- data/lib/mail/fields/common/common_date.rb +2 -1
- data/lib/mail/fields/common/common_field.rb +5 -11
- data/lib/mail/fields/common/common_message_id.rb +3 -2
- data/lib/mail/fields/common/parameter_hash.rb +2 -1
- data/lib/mail/fields/content_description_field.rb +2 -1
- data/lib/mail/fields/content_disposition_field.rb +14 -13
- data/lib/mail/fields/content_id_field.rb +5 -4
- data/lib/mail/fields/content_location_field.rb +3 -2
- data/lib/mail/fields/content_transfer_encoding_field.rb +3 -2
- data/lib/mail/fields/content_type_field.rb +7 -11
- data/lib/mail/fields/date_field.rb +4 -4
- data/lib/mail/fields/from_field.rb +2 -2
- data/lib/mail/fields/in_reply_to_field.rb +2 -1
- data/lib/mail/fields/keywords_field.rb +3 -3
- data/lib/mail/fields/message_id_field.rb +3 -2
- data/lib/mail/fields/mime_version_field.rb +4 -3
- data/lib/mail/fields/optional_field.rb +5 -1
- data/lib/mail/fields/received_field.rb +5 -4
- data/lib/mail/fields/references_field.rb +2 -1
- data/lib/mail/fields/reply_to_field.rb +2 -2
- data/lib/mail/fields/resent_bcc_field.rb +2 -2
- data/lib/mail/fields/resent_cc_field.rb +2 -2
- data/lib/mail/fields/resent_date_field.rb +2 -2
- data/lib/mail/fields/resent_from_field.rb +2 -2
- data/lib/mail/fields/resent_message_id_field.rb +2 -1
- data/lib/mail/fields/resent_sender_field.rb +2 -2
- data/lib/mail/fields/resent_to_field.rb +2 -2
- data/lib/mail/fields/return_path_field.rb +2 -2
- data/lib/mail/fields/sender_field.rb +2 -2
- data/lib/mail/fields/structured_field.rb +1 -0
- data/lib/mail/fields/subject_field.rb +2 -1
- data/lib/mail/fields/to_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +25 -7
- data/lib/mail/fields.rb +1 -0
- data/lib/mail/header.rb +15 -12
- data/lib/mail/indifferent_hash.rb +1 -0
- data/lib/mail/mail.rb +3 -10
- data/lib/mail/matchers/attachment_matchers.rb +29 -0
- data/lib/mail/matchers/has_sent_mail.rb +51 -7
- data/lib/mail/message.rb +91 -86
- data/lib/mail/multibyte/chars.rb +32 -30
- data/lib/mail/multibyte/unicode.rb +31 -26
- data/lib/mail/multibyte/utils.rb +1 -0
- data/lib/mail/multibyte.rb +65 -15
- data/lib/mail/network/delivery_methods/exim.rb +7 -10
- data/lib/mail/network/delivery_methods/file_delivery.rb +5 -8
- data/lib/mail/network/delivery_methods/logger_delivery.rb +37 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +17 -11
- data/lib/mail/network/delivery_methods/smtp.rb +60 -53
- data/lib/mail/network/delivery_methods/smtp_connection.rb +11 -6
- data/lib/mail/network/delivery_methods/test_mailer.rb +6 -8
- data/lib/mail/network/retriever_methods/base.rb +1 -0
- data/lib/mail/network/retriever_methods/imap.rb +19 -5
- data/lib/mail/network/retriever_methods/pop3.rb +4 -1
- data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
- data/lib/mail/network.rb +2 -0
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +33208 -104
- data/lib/mail/parsers/address_lists_parser.rl +172 -0
- data/lib/mail/parsers/content_disposition_parser.rb +877 -49
- data/lib/mail/parsers/content_disposition_parser.rl +82 -0
- data/lib/mail/parsers/content_location_parser.rb +804 -23
- data/lib/mail/parsers/content_location_parser.rl +71 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +502 -19
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +64 -0
- data/lib/mail/parsers/content_type_parser.rb +1024 -48
- data/lib/mail/parsers/content_type_parser.rl +83 -0
- data/lib/mail/parsers/date_time_parser.rb +872 -23
- data/lib/mail/parsers/date_time_parser.rl +62 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3570 -34
- data/lib/mail/parsers/envelope_from_parser.rl +82 -0
- data/lib/mail/parsers/message_ids_parser.rb +2840 -25
- data/lib/mail/parsers/message_ids_parser.rl +82 -0
- data/lib/mail/parsers/mime_version_parser.rb +492 -26
- data/lib/mail/parsers/mime_version_parser.rl +61 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +862 -17
- data/lib/mail/parsers/phrase_lists_parser.rl +83 -0
- data/lib/mail/parsers/received_parser.rb +8765 -36
- data/lib/mail/parsers/received_parser.rl +84 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
- data/lib/mail/parsers/rfc2045_mime.rl +16 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
- data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
- data/lib/mail/parsers/rfc5322.rl +59 -0
- data/lib/mail/parsers/rfc5322_address.rl +72 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/lib/mail/parsers.rb +17 -24
- data/lib/mail/part.rb +8 -5
- data/lib/mail/parts_list.rb +31 -14
- data/lib/mail/utilities.rb +109 -10
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +3 -2
- data/lib/mail/version_specific/ruby_1_8.rb +50 -6
- data/lib/mail/version_specific/ruby_1_9.rb +103 -18
- data/lib/mail.rb +5 -12
- metadata +47 -57
- data/CHANGELOG.rdoc +0 -759
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -2
- data/Gemfile +0 -15
- data/Rakefile +0 -29
- data/TODO.rdoc +0 -9
- data/lib/mail/core_extensions/nil.rb +0 -19
- data/lib/mail/core_extensions/object.rb +0 -13
- data/lib/mail/core_extensions/string/access.rb +0 -145
- data/lib/mail/core_extensions/string/multibyte.rb +0 -78
- data/lib/mail/multibyte/exceptions.rb +0 -8
- data/lib/mail/parsers/ragel/common.rl +0 -185
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
- data/lib/mail/parsers/ragel/ruby.rb +0 -40
- data/lib/mail/parsers/ragel.rb +0 -17
|
@@ -1,20 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Mail
|
|
2
|
-
module CheckDeliveryParams
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
module CheckDeliveryParams #:nodoc:
|
|
4
|
+
class << self
|
|
5
|
+
def check(mail)
|
|
6
|
+
[ check_from(mail.smtp_envelope_from),
|
|
7
|
+
check_to(mail.smtp_envelope_to),
|
|
8
|
+
check_message(mail) ]
|
|
6
9
|
end
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
def check_from(addr)
|
|
12
|
+
if Utilities.blank?(addr)
|
|
13
|
+
raise ArgumentError, "SMTP From address may not be blank: #{addr.inspect}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
check_addr 'From', addr
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def check_to(addrs)
|
|
20
|
+
if Utilities.blank?(addrs)
|
|
21
|
+
raise ArgumentError, "SMTP To address may not be blank: #{addrs.inspect}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
Array(addrs).map do |addr|
|
|
25
|
+
check_addr 'To', addr
|
|
26
|
+
end
|
|
10
27
|
end
|
|
11
28
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
29
|
+
def check_addr(addr_name, addr)
|
|
30
|
+
validate_smtp_addr addr do |error_message|
|
|
31
|
+
raise ArgumentError, "SMTP #{addr_name} address #{error_message}: #{addr.inspect}"
|
|
32
|
+
end
|
|
15
33
|
end
|
|
16
34
|
|
|
17
|
-
|
|
35
|
+
def validate_smtp_addr(addr)
|
|
36
|
+
if addr
|
|
37
|
+
if addr.bytesize > 2048
|
|
38
|
+
yield 'may not exceed 2kB'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if /[\r\n]/ =~ addr
|
|
42
|
+
yield 'may not contain CR or LF line breaks'
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
addr
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def check_message(message)
|
|
50
|
+
message = message.encoded if message.respond_to?(:encoded)
|
|
51
|
+
|
|
52
|
+
if Utilities.blank?(message)
|
|
53
|
+
raise ArgumentError, 'An encoded message is required to send an email'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
message
|
|
57
|
+
end
|
|
18
58
|
end
|
|
19
59
|
end
|
|
20
60
|
end
|
data/lib/mail/configuration.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
#
|
|
3
4
|
# Thanks to Nicolas Fouché for this wrapper
|
|
4
5
|
#
|
|
@@ -41,6 +42,8 @@ module Mail
|
|
|
41
42
|
Mail::SMTPConnection
|
|
42
43
|
when :test
|
|
43
44
|
Mail::TestMailer
|
|
45
|
+
when :logger
|
|
46
|
+
Mail::LoggerDelivery
|
|
44
47
|
else
|
|
45
48
|
method
|
|
46
49
|
end
|
data/lib/mail/constants.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: us-ascii
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
module Mail
|
|
3
4
|
module Constants
|
|
4
5
|
white_space = %Q|\x9\x20|
|
|
@@ -12,10 +13,10 @@ module Mail
|
|
|
12
13
|
control = %Q|\x00-\x1f\x7f-\xff|
|
|
13
14
|
|
|
14
15
|
if control.respond_to?(:force_encoding)
|
|
15
|
-
control = control.force_encoding(Encoding::BINARY)
|
|
16
|
+
control = control.dup.force_encoding(Encoding::BINARY)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
CRLF = /\r
|
|
19
|
+
CRLF = /\r?\n/
|
|
19
20
|
WSP = /[#{white_space}]/
|
|
20
21
|
FWS = /#{CRLF}#{WSP}*/
|
|
21
22
|
TEXT = /[#{text}]/ # + obs-text
|
|
@@ -33,7 +34,8 @@ module Mail
|
|
|
33
34
|
ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{sp}]/n
|
|
34
35
|
PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n
|
|
35
36
|
TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{sp}]/n
|
|
36
|
-
ENCODED_VALUE = /\=\?[^?]
|
|
37
|
+
ENCODED_VALUE = /\=\?([^?]+)\?([QB])\?[^?]*?\?\=/mi
|
|
38
|
+
FULL_ENCODED_VALUE = /(\=\?[^?]+\?[QB]\?[^?]*?\?\=)/mi
|
|
37
39
|
|
|
38
40
|
EMPTY = ''
|
|
39
41
|
SPACE = ' '
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
class SMTP
|
|
4
|
-
# This is a backport of r30294 from ruby trunk because of a bug in net/smtp.
|
|
5
|
-
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30294
|
|
6
|
-
#
|
|
7
|
-
# Fixed in what will be Ruby 1.9.3 - tlsconnect also does not exist in some early versions of ruby
|
|
8
|
-
begin
|
|
9
|
-
alias_method :original_tlsconnect, :tlsconnect
|
|
2
|
+
# frozen_string_literal: true
|
|
10
3
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
# This is a backport of r30294 from ruby trunk because of a bug in net/smtp.
|
|
5
|
+
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30294
|
|
6
|
+
#
|
|
7
|
+
# Fixed in Ruby 1.9.3 - tlsconnect also does not exist in some early versions of ruby
|
|
8
|
+
if RUBY_VERSION < '1.9.3'
|
|
9
|
+
module Net
|
|
10
|
+
class SMTP
|
|
11
|
+
begin
|
|
12
|
+
alias_method :original_tlsconnect, :tlsconnect
|
|
13
|
+
|
|
14
|
+
def tlsconnect(s)
|
|
15
|
+
verified = false
|
|
16
|
+
begin
|
|
17
|
+
original_tlsconnect(s).tap { verified = true }
|
|
18
|
+
ensure
|
|
19
|
+
unless verified
|
|
20
|
+
s.close rescue nil
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
end
|
|
24
|
+
rescue NameError
|
|
20
25
|
end
|
|
21
|
-
rescue NameError
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
class String #:nodoc:
|
|
3
4
|
|
|
4
|
-
CRLF = "\r\n"
|
|
5
|
-
LF = "\n"
|
|
6
|
-
|
|
7
|
-
if RUBY_VERSION >= '1.9'
|
|
8
|
-
# This 1.9 only regex can save a reasonable amount of time (~20%)
|
|
9
|
-
# by not matching "\r\n" so the string is returned unchanged in
|
|
10
|
-
# the common case.
|
|
11
|
-
CRLF_REGEX = Regexp.new("(?<!\r)\n|\r(?!\n)")
|
|
12
|
-
else
|
|
13
|
-
CRLF_REGEX = /\n|\r\n|\r/
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def to_crlf
|
|
17
|
-
to_str.gsub(CRLF_REGEX, CRLF)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def to_lf
|
|
21
|
-
to_str.gsub(/\r\n|\r/, LF)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
unless String.instance_methods(false).map {|m| m.to_sym}.include?(:blank?)
|
|
25
|
-
def blank?
|
|
26
|
-
self !~ /\S/
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
5
|
unless method_defined?(:ascii_only?)
|
|
31
6
|
# Backport from Ruby 1.9 checks for non-us-ascii characters.
|
|
32
7
|
def ascii_only?
|
|
@@ -36,10 +11,6 @@ class String #:nodoc:
|
|
|
36
11
|
MATCH_NON_US_ASCII = /[^\x00-\x7f]/
|
|
37
12
|
end
|
|
38
13
|
|
|
39
|
-
def not_ascii_only?
|
|
40
|
-
!ascii_only?
|
|
41
|
-
end
|
|
42
|
-
|
|
43
14
|
unless method_defined?(:bytesize)
|
|
44
15
|
alias :bytesize :length
|
|
45
16
|
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/address_lists_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class Address
|
|
4
|
-
|
|
5
7
|
include Mail::Utilities
|
|
6
8
|
|
|
7
9
|
# Mail::Address handles all email addresses in Mail. It takes an email address string
|
|
@@ -21,7 +23,6 @@ module Mail
|
|
|
21
23
|
# a.comments #=> ['My email address']
|
|
22
24
|
# a.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
|
23
25
|
def initialize(value = nil)
|
|
24
|
-
@output_type = :decode
|
|
25
26
|
if value.nil?
|
|
26
27
|
@parsed = false
|
|
27
28
|
@data = nil
|
|
@@ -43,14 +44,14 @@ module Mail
|
|
|
43
44
|
#
|
|
44
45
|
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
45
46
|
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
|
46
|
-
def format
|
|
47
|
+
def format(output_type = :decode)
|
|
47
48
|
parse unless @parsed
|
|
48
49
|
if @data.nil?
|
|
49
50
|
EMPTY
|
|
50
|
-
elsif display_name
|
|
51
|
-
[quote_phrase(
|
|
52
|
-
elsif address
|
|
53
|
-
[
|
|
51
|
+
elsif name = display_name(output_type)
|
|
52
|
+
[quote_phrase(name), "<#{address(output_type)}>", format_comments].compact.join(SPACE)
|
|
53
|
+
elsif a = address(output_type)
|
|
54
|
+
[a, format_comments].compact.join(SPACE)
|
|
54
55
|
else
|
|
55
56
|
raw
|
|
56
57
|
end
|
|
@@ -61,9 +62,13 @@ module Mail
|
|
|
61
62
|
#
|
|
62
63
|
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
63
64
|
# a.address #=> 'mikel@test.lindsaar.net'
|
|
64
|
-
def address
|
|
65
|
+
def address(output_type = :decode)
|
|
65
66
|
parse unless @parsed
|
|
66
|
-
|
|
67
|
+
if d = domain(output_type)
|
|
68
|
+
"#{local(output_type)}@#{d}"
|
|
69
|
+
else
|
|
70
|
+
local(output_type)
|
|
71
|
+
end
|
|
67
72
|
end
|
|
68
73
|
|
|
69
74
|
# Provides a way to assign an address to an already made Mail::Address object.
|
|
@@ -79,10 +84,10 @@ module Mail
|
|
|
79
84
|
#
|
|
80
85
|
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
81
86
|
# a.display_name #=> 'Mikel Lindsaar'
|
|
82
|
-
def display_name
|
|
87
|
+
def display_name(output_type = :decode)
|
|
83
88
|
parse unless @parsed
|
|
84
89
|
@display_name ||= get_display_name
|
|
85
|
-
Encodings.decode_encode(@display_name.to_s,
|
|
90
|
+
Encodings.decode_encode(@display_name.to_s, output_type) if @display_name
|
|
86
91
|
end
|
|
87
92
|
|
|
88
93
|
# Provides a way to assign a display name to an already made Mail::Address object.
|
|
@@ -92,7 +97,7 @@ module Mail
|
|
|
92
97
|
# a.display_name = 'Mikel Lindsaar'
|
|
93
98
|
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>'
|
|
94
99
|
def display_name=( str )
|
|
95
|
-
@display_name = str
|
|
100
|
+
@display_name = str.nil? ? nil : str.dup # in case frozen
|
|
96
101
|
end
|
|
97
102
|
|
|
98
103
|
# Returns the local part (the left hand side of the @ sign in the email address) of
|
|
@@ -100,9 +105,9 @@ module Mail
|
|
|
100
105
|
#
|
|
101
106
|
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
102
107
|
# a.local #=> 'mikel'
|
|
103
|
-
def local
|
|
108
|
+
def local(output_type = :decode)
|
|
104
109
|
parse unless @parsed
|
|
105
|
-
"#{@data.obs_domain_list}#{get_local.strip}" if get_local
|
|
110
|
+
Encodings.decode_encode("#{@data.obs_domain_list}#{get_local.strip}", output_type) if get_local
|
|
106
111
|
end
|
|
107
112
|
|
|
108
113
|
# Returns the domain part (the right hand side of the @ sign in the email address) of
|
|
@@ -110,19 +115,28 @@ module Mail
|
|
|
110
115
|
#
|
|
111
116
|
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
112
117
|
# a.domain #=> 'test.lindsaar.net'
|
|
113
|
-
def domain
|
|
118
|
+
def domain(output_type = :decode)
|
|
114
119
|
parse unless @parsed
|
|
115
|
-
strip_all_comments(get_domain) if get_domain
|
|
120
|
+
Encodings.decode_encode(strip_all_comments(get_domain), output_type) if get_domain
|
|
116
121
|
end
|
|
117
122
|
|
|
118
|
-
# Returns an array of comments that are in the email, or
|
|
123
|
+
# Returns an array of comments that are in the email, or nil if there
|
|
119
124
|
# are no comments
|
|
120
125
|
#
|
|
121
126
|
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
122
127
|
# a.comments #=> ['My email address']
|
|
128
|
+
#
|
|
129
|
+
# b = Address.new('Mikel Lindsaar <mikel@test.lindsaar.net>')
|
|
130
|
+
# b.comments #=> nil
|
|
131
|
+
|
|
123
132
|
def comments
|
|
124
133
|
parse unless @parsed
|
|
125
|
-
|
|
134
|
+
comments = get_comments
|
|
135
|
+
if comments.nil? || comments.none?
|
|
136
|
+
nil
|
|
137
|
+
else
|
|
138
|
+
comments.map { |c| c.squeeze(SPACE) }
|
|
139
|
+
end
|
|
126
140
|
end
|
|
127
141
|
|
|
128
142
|
# Sometimes an address will not have a display name, but might have the name
|
|
@@ -153,13 +167,11 @@ module Mail
|
|
|
153
167
|
end
|
|
154
168
|
|
|
155
169
|
def encoded
|
|
156
|
-
|
|
157
|
-
format
|
|
170
|
+
format :encode
|
|
158
171
|
end
|
|
159
172
|
|
|
160
173
|
def decoded
|
|
161
|
-
|
|
162
|
-
format
|
|
174
|
+
format :decode
|
|
163
175
|
end
|
|
164
176
|
|
|
165
177
|
def group
|
|
@@ -173,18 +185,18 @@ module Mail
|
|
|
173
185
|
@data = nil
|
|
174
186
|
|
|
175
187
|
case value
|
|
176
|
-
when Mail::Parsers::AddressStruct
|
|
188
|
+
when Mail::Parsers::AddressListsParser::AddressStruct
|
|
177
189
|
@data = value
|
|
178
190
|
when String
|
|
179
|
-
unless
|
|
180
|
-
address_list = Mail::Parsers::AddressListsParser.
|
|
191
|
+
unless Utilities.blank?(value)
|
|
192
|
+
address_list = Mail::Parsers::AddressListsParser.parse(value)
|
|
181
193
|
@data = address_list.addresses.first
|
|
182
194
|
end
|
|
183
195
|
end
|
|
184
196
|
end
|
|
185
197
|
|
|
186
198
|
def strip_all_comments(string)
|
|
187
|
-
unless
|
|
199
|
+
unless Utilities.blank?(comments)
|
|
188
200
|
comments.each do |comment|
|
|
189
201
|
string = string.gsub("(#{comment})", EMPTY)
|
|
190
202
|
end
|
|
@@ -193,7 +205,7 @@ module Mail
|
|
|
193
205
|
end
|
|
194
206
|
|
|
195
207
|
def strip_domain_comments(value)
|
|
196
|
-
unless
|
|
208
|
+
unless Utilities.blank?(comments)
|
|
197
209
|
comments.each do |comment|
|
|
198
210
|
if @data.domain && @data.domain.include?("(#{comment})")
|
|
199
211
|
value = value.gsub("(#{comment})", EMPTY)
|
|
@@ -204,13 +216,12 @@ module Mail
|
|
|
204
216
|
end
|
|
205
217
|
|
|
206
218
|
def get_display_name
|
|
207
|
-
if @data.display_name
|
|
219
|
+
if @data && @data.display_name
|
|
208
220
|
str = strip_all_comments(@data.display_name.to_s)
|
|
209
|
-
elsif @data.comments && @data.domain
|
|
221
|
+
elsif @data && @data.comments && @data.domain
|
|
210
222
|
str = strip_domain_comments(format_comments)
|
|
211
223
|
end
|
|
212
|
-
|
|
213
|
-
str unless str.blank?
|
|
224
|
+
str unless Utilities.blank?(str)
|
|
214
225
|
end
|
|
215
226
|
|
|
216
227
|
def get_name
|
|
@@ -220,7 +231,7 @@ module Mail
|
|
|
220
231
|
str = "(#{comments.join(SPACE).squeeze(SPACE)})"
|
|
221
232
|
end
|
|
222
233
|
|
|
223
|
-
unparen(str) unless
|
|
234
|
+
unparen(str) unless Utilities.blank?(str)
|
|
224
235
|
end
|
|
225
236
|
|
|
226
237
|
def format_comments
|
|
@@ -1,41 +1,34 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/address_lists_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class AddressList # :nodoc:
|
|
7
|
+
attr_reader :addresses, :group_names
|
|
4
8
|
|
|
5
9
|
# Mail::AddressList is the class that parses To, From and other address fields from
|
|
6
10
|
# emails passed into Mail.
|
|
7
|
-
#
|
|
11
|
+
#
|
|
8
12
|
# AddressList provides a way to query the groups and mailbox lists of the passed in
|
|
9
13
|
# string.
|
|
10
|
-
#
|
|
14
|
+
#
|
|
11
15
|
# It can supply all addresses in an array, or return each address as an address object.
|
|
12
|
-
#
|
|
16
|
+
#
|
|
13
17
|
# Mail::AddressList requires a correctly formatted group or mailbox list per RFC2822 or
|
|
14
18
|
# RFC822. It also handles all obsolete versions in those RFCs.
|
|
15
|
-
#
|
|
19
|
+
#
|
|
16
20
|
# list = 'ada@test.lindsaar.net, My Group: mikel@test.lindsaar.net, Bob <bob@test.lindsaar.net>;'
|
|
17
21
|
# a = AddressList.new(list)
|
|
18
22
|
# a.addresses #=> [#<Mail::Address:14943130 Address: |ada@test.lindsaar.net...
|
|
19
23
|
# a.group_names #=> ["My Group"]
|
|
20
24
|
def initialize(string)
|
|
21
|
-
|
|
22
|
-
@
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# Returns a list of address objects from the parsed line
|
|
26
|
-
def addresses
|
|
27
|
-
@addresses ||= @address_list.addresses.map do |address_data|
|
|
28
|
-
Mail::Address.new(address_data)
|
|
29
|
-
end
|
|
25
|
+
address_list = Parsers::AddressListsParser.parse(string)
|
|
26
|
+
@addresses = address_list.addresses.map { |a| Address.new(a) }
|
|
27
|
+
@group_names = address_list.group_names
|
|
30
28
|
end
|
|
31
29
|
|
|
32
30
|
def addresses_grouped_by_group
|
|
33
31
|
addresses.select(&:group).group_by(&:group)
|
|
34
32
|
end
|
|
35
|
-
|
|
36
|
-
# Returns the names as an array of strings of all groups
|
|
37
|
-
def group_names # :nodoc:
|
|
38
|
-
@address_list.group_names
|
|
39
|
-
end
|
|
40
33
|
end
|
|
41
34
|
end
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_disposition_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class ContentDispositionElement # :nodoc:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
content_disposition = Mail::Parsers::ContentDispositionParser.new.parse(cleaned(string))
|
|
7
|
+
attr_reader :disposition_type, :parameters
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
content_disposition = Mail::Parsers::ContentDispositionParser.parse(cleaned(string))
|
|
9
11
|
@disposition_type = content_disposition.disposition_type
|
|
10
12
|
@parameters = content_disposition.parameters
|
|
11
13
|
end
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@disposition_type
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def parameters
|
|
18
|
-
@parameters
|
|
19
|
-
end
|
|
20
|
-
|
|
14
|
+
|
|
15
|
+
private
|
|
21
16
|
def cleaned(string)
|
|
22
17
|
string =~ /(.+);\s*$/ ? $1 : string
|
|
23
18
|
end
|
|
24
|
-
|
|
25
19
|
end
|
|
26
20
|
end
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_location_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class ContentLocationElement # :nodoc:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
content_location = Mail::Parsers::ContentLocationParser.new.parse(string)
|
|
9
|
-
@location = content_location.location
|
|
7
|
+
attr_reader :location
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
@location = Mail::Parsers::ContentLocationParser.parse(string).location
|
|
10
11
|
end
|
|
11
|
-
|
|
12
|
-
def location
|
|
13
|
-
@location
|
|
14
|
-
end
|
|
15
|
-
|
|
12
|
+
|
|
16
13
|
def to_s(*args)
|
|
17
14
|
location.to_s
|
|
18
15
|
end
|
|
19
|
-
|
|
20
16
|
end
|
|
21
17
|
end
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_transfer_encoding_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class ContentTransferEncodingElement
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
attr_reader :encoding
|
|
8
|
+
|
|
7
9
|
def initialize(string)
|
|
8
|
-
|
|
9
|
-
@encoding = content_transfer_encoding.encoding
|
|
10
|
+
@encoding = Mail::Parsers::ContentTransferEncodingParser.parse(string).encoding
|
|
10
11
|
end
|
|
11
|
-
|
|
12
|
-
def encoding
|
|
13
|
-
@encoding
|
|
14
|
-
end
|
|
15
|
-
|
|
16
12
|
end
|
|
17
13
|
end
|
|
@@ -1,31 +1,21 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_type_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class ContentTypeElement # :nodoc:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
content_type = Mail::Parsers::ContentTypeParser.new.parse(cleaned(string))
|
|
7
|
+
attr_reader :main_type, :sub_type, :parameters
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
content_type = Mail::Parsers::ContentTypeParser.parse(cleaned(string))
|
|
9
11
|
@main_type = content_type.main_type
|
|
10
12
|
@sub_type = content_type.sub_type
|
|
11
13
|
@parameters = content_type.parameters
|
|
12
14
|
end
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@main_type
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def sub_type
|
|
19
|
-
@sub_type
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def parameters
|
|
23
|
-
@parameters
|
|
24
|
-
end
|
|
25
|
-
|
|
15
|
+
|
|
16
|
+
private
|
|
26
17
|
def cleaned(string)
|
|
27
18
|
string =~ /(.+);\s*$/ ? $1 : string
|
|
28
19
|
end
|
|
29
|
-
|
|
30
20
|
end
|
|
31
21
|
end
|
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/date_time_parser'
|
|
4
|
+
|
|
2
5
|
module Mail
|
|
3
6
|
class DateTimeElement # :nodoc:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
date_time = Mail::Parsers::DateTimeParser.new.parse(string)
|
|
7
|
+
attr_reader :date_string, :time_string
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
date_time = Mail::Parsers::DateTimeParser.parse(string)
|
|
9
11
|
@date_string = date_time.date_string
|
|
10
12
|
@time_string = date_time.time_string
|
|
11
13
|
end
|
|
12
|
-
|
|
13
|
-
def date_string
|
|
14
|
-
@date_string
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def time_string
|
|
18
|
-
@time_string
|
|
19
|
-
end
|
|
20
|
-
|
|
21
14
|
end
|
|
22
15
|
end
|
|
@@ -1,39 +1,33 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/envelope_from_parser'
|
|
4
|
+
require 'date'
|
|
5
|
+
|
|
2
6
|
module Mail
|
|
3
7
|
class EnvelopeFromElement
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@
|
|
9
|
-
@
|
|
10
|
-
@date_time = ::DateTime.parse(@envelope_from.ctime_date)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def date_time
|
|
14
|
-
@date_time
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def address
|
|
18
|
-
@address
|
|
8
|
+
attr_reader :date_time, :address
|
|
9
|
+
|
|
10
|
+
def initialize(string)
|
|
11
|
+
envelope_from = Mail::Parsers::EnvelopeFromParser.parse(string)
|
|
12
|
+
@address = envelope_from.address
|
|
13
|
+
@date_time = ::DateTime.parse(envelope_from.ctime_date)
|
|
19
14
|
end
|
|
20
|
-
|
|
15
|
+
|
|
21
16
|
# RFC 4155:
|
|
22
17
|
# a timestamp indicating the UTC date and time when the message
|
|
23
18
|
# was originally received, conformant with the syntax of the
|
|
24
19
|
# traditional UNIX 'ctime' output sans timezone (note that the
|
|
25
20
|
# use of UTC precludes the need for a timezone indicator);
|
|
26
21
|
def formatted_date_time
|
|
27
|
-
if
|
|
28
|
-
|
|
22
|
+
if date_time.respond_to?(:ctime)
|
|
23
|
+
date_time.ctime
|
|
29
24
|
else
|
|
30
|
-
|
|
25
|
+
date_time.strftime '%a %b %e %T %Y'
|
|
31
26
|
end
|
|
32
27
|
end
|
|
33
28
|
|
|
34
29
|
def to_s
|
|
35
|
-
"#{
|
|
30
|
+
"#{address} #{formatted_date_time}"
|
|
36
31
|
end
|
|
37
|
-
|
|
38
32
|
end
|
|
39
33
|
end
|