nano-fast-tool 0.0.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 +7 -0
- data/mail-2.9.1/MIT-LICENSE +20 -0
- data/mail-2.9.1/README.md +771 -0
- data/mail-2.9.1/lib/mail/attachments_list.rb +109 -0
- data/mail-2.9.1/lib/mail/body.rb +305 -0
- data/mail-2.9.1/lib/mail/configuration.rb +78 -0
- data/mail-2.9.1/lib/mail/constants.rb +79 -0
- data/mail-2.9.1/lib/mail/elements/address.rb +258 -0
- data/mail-2.9.1/lib/mail/elements/address_list.rb +34 -0
- data/mail-2.9.1/lib/mail/elements/content_disposition_element.rb +20 -0
- data/mail-2.9.1/lib/mail/elements/content_location_element.rb +17 -0
- data/mail-2.9.1/lib/mail/elements/content_transfer_encoding_element.rb +13 -0
- data/mail-2.9.1/lib/mail/elements/content_type_element.rb +25 -0
- data/mail-2.9.1/lib/mail/elements/date_time_element.rb +15 -0
- data/mail-2.9.1/lib/mail/elements/envelope_from_element.rb +39 -0
- data/mail-2.9.1/lib/mail/elements/message_ids_element.rb +31 -0
- data/mail-2.9.1/lib/mail/elements/mime_version_element.rb +15 -0
- data/mail-2.9.1/lib/mail/elements/phrase_list.rb +19 -0
- data/mail-2.9.1/lib/mail/elements/received_element.rb +35 -0
- data/mail-2.9.1/lib/mail/elements.rb +15 -0
- data/mail-2.9.1/lib/mail/encodings/7bit.rb +27 -0
- data/mail-2.9.1/lib/mail/encodings/8bit.rb +18 -0
- data/mail-2.9.1/lib/mail/encodings/base64.rb +38 -0
- data/mail-2.9.1/lib/mail/encodings/binary.rb +13 -0
- data/mail-2.9.1/lib/mail/encodings/identity.rb +24 -0
- data/mail-2.9.1/lib/mail/encodings/quoted_printable.rb +45 -0
- data/mail-2.9.1/lib/mail/encodings/transfer_encoding.rb +77 -0
- data/mail-2.9.1/lib/mail/encodings/unix_to_unix.rb +20 -0
- data/mail-2.9.1/lib/mail/encodings.rb +314 -0
- data/mail-2.9.1/lib/mail/envelope.rb +28 -0
- data/mail-2.9.1/lib/mail/field.rb +313 -0
- data/mail-2.9.1/lib/mail/field_list.rb +87 -0
- data/mail-2.9.1/lib/mail/fields/bcc_field.rb +49 -0
- data/mail-2.9.1/lib/mail/fields/cc_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/comments_field.rb +31 -0
- data/mail-2.9.1/lib/mail/fields/common_address_field.rb +162 -0
- data/mail-2.9.1/lib/mail/fields/common_date_field.rb +56 -0
- data/mail-2.9.1/lib/mail/fields/common_field.rb +77 -0
- data/mail-2.9.1/lib/mail/fields/common_message_id_field.rb +41 -0
- data/mail-2.9.1/lib/mail/fields/content_description_field.rb +12 -0
- data/mail-2.9.1/lib/mail/fields/content_disposition_field.rb +44 -0
- data/mail-2.9.1/lib/mail/fields/content_id_field.rb +35 -0
- data/mail-2.9.1/lib/mail/fields/content_location_field.rb +28 -0
- data/mail-2.9.1/lib/mail/fields/content_transfer_encoding_field.rb +44 -0
- data/mail-2.9.1/lib/mail/fields/content_type_field.rb +171 -0
- data/mail-2.9.1/lib/mail/fields/date_field.rb +28 -0
- data/mail-2.9.1/lib/mail/fields/from_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/in_reply_to_field.rb +45 -0
- data/mail-2.9.1/lib/mail/fields/keywords_field.rb +30 -0
- data/mail-2.9.1/lib/mail/fields/message_id_field.rb +36 -0
- data/mail-2.9.1/lib/mail/fields/mime_version_field.rb +42 -0
- data/mail-2.9.1/lib/mail/fields/named_structured_field.rb +10 -0
- data/mail-2.9.1/lib/mail/fields/named_unstructured_field.rb +10 -0
- data/mail-2.9.1/lib/mail/fields/optional_field.rb +15 -0
- data/mail-2.9.1/lib/mail/fields/parameter_hash.rb +61 -0
- data/mail-2.9.1/lib/mail/fields/received_field.rb +61 -0
- data/mail-2.9.1/lib/mail/fields/references_field.rb +42 -0
- data/mail-2.9.1/lib/mail/fields/reply_to_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/resent_bcc_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/resent_cc_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/resent_date_field.rb +10 -0
- data/mail-2.9.1/lib/mail/fields/resent_from_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/resent_message_id_field.rb +10 -0
- data/mail-2.9.1/lib/mail/fields/resent_sender_field.rb +32 -0
- data/mail-2.9.1/lib/mail/fields/resent_to_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/return_path_field.rb +60 -0
- data/mail-2.9.1/lib/mail/fields/sender_field.rb +45 -0
- data/mail-2.9.1/lib/mail/fields/structured_field.rb +24 -0
- data/mail-2.9.1/lib/mail/fields/subject_field.rb +14 -0
- data/mail-2.9.1/lib/mail/fields/to_field.rb +33 -0
- data/mail-2.9.1/lib/mail/fields/unstructured_field.rb +189 -0
- data/mail-2.9.1/lib/mail/fields.rb +45 -0
- data/mail-2.9.1/lib/mail/header.rb +237 -0
- data/mail-2.9.1/lib/mail/indifferent_hash.rb +147 -0
- data/mail-2.9.1/lib/mail/mail.rb +267 -0
- data/mail-2.9.1/lib/mail/matchers/attachment_matchers.rb +44 -0
- data/mail-2.9.1/lib/mail/matchers/has_sent_mail.rb +201 -0
- data/mail-2.9.1/lib/mail/message.rb +2159 -0
- data/mail-2.9.1/lib/mail/multibyte/chars.rb +318 -0
- data/mail-2.9.1/lib/mail/multibyte/unicode.rb +405 -0
- data/mail-2.9.1/lib/mail/multibyte/utils.rb +44 -0
- data/mail-2.9.1/lib/mail/multibyte.rb +82 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/exim.rb +50 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/file_delivery.rb +43 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/sendmail.rb +87 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/smtp.rb +200 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/smtp_connection.rb +57 -0
- data/mail-2.9.1/lib/mail/network/delivery_methods/test_mailer.rb +44 -0
- data/mail-2.9.1/lib/mail/network/retriever_methods/base.rb +64 -0
- data/mail-2.9.1/lib/mail/network/retriever_methods/imap.rb +190 -0
- data/mail-2.9.1/lib/mail/network/retriever_methods/pop3.rb +143 -0
- data/mail-2.9.1/lib/mail/network/retriever_methods/test_retriever.rb +45 -0
- data/mail-2.9.1/lib/mail/network.rb +16 -0
- data/mail-2.9.1/lib/mail/parser_tools.rb +15 -0
- data/mail-2.9.1/lib/mail/parsers/address_lists_parser.rb +33245 -0
- data/mail-2.9.1/lib/mail/parsers/address_lists_parser.rl +183 -0
- data/mail-2.9.1/lib/mail/parsers/content_disposition_parser.rb +904 -0
- data/mail-2.9.1/lib/mail/parsers/content_disposition_parser.rl +93 -0
- data/mail-2.9.1/lib/mail/parsers/content_location_parser.rb +825 -0
- data/mail-2.9.1/lib/mail/parsers/content_location_parser.rl +82 -0
- data/mail-2.9.1/lib/mail/parsers/content_transfer_encoding_parser.rb +525 -0
- data/mail-2.9.1/lib/mail/parsers/content_transfer_encoding_parser.rl +75 -0
- data/mail-2.9.1/lib/mail/parsers/content_type_parser.rb +1051 -0
- data/mail-2.9.1/lib/mail/parsers/content_type_parser.rl +94 -0
- data/mail-2.9.1/lib/mail/parsers/date_time_parser.rb +894 -0
- data/mail-2.9.1/lib/mail/parsers/date_time_parser.rl +73 -0
- data/mail-2.9.1/lib/mail/parsers/envelope_from_parser.rb +3678 -0
- data/mail-2.9.1/lib/mail/parsers/envelope_from_parser.rl +93 -0
- data/mail-2.9.1/lib/mail/parsers/message_ids_parser.rb +5164 -0
- data/mail-2.9.1/lib/mail/parsers/message_ids_parser.rl +97 -0
- data/mail-2.9.1/lib/mail/parsers/mime_version_parser.rb +516 -0
- data/mail-2.9.1/lib/mail/parsers/mime_version_parser.rl +72 -0
- data/mail-2.9.1/lib/mail/parsers/phrase_lists_parser.rb +887 -0
- data/mail-2.9.1/lib/mail/parsers/phrase_lists_parser.rl +94 -0
- data/mail-2.9.1/lib/mail/parsers/received_parser.rb +8785 -0
- data/mail-2.9.1/lib/mail/parsers/received_parser.rl +95 -0
- data/mail-2.9.1/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
- data/mail-2.9.1/lib/mail/parsers/rfc2045_content_type.rl +25 -0
- data/mail-2.9.1/lib/mail/parsers/rfc2045_mime.rl +16 -0
- data/mail-2.9.1/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
- data/mail-2.9.1/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/mail-2.9.1/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
- data/mail-2.9.1/lib/mail/parsers/rfc5322.rl +74 -0
- data/mail-2.9.1/lib/mail/parsers/rfc5322_address.rl +72 -0
- data/mail-2.9.1/lib/mail/parsers/rfc5322_date_time.rl +37 -0
- data/mail-2.9.1/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/mail-2.9.1/lib/mail/parsers.rb +13 -0
- data/mail-2.9.1/lib/mail/part.rb +119 -0
- data/mail-2.9.1/lib/mail/parts_list.rb +131 -0
- data/mail-2.9.1/lib/mail/smtp_envelope.rb +57 -0
- data/mail-2.9.1/lib/mail/utilities.rb +576 -0
- data/mail-2.9.1/lib/mail/values/unicode_tables.dat +0 -0
- data/mail-2.9.1/lib/mail/version.rb +17 -0
- data/mail-2.9.1/lib/mail/yaml.rb +30 -0
- data/mail-2.9.1/lib/mail.rb +65 -0
- data/nano-fast-tool.gemspec +12 -0
- metadata +177 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/address_lists_parser'
|
|
4
|
+
require 'mail/constants'
|
|
5
|
+
require 'mail/utilities'
|
|
6
|
+
|
|
7
|
+
module Mail
|
|
8
|
+
# Mail::Address handles all email addresses in Mail. It takes an email address string
|
|
9
|
+
# and parses it, breaking it down into its component parts and allowing you to get the
|
|
10
|
+
# address, comments, display name, name, local part, domain part and fully formatted
|
|
11
|
+
# address.
|
|
12
|
+
#
|
|
13
|
+
# Mail::Address requires a correctly formatted email address per RFC2822 or RFC822. It
|
|
14
|
+
# handles all obsolete versions including obsolete domain routing on the local part.
|
|
15
|
+
#
|
|
16
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
17
|
+
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
|
18
|
+
# a.address #=> 'mikel@test.lindsaar.net'
|
|
19
|
+
# a.display_name #=> 'Mikel Lindsaar'
|
|
20
|
+
# a.local #=> 'mikel'
|
|
21
|
+
# a.domain #=> 'test.lindsaar.net'
|
|
22
|
+
# a.comments #=> ['My email address']
|
|
23
|
+
# a.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
|
24
|
+
class Address
|
|
25
|
+
def initialize(value = nil)
|
|
26
|
+
if value.nil?
|
|
27
|
+
@parsed = false
|
|
28
|
+
@data = nil
|
|
29
|
+
else
|
|
30
|
+
parse(value)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns the raw input of the passed in string, this is before it is passed
|
|
35
|
+
# by the parser.
|
|
36
|
+
def raw
|
|
37
|
+
@data.raw
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns a correctly formatted address for the email going out. If given
|
|
41
|
+
# an incorrectly formatted address as input, Mail::Address will do its best
|
|
42
|
+
# to format it correctly. This includes quoting display names as needed and
|
|
43
|
+
# putting the address in angle brackets etc.
|
|
44
|
+
#
|
|
45
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
46
|
+
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
|
47
|
+
def format(output_type = :decode)
|
|
48
|
+
parse unless @parsed
|
|
49
|
+
if @data.nil?
|
|
50
|
+
Constants::EMPTY
|
|
51
|
+
elsif name = display_name(output_type)
|
|
52
|
+
[Utilities.quote_phrase(name), "<#{address(output_type)}>", format_comments].compact.join(Constants::SPACE)
|
|
53
|
+
elsif a = address(output_type)
|
|
54
|
+
[a, format_comments].compact.join(Constants::SPACE)
|
|
55
|
+
else
|
|
56
|
+
raw
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Returns the address that is in the address itself. That is, the
|
|
61
|
+
# local@domain string, without any angle brackets or the like.
|
|
62
|
+
#
|
|
63
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
64
|
+
# a.address #=> 'mikel@test.lindsaar.net'
|
|
65
|
+
def address(output_type = :decode)
|
|
66
|
+
parse unless @parsed
|
|
67
|
+
if d = domain(output_type)
|
|
68
|
+
"#{local(output_type)}@#{d}"
|
|
69
|
+
else
|
|
70
|
+
local(output_type)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Provides a way to assign an address to an already made Mail::Address object.
|
|
75
|
+
#
|
|
76
|
+
# a = Address.new
|
|
77
|
+
# a.address = 'Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>'
|
|
78
|
+
# a.address #=> 'mikel@test.lindsaar.net'
|
|
79
|
+
def address=(value)
|
|
80
|
+
parse(value)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns the display name of the email address passed in.
|
|
84
|
+
#
|
|
85
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
86
|
+
# a.display_name #=> 'Mikel Lindsaar'
|
|
87
|
+
def display_name(output_type = :decode)
|
|
88
|
+
parse unless @parsed
|
|
89
|
+
@display_name ||= get_display_name
|
|
90
|
+
Encodings.decode_encode(@display_name.to_s, output_type) if @display_name
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Provides a way to assign a display name to an already made Mail::Address object.
|
|
94
|
+
#
|
|
95
|
+
# a = Address.new
|
|
96
|
+
# a.address = 'mikel@test.lindsaar.net'
|
|
97
|
+
# a.display_name = 'Mikel Lindsaar'
|
|
98
|
+
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>'
|
|
99
|
+
def display_name=( str )
|
|
100
|
+
@display_name = str.nil? ? nil : str.dup # in case frozen
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns the local part (the left hand side of the @ sign in the email address) of
|
|
104
|
+
# the address
|
|
105
|
+
#
|
|
106
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
107
|
+
# a.local #=> 'mikel'
|
|
108
|
+
def local(output_type = :decode)
|
|
109
|
+
parse unless @parsed
|
|
110
|
+
Encodings.decode_encode("#{@data.obs_domain_list}#{get_local.strip}", output_type) if get_local
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Returns the domain part (the right hand side of the @ sign in the email address) of
|
|
114
|
+
# the address
|
|
115
|
+
#
|
|
116
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
117
|
+
# a.domain #=> 'test.lindsaar.net'
|
|
118
|
+
def domain(output_type = :decode)
|
|
119
|
+
parse unless @parsed
|
|
120
|
+
Encodings.decode_encode(strip_all_comments(get_domain), output_type) if get_domain
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Returns an array of comments that are in the email, or nil if there
|
|
124
|
+
# are no comments
|
|
125
|
+
#
|
|
126
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
127
|
+
# a.comments #=> ['My email address']
|
|
128
|
+
#
|
|
129
|
+
# b = Address.new('Mikel Lindsaar <mikel@test.lindsaar.net>')
|
|
130
|
+
# b.comments #=> nil
|
|
131
|
+
|
|
132
|
+
def comments
|
|
133
|
+
parse unless @parsed
|
|
134
|
+
comments = get_comments
|
|
135
|
+
if comments.nil? || comments.none?
|
|
136
|
+
nil
|
|
137
|
+
else
|
|
138
|
+
comments.map { |c| c.squeeze(Constants::SPACE) }
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Sometimes an address will not have a display name, but might have the name
|
|
143
|
+
# as a comment field after the address. This returns that name if it exists.
|
|
144
|
+
#
|
|
145
|
+
# a = Address.new('mikel@test.lindsaar.net (Mikel Lindsaar)')
|
|
146
|
+
# a.name #=> 'Mikel Lindsaar'
|
|
147
|
+
def name
|
|
148
|
+
parse unless @parsed
|
|
149
|
+
get_name
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Returns the format of the address, or returns nothing
|
|
153
|
+
#
|
|
154
|
+
# a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
|
|
155
|
+
# a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
|
|
156
|
+
def to_s
|
|
157
|
+
parse unless @parsed
|
|
158
|
+
format
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Shows the Address object basic details, including the Address
|
|
162
|
+
# a = Address.new('Mikel (My email) <mikel@test.lindsaar.net>')
|
|
163
|
+
# a.inspect #=> "#<Mail::Address:14184910 Address: |Mikel <mikel@test.lindsaar.net> (My email)| >"
|
|
164
|
+
def inspect
|
|
165
|
+
parse unless @parsed
|
|
166
|
+
"#<#{self.class}:#{self.object_id} Address: |#{to_s}| >"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def encoded
|
|
170
|
+
format :encode
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def decoded
|
|
174
|
+
format :decode
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def group
|
|
178
|
+
@data && @data.group
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def parse(value = nil)
|
|
184
|
+
@parsed = true
|
|
185
|
+
@data = nil
|
|
186
|
+
|
|
187
|
+
case value
|
|
188
|
+
when Mail::Parsers::AddressListsParser::AddressStruct
|
|
189
|
+
@data = value
|
|
190
|
+
when String
|
|
191
|
+
unless Utilities.blank?(value)
|
|
192
|
+
address_list = Mail::Parsers::AddressListsParser.parse(value)
|
|
193
|
+
@data = address_list.addresses.first
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def strip_all_comments(string)
|
|
199
|
+
unless Utilities.blank?(comments)
|
|
200
|
+
comments.each do |comment|
|
|
201
|
+
string = string.gsub("(#{comment})", Constants::EMPTY)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
string.strip
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def strip_domain_comments(value)
|
|
208
|
+
unless Utilities.blank?(comments)
|
|
209
|
+
comments.each do |comment|
|
|
210
|
+
if @data.domain && @data.domain.include?("(#{comment})")
|
|
211
|
+
value = value.gsub("(#{comment})", Constants::EMPTY)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
value.to_s.strip
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def get_display_name
|
|
219
|
+
if @data && @data.display_name
|
|
220
|
+
str = strip_all_comments(@data.display_name.to_s)
|
|
221
|
+
elsif @data && @data.comments && @data.domain
|
|
222
|
+
str = strip_domain_comments(format_comments)
|
|
223
|
+
end
|
|
224
|
+
str unless Utilities.blank?(str)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def get_name
|
|
228
|
+
if display_name
|
|
229
|
+
str = display_name
|
|
230
|
+
elsif comments
|
|
231
|
+
str = "(#{comments.join(Constants::SPACE).squeeze(Constants::SPACE)})"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
Utilities.unparen(str) unless Utilities.blank?(str)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def format_comments
|
|
238
|
+
if comments
|
|
239
|
+
comment_text = comments.map {|c| Utilities.escape_paren(c) }.join(Constants::SPACE).squeeze(Constants::SPACE)
|
|
240
|
+
@format_comments ||= "(#{comment_text})"
|
|
241
|
+
else
|
|
242
|
+
nil
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def get_local
|
|
247
|
+
@data && @data.local
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def get_domain
|
|
251
|
+
@data && @data.domain
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def get_comments
|
|
255
|
+
@data && @data.comments
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/address_lists_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class AddressList #:nodoc:
|
|
7
|
+
attr_reader :addresses, :group_names
|
|
8
|
+
|
|
9
|
+
# Mail::AddressList is the class that parses To, From and other address fields from
|
|
10
|
+
# emails passed into Mail.
|
|
11
|
+
#
|
|
12
|
+
# AddressList provides a way to query the groups and mailbox lists of the passed in
|
|
13
|
+
# string.
|
|
14
|
+
#
|
|
15
|
+
# It can supply all addresses in an array, or return each address as an address object.
|
|
16
|
+
#
|
|
17
|
+
# Mail::AddressList requires a correctly formatted group or mailbox list per RFC2822 or
|
|
18
|
+
# RFC822. It also handles all obsolete versions in those RFCs.
|
|
19
|
+
#
|
|
20
|
+
# list = 'ada@test.lindsaar.net, My Group: mikel@test.lindsaar.net, Bob <bob@test.lindsaar.net>;'
|
|
21
|
+
# a = AddressList.new(list)
|
|
22
|
+
# a.addresses #=> [#<Mail::Address:14943130 Address: |ada@test.lindsaar.net...
|
|
23
|
+
# a.group_names #=> ["My Group"]
|
|
24
|
+
def initialize(string)
|
|
25
|
+
address_list = Parsers::AddressListsParser.parse(string)
|
|
26
|
+
@addresses = address_list.addresses.map { |a| Address.new(a) }
|
|
27
|
+
@group_names = address_list.group_names
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def addresses_grouped_by_group
|
|
31
|
+
addresses.select(&:group).group_by(&:group)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_disposition_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentDispositionElement #:nodoc:
|
|
7
|
+
attr_reader :disposition_type, :parameters
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
content_disposition = Mail::Parsers::ContentDispositionParser.parse(cleaned(string))
|
|
11
|
+
@disposition_type = content_disposition.disposition_type
|
|
12
|
+
@parameters = content_disposition.parameters
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
def cleaned(string)
|
|
17
|
+
string =~ /(.+);\s*$/ ? $1 : string
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_location_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentLocationElement #:nodoc:
|
|
7
|
+
attr_reader :location
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
@location = Mail::Parsers::ContentLocationParser.parse(string).location
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_s(*args)
|
|
14
|
+
location.to_s
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_transfer_encoding_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentTransferEncodingElement #:nodoc:
|
|
7
|
+
attr_reader :encoding
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
@encoding = Mail::Parsers::ContentTransferEncodingParser.parse(string).encoding
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/content_type_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentTypeElement #:nodoc:
|
|
7
|
+
attr_reader :main_type, :sub_type, :parameters
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
content_type = Mail::Parsers::ContentTypeParser.parse(cleaned(string))
|
|
11
|
+
@main_type = content_type.main_type
|
|
12
|
+
@sub_type = content_type.sub_type
|
|
13
|
+
@parameters = content_type.parameters
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
def cleaned(string)
|
|
18
|
+
if string =~ /;\s*$/
|
|
19
|
+
$`
|
|
20
|
+
else
|
|
21
|
+
string
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/date_time_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class DateTimeElement #:nodoc:
|
|
7
|
+
attr_reader :date_string, :time_string
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
date_time = Mail::Parsers::DateTimeParser.parse(string)
|
|
11
|
+
@date_string = date_time.date_string
|
|
12
|
+
@time_string = date_time.time_string
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/envelope_from_parser'
|
|
4
|
+
require 'date'
|
|
5
|
+
|
|
6
|
+
module Mail
|
|
7
|
+
class EnvelopeFromElement #:nodoc:
|
|
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) if envelope_from.ctime_date
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# RFC 4155:
|
|
17
|
+
# a timestamp indicating the UTC date and time when the message
|
|
18
|
+
# was originally received, conformant with the syntax of the
|
|
19
|
+
# traditional UNIX 'ctime' output sans timezone (note that the
|
|
20
|
+
# use of UTC precludes the need for a timezone indicator);
|
|
21
|
+
def formatted_date_time
|
|
22
|
+
if date_time
|
|
23
|
+
if date_time.respond_to?(:ctime)
|
|
24
|
+
date_time.ctime
|
|
25
|
+
else
|
|
26
|
+
date_time.strftime '%a %b %e %T %Y'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_s
|
|
32
|
+
if date_time
|
|
33
|
+
"#{address} #{formatted_date_time}"
|
|
34
|
+
else
|
|
35
|
+
address
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/message_ids_parser'
|
|
4
|
+
require 'mail/utilities'
|
|
5
|
+
|
|
6
|
+
module Mail
|
|
7
|
+
class MessageIdsElement #:nodoc:
|
|
8
|
+
def self.parse(string)
|
|
9
|
+
new(string).tap(&:message_ids)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :message_ids
|
|
13
|
+
|
|
14
|
+
def initialize(string)
|
|
15
|
+
@message_ids = parse(string)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def message_id
|
|
19
|
+
message_ids.first
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
def parse(string)
|
|
24
|
+
if Utilities.blank? string
|
|
25
|
+
[]
|
|
26
|
+
else
|
|
27
|
+
Mail::Parsers::MessageIdsParser.parse(string).message_ids
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/mime_version_parser'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
class MimeVersionElement #:nodoc:
|
|
7
|
+
attr_reader :major, :minor
|
|
8
|
+
|
|
9
|
+
def initialize(string)
|
|
10
|
+
mime_version = Mail::Parsers::MimeVersionParser.parse(string)
|
|
11
|
+
@major = mime_version.major
|
|
12
|
+
@minor = mime_version.minor
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/phrase_lists_parser'
|
|
4
|
+
require 'mail/utilities'
|
|
5
|
+
|
|
6
|
+
module Mail
|
|
7
|
+
class PhraseList #:nodoc:
|
|
8
|
+
attr_reader :phrases
|
|
9
|
+
|
|
10
|
+
def initialize(string)
|
|
11
|
+
@phrases =
|
|
12
|
+
if Utilities.blank? string
|
|
13
|
+
[]
|
|
14
|
+
else
|
|
15
|
+
Mail::Parsers::PhraseListsParser.parse(string).phrases.map { |p| Mail::Utilities.unquote(p) }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/parsers/received_parser'
|
|
4
|
+
require 'mail/utilities'
|
|
5
|
+
require 'date'
|
|
6
|
+
|
|
7
|
+
module Mail
|
|
8
|
+
class ReceivedElement #:nodoc:
|
|
9
|
+
attr_reader :info, :date_time
|
|
10
|
+
|
|
11
|
+
def initialize(string)
|
|
12
|
+
if Utilities.blank? string
|
|
13
|
+
@date_time = nil
|
|
14
|
+
@info = nil
|
|
15
|
+
else
|
|
16
|
+
received = Mail::Parsers::ReceivedParser.parse(string)
|
|
17
|
+
@date_time = datetime_for(received)
|
|
18
|
+
@info = received.info
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_s(*args)
|
|
23
|
+
"#{info}; #{date_time.to_s(*args)}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
def datetime_for(received)
|
|
28
|
+
::DateTime.parse("#{received.date} #{received.time}")
|
|
29
|
+
rescue ArgumentError => e
|
|
30
|
+
raise e unless e.message == 'invalid date'
|
|
31
|
+
warn "WARNING: Invalid date field for received element (#{received.date} #{received.time}): #{e.class}: #{e.message}"
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Mail
|
|
3
|
+
register_autoload :Address, 'mail/elements/address'
|
|
4
|
+
register_autoload :AddressList, 'mail/elements/address_list'
|
|
5
|
+
register_autoload :ContentDispositionElement, 'mail/elements/content_disposition_element'
|
|
6
|
+
register_autoload :ContentLocationElement, 'mail/elements/content_location_element'
|
|
7
|
+
register_autoload :ContentTransferEncodingElement, 'mail/elements/content_transfer_encoding_element'
|
|
8
|
+
register_autoload :ContentTypeElement, 'mail/elements/content_type_element'
|
|
9
|
+
register_autoload :DateTimeElement, 'mail/elements/date_time_element'
|
|
10
|
+
register_autoload :EnvelopeFromElement, 'mail/elements/envelope_from_element'
|
|
11
|
+
register_autoload :MessageIdsElement, 'mail/elements/message_ids_element'
|
|
12
|
+
register_autoload :MimeVersionElement, 'mail/elements/mime_version_element'
|
|
13
|
+
register_autoload :PhraseList, 'mail/elements/phrase_list'
|
|
14
|
+
register_autoload :ReceivedElement, 'mail/elements/received_element'
|
|
15
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/encodings/8bit'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
module Encodings
|
|
7
|
+
# 7bit and 8bit are equivalent. 7bit encoding is for text only.
|
|
8
|
+
class SevenBit < EightBit
|
|
9
|
+
NAME = '7bit'
|
|
10
|
+
PRIORITY = 1
|
|
11
|
+
Encodings.register(NAME, self)
|
|
12
|
+
|
|
13
|
+
def self.decode(str)
|
|
14
|
+
::Mail::Utilities.binary_unsafe_to_lf str
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.encode(str)
|
|
18
|
+
::Mail::Utilities.binary_unsafe_to_crlf str
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Per RFC 2045 2.7. 7bit Data, No octets with decimal values greater than 127 are allowed.
|
|
22
|
+
def self.compatible_input?(str)
|
|
23
|
+
str.ascii_only? && super
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/encodings/binary'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
module Encodings
|
|
7
|
+
class EightBit < Binary
|
|
8
|
+
NAME = '8bit'
|
|
9
|
+
PRIORITY = 4
|
|
10
|
+
Encodings.register(NAME, self)
|
|
11
|
+
|
|
12
|
+
# Per RFC 2821 4.5.3.1, SMTP lines may not be longer than 1000 octets including the <CRLF>.
|
|
13
|
+
def self.compatible_input?(str)
|
|
14
|
+
!str.lines.find { |line| line.bytesize > 998 }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/encodings/7bit'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
module Encodings
|
|
7
|
+
# Base64 encoding handles binary content at the cost of 4 output bytes
|
|
8
|
+
# per input byte.
|
|
9
|
+
class Base64 < SevenBit
|
|
10
|
+
NAME = 'base64'
|
|
11
|
+
PRIORITY = 3
|
|
12
|
+
Encodings.register(NAME, self)
|
|
13
|
+
|
|
14
|
+
def self.can_encode?(enc)
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.decode(str)
|
|
19
|
+
Utilities.decode_base64(str)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.encode(str)
|
|
23
|
+
::Mail::Utilities.binary_unsafe_to_crlf(Utilities.encode_base64(str))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# 3 bytes in -> 4 bytes out
|
|
27
|
+
def self.cost(str)
|
|
28
|
+
4.0 / 3
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Ruby Base64 inserts newlines automatically, so it doesn't exceed
|
|
32
|
+
# SMTP line length limits.
|
|
33
|
+
def self.compatible_input?(str)
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'mail/encodings/transfer_encoding'
|
|
4
|
+
|
|
5
|
+
module Mail
|
|
6
|
+
module Encodings
|
|
7
|
+
# Identity encodings do no encoding/decoding and have a fixed cost:
|
|
8
|
+
# 1 byte in -> 1 byte out.
|
|
9
|
+
class Identity < TransferEncoding #:nodoc:
|
|
10
|
+
def self.decode(str)
|
|
11
|
+
str
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.encode(str)
|
|
15
|
+
str
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# 1 output byte per input byte.
|
|
19
|
+
def self.cost(str)
|
|
20
|
+
1.0
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|