mail 2.5.5 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +170 -108
  4. data/lib/mail/attachments_list.rb +13 -10
  5. data/lib/mail/body.rb +105 -91
  6. data/lib/mail/check_delivery_params.rb +30 -22
  7. data/lib/mail/configuration.rb +3 -0
  8. data/lib/mail/constants.rb +79 -0
  9. data/lib/mail/elements/address.rb +118 -174
  10. data/lib/mail/elements/address_list.rb +16 -56
  11. data/lib/mail/elements/content_disposition_element.rb +12 -22
  12. data/lib/mail/elements/content_location_element.rb +9 -17
  13. data/lib/mail/elements/content_transfer_encoding_element.rb +8 -19
  14. data/lib/mail/elements/content_type_element.rb +20 -30
  15. data/lib/mail/elements/date_time_element.rb +10 -21
  16. data/lib/mail/elements/envelope_from_element.rb +23 -31
  17. data/lib/mail/elements/message_ids_element.rb +22 -20
  18. data/lib/mail/elements/mime_version_element.rb +10 -21
  19. data/lib/mail/elements/phrase_list.rb +13 -15
  20. data/lib/mail/elements/received_element.rb +26 -21
  21. data/lib/mail/elements.rb +1 -0
  22. data/lib/mail/encodings/7bit.rb +10 -14
  23. data/lib/mail/encodings/8bit.rb +5 -18
  24. data/lib/mail/encodings/base64.rb +15 -10
  25. data/lib/mail/encodings/binary.rb +4 -22
  26. data/lib/mail/encodings/identity.rb +24 -0
  27. data/lib/mail/encodings/quoted_printable.rb +13 -7
  28. data/lib/mail/encodings/transfer_encoding.rb +47 -28
  29. data/lib/mail/encodings/unix_to_unix.rb +20 -0
  30. data/lib/mail/encodings.rb +102 -93
  31. data/lib/mail/envelope.rb +12 -19
  32. data/lib/mail/field.rb +143 -71
  33. data/lib/mail/field_list.rb +73 -19
  34. data/lib/mail/fields/bcc_field.rb +42 -48
  35. data/lib/mail/fields/cc_field.rb +29 -50
  36. data/lib/mail/fields/comments_field.rb +28 -37
  37. data/lib/mail/fields/common_address_field.rb +170 -0
  38. data/lib/mail/fields/common_date_field.rb +58 -0
  39. data/lib/mail/fields/common_field.rb +77 -0
  40. data/lib/mail/fields/common_message_id_field.rb +42 -0
  41. data/lib/mail/fields/content_description_field.rb +8 -14
  42. data/lib/mail/fields/content_disposition_field.rb +20 -44
  43. data/lib/mail/fields/content_id_field.rb +25 -51
  44. data/lib/mail/fields/content_location_field.rb +12 -25
  45. data/lib/mail/fields/content_transfer_encoding_field.rb +31 -36
  46. data/lib/mail/fields/content_type_field.rb +51 -80
  47. data/lib/mail/fields/date_field.rb +24 -52
  48. data/lib/mail/fields/from_field.rb +29 -50
  49. data/lib/mail/fields/in_reply_to_field.rb +39 -49
  50. data/lib/mail/fields/keywords_field.rb +19 -32
  51. data/lib/mail/fields/message_id_field.rb +26 -71
  52. data/lib/mail/fields/mime_version_field.rb +20 -30
  53. data/lib/mail/fields/named_structured_field.rb +11 -0
  54. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  55. data/lib/mail/fields/optional_field.rb +10 -7
  56. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +16 -13
  57. data/lib/mail/fields/received_field.rb +44 -57
  58. data/lib/mail/fields/references_field.rb +36 -49
  59. data/lib/mail/fields/reply_to_field.rb +29 -50
  60. data/lib/mail/fields/resent_bcc_field.rb +29 -50
  61. data/lib/mail/fields/resent_cc_field.rb +29 -50
  62. data/lib/mail/fields/resent_date_field.rb +6 -30
  63. data/lib/mail/fields/resent_from_field.rb +29 -50
  64. data/lib/mail/fields/resent_message_id_field.rb +6 -29
  65. data/lib/mail/fields/resent_sender_field.rb +28 -57
  66. data/lib/mail/fields/resent_to_field.rb +29 -50
  67. data/lib/mail/fields/return_path_field.rb +51 -55
  68. data/lib/mail/fields/sender_field.rb +35 -56
  69. data/lib/mail/fields/structured_field.rb +4 -30
  70. data/lib/mail/fields/subject_field.rb +10 -11
  71. data/lib/mail/fields/to_field.rb +29 -50
  72. data/lib/mail/fields/unstructured_field.rb +43 -51
  73. data/lib/mail/fields.rb +1 -0
  74. data/lib/mail/header.rb +78 -129
  75. data/lib/mail/indifferent_hash.rb +1 -0
  76. data/lib/mail/mail.rb +18 -11
  77. data/lib/mail/matchers/attachment_matchers.rb +44 -0
  78. data/lib/mail/matchers/has_sent_mail.rb +81 -4
  79. data/lib/mail/message.rb +142 -139
  80. data/lib/mail/multibyte/chars.rb +24 -180
  81. data/lib/mail/multibyte/unicode.rb +32 -27
  82. data/lib/mail/multibyte/utils.rb +27 -43
  83. data/lib/mail/multibyte.rb +56 -16
  84. data/lib/mail/network/delivery_methods/exim.rb +6 -4
  85. data/lib/mail/network/delivery_methods/file_delivery.rb +12 -10
  86. data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  87. data/lib/mail/network/delivery_methods/sendmail.rb +63 -21
  88. data/lib/mail/network/delivery_methods/smtp.rb +76 -50
  89. data/lib/mail/network/delivery_methods/smtp_connection.rb +4 -4
  90. data/lib/mail/network/delivery_methods/test_mailer.rb +5 -2
  91. data/lib/mail/network/retriever_methods/base.rb +9 -8
  92. data/lib/mail/network/retriever_methods/imap.rb +37 -18
  93. data/lib/mail/network/retriever_methods/pop3.rb +6 -3
  94. data/lib/mail/network/retriever_methods/test_retriever.rb +4 -2
  95. data/lib/mail/network.rb +2 -0
  96. data/lib/mail/parser_tools.rb +15 -0
  97. data/lib/mail/parsers/address_lists_parser.rb +33242 -0
  98. data/lib/mail/parsers/address_lists_parser.rl +179 -0
  99. data/lib/mail/parsers/content_disposition_parser.rb +901 -0
  100. data/lib/mail/parsers/content_disposition_parser.rl +89 -0
  101. data/lib/mail/parsers/content_location_parser.rb +822 -0
  102. data/lib/mail/parsers/content_location_parser.rl +78 -0
  103. data/lib/mail/parsers/content_transfer_encoding_parser.rb +522 -0
  104. data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
  105. data/lib/mail/parsers/content_type_parser.rb +1048 -0
  106. data/lib/mail/parsers/content_type_parser.rl +90 -0
  107. data/lib/mail/parsers/date_time_parser.rb +891 -0
  108. data/lib/mail/parsers/date_time_parser.rl +69 -0
  109. data/lib/mail/parsers/envelope_from_parser.rb +3675 -0
  110. data/lib/mail/parsers/envelope_from_parser.rl +89 -0
  111. data/lib/mail/parsers/message_ids_parser.rb +5161 -0
  112. data/lib/mail/parsers/message_ids_parser.rl +93 -0
  113. data/lib/mail/parsers/mime_version_parser.rb +513 -0
  114. data/lib/mail/parsers/mime_version_parser.rl +68 -0
  115. data/lib/mail/parsers/phrase_lists_parser.rb +884 -0
  116. data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
  117. data/lib/mail/parsers/received_parser.rb +8782 -0
  118. data/lib/mail/parsers/received_parser.rl +91 -0
  119. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  120. data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  121. data/lib/mail/parsers/rfc2045_mime.rl +16 -0
  122. data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  123. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  124. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  125. data/lib/mail/parsers/rfc5322.rl +74 -0
  126. data/lib/mail/parsers/rfc5322_address.rl +72 -0
  127. data/lib/mail/parsers/rfc5322_date_time.rl +37 -0
  128. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  129. data/lib/mail/parsers.rb +13 -0
  130. data/lib/mail/part.rb +11 -12
  131. data/lib/mail/parts_list.rb +90 -14
  132. data/lib/mail/smtp_envelope.rb +57 -0
  133. data/lib/mail/utilities.rb +415 -76
  134. data/lib/mail/values/unicode_tables.dat +0 -0
  135. data/lib/mail/version.rb +8 -15
  136. data/lib/mail/yaml.rb +30 -0
  137. data/lib/mail.rb +9 -32
  138. metadata +127 -79
  139. data/CHANGELOG.rdoc +0 -742
  140. data/CONTRIBUTING.md +0 -45
  141. data/Dependencies.txt +0 -3
  142. data/Gemfile +0 -32
  143. data/Rakefile +0 -21
  144. data/TODO.rdoc +0 -9
  145. data/lib/VERSION +0 -4
  146. data/lib/load_parsers.rb +0 -35
  147. data/lib/mail/core_extensions/nil.rb +0 -19
  148. data/lib/mail/core_extensions/object.rb +0 -13
  149. data/lib/mail/core_extensions/smtp.rb +0 -24
  150. data/lib/mail/core_extensions/string/access.rb +0 -145
  151. data/lib/mail/core_extensions/string/multibyte.rb +0 -78
  152. data/lib/mail/core_extensions/string.rb +0 -33
  153. data/lib/mail/fields/common/address_container.rb +0 -16
  154. data/lib/mail/fields/common/common_address.rb +0 -140
  155. data/lib/mail/fields/common/common_date.rb +0 -42
  156. data/lib/mail/fields/common/common_field.rb +0 -57
  157. data/lib/mail/fields/common/common_message_id.rb +0 -48
  158. data/lib/mail/multibyte/exceptions.rb +0 -8
  159. data/lib/mail/parsers/address_lists.rb +0 -64
  160. data/lib/mail/parsers/address_lists.treetop +0 -19
  161. data/lib/mail/parsers/content_disposition.rb +0 -535
  162. data/lib/mail/parsers/content_disposition.treetop +0 -46
  163. data/lib/mail/parsers/content_location.rb +0 -139
  164. data/lib/mail/parsers/content_location.treetop +0 -20
  165. data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
  166. data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
  167. data/lib/mail/parsers/content_type.rb +0 -971
  168. data/lib/mail/parsers/content_type.treetop +0 -68
  169. data/lib/mail/parsers/date_time.rb +0 -114
  170. data/lib/mail/parsers/date_time.treetop +0 -11
  171. data/lib/mail/parsers/envelope_from.rb +0 -194
  172. data/lib/mail/parsers/envelope_from.treetop +0 -32
  173. data/lib/mail/parsers/message_ids.rb +0 -45
  174. data/lib/mail/parsers/message_ids.treetop +0 -15
  175. data/lib/mail/parsers/mime_version.rb +0 -144
  176. data/lib/mail/parsers/mime_version.treetop +0 -19
  177. data/lib/mail/parsers/phrase_lists.rb +0 -45
  178. data/lib/mail/parsers/phrase_lists.treetop +0 -15
  179. data/lib/mail/parsers/received.rb +0 -71
  180. data/lib/mail/parsers/received.treetop +0 -11
  181. data/lib/mail/parsers/rfc2045.rb +0 -421
  182. data/lib/mail/parsers/rfc2045.treetop +0 -35
  183. data/lib/mail/parsers/rfc2822.rb +0 -5397
  184. data/lib/mail/parsers/rfc2822.treetop +0 -408
  185. data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
  186. data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
  187. data/lib/mail/patterns.rb +0 -35
  188. data/lib/mail/version_specific/ruby_1_8.rb +0 -119
  189. data/lib/mail/version_specific/ruby_1_9.rb +0 -147
  190. data/lib/tasks/corpus.rake +0 -125
  191. data/lib/tasks/treetop.rake +0 -10
@@ -1,42 +1,40 @@
1
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
+
2
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)'
3
24
  class Address
4
-
5
- include Mail::Utilities
6
-
7
- # Mail::Address handles all email addresses in Mail. It takes an email address string
8
- # and parses it, breaking it down into its component parts and allowing you to get the
9
- # address, comments, display name, name, local part, domain part and fully formatted
10
- # address.
11
- #
12
- # Mail::Address requires a correctly formatted email address per RFC2822 or RFC822. It
13
- # handles all obsolete versions including obsolete domain routing on the local part.
14
- #
15
- # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
16
- # a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
17
- # a.address #=> 'mikel@test.lindsaar.net'
18
- # a.display_name #=> 'Mikel Lindsaar'
19
- # a.local #=> 'mikel'
20
- # a.domain #=> 'test.lindsaar.net'
21
- # a.comments #=> ['My email address']
22
- # a.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
23
25
  def initialize(value = nil)
24
- @output_type = :decode
25
- @tree = nil
26
- @raw_text = value
27
- case
28
- when value.nil?
26
+ if value.nil?
29
27
  @parsed = false
30
- return
28
+ @data = nil
31
29
  else
32
30
  parse(value)
33
31
  end
34
32
  end
35
-
36
- # Returns the raw imput of the passed in string, this is before it is passed
33
+
34
+ # Returns the raw input of the passed in string, this is before it is passed
37
35
  # by the parser.
38
36
  def raw
39
- @raw_text
37
+ @data.raw
40
38
  end
41
39
 
42
40
  # Returns a correctly formatted address for the email going out. If given
@@ -46,112 +44,120 @@ module Mail
46
44
  #
47
45
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
48
46
  # a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
49
- def format
47
+ def format(output_type = :decode)
50
48
  parse unless @parsed
51
- case
52
- when tree.nil?
53
- ''
54
- when display_name
55
- [quote_phrase(display_name), "<#{address}>", format_comments].compact.join(" ")
56
- when address
57
- [address, format_comments].compact.join(" ")
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)
58
55
  else
59
- tree.text_value
56
+ raw
60
57
  end
61
58
  end
62
59
 
63
- # Returns the address that is in the address itself. That is, the
60
+ # Returns the address that is in the address itself. That is, the
64
61
  # local@domain string, without any angle brackets or the like.
65
- #
62
+ #
66
63
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
67
64
  # a.address #=> 'mikel@test.lindsaar.net'
68
- def address
65
+ def address(output_type = :decode)
69
66
  parse unless @parsed
70
- domain ? "#{local}@#{domain}" : local
67
+ if d = domain(output_type)
68
+ "#{local(output_type)}@#{d}"
69
+ else
70
+ local(output_type)
71
+ end
71
72
  end
72
-
73
+
73
74
  # Provides a way to assign an address to an already made Mail::Address object.
74
- #
75
+ #
75
76
  # a = Address.new
76
77
  # a.address = 'Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>'
77
78
  # a.address #=> 'mikel@test.lindsaar.net'
78
79
  def address=(value)
79
80
  parse(value)
80
81
  end
81
-
82
+
82
83
  # Returns the display name of the email address passed in.
83
- #
84
+ #
84
85
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
85
86
  # a.display_name #=> 'Mikel Lindsaar'
86
- def display_name
87
+ def display_name(output_type = :decode)
87
88
  parse unless @parsed
88
89
  @display_name ||= get_display_name
89
- Encodings.decode_encode(@display_name.to_s, @output_type) if @display_name
90
+ Encodings.decode_encode(@display_name.to_s, output_type) if @display_name
90
91
  end
91
-
92
+
92
93
  # Provides a way to assign a display name to an already made Mail::Address object.
93
- #
94
+ #
94
95
  # a = Address.new
95
96
  # a.address = 'mikel@test.lindsaar.net'
96
97
  # a.display_name = 'Mikel Lindsaar'
97
98
  # a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>'
98
99
  def display_name=( str )
99
- @display_name = str
100
+ @display_name = str.nil? ? nil : str.dup # in case frozen
100
101
  end
101
102
 
102
103
  # Returns the local part (the left hand side of the @ sign in the email address) of
103
104
  # the address
104
- #
105
+ #
105
106
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
106
107
  # a.local #=> 'mikel'
107
- def local
108
+ def local(output_type = :decode)
108
109
  parse unless @parsed
109
- "#{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
110
111
  end
111
112
 
112
113
  # Returns the domain part (the right hand side of the @ sign in the email address) of
113
114
  # the address
114
- #
115
+ #
115
116
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
116
117
  # a.domain #=> 'test.lindsaar.net'
117
- def domain
118
+ def domain(output_type = :decode)
118
119
  parse unless @parsed
119
- strip_all_comments(get_domain) if get_domain
120
+ Encodings.decode_encode(strip_all_comments(get_domain), output_type) if get_domain
120
121
  end
121
-
122
- # Returns an array of comments that are in the email, or an empty array if there
122
+
123
+ # Returns an array of comments that are in the email, or nil if there
123
124
  # are no comments
124
- #
125
+ #
125
126
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
126
127
  # a.comments #=> ['My email address']
128
+ #
129
+ # b = Address.new('Mikel Lindsaar <mikel@test.lindsaar.net>')
130
+ # b.comments #=> nil
131
+
127
132
  def comments
128
133
  parse unless @parsed
129
- if get_comments.empty?
134
+ comments = get_comments
135
+ if comments.nil? || comments.none?
130
136
  nil
131
137
  else
132
- get_comments.map { |c| c.squeeze(" ") }
138
+ comments.map { |c| c.squeeze(Constants::SPACE) }
133
139
  end
134
140
  end
135
-
141
+
136
142
  # Sometimes an address will not have a display name, but might have the name
137
143
  # as a comment field after the address. This returns that name if it exists.
138
- #
144
+ #
139
145
  # a = Address.new('mikel@test.lindsaar.net (Mikel Lindsaar)')
140
146
  # a.name #=> 'Mikel Lindsaar'
141
147
  def name
142
148
  parse unless @parsed
143
149
  get_name
144
150
  end
145
-
151
+
146
152
  # Returns the format of the address, or returns nothing
147
- #
153
+ #
148
154
  # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
149
155
  # a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
150
156
  def to_s
151
157
  parse unless @parsed
152
158
  format
153
159
  end
154
-
160
+
155
161
  # Shows the Address object basic details, including the Address
156
162
  # a = Address.new('Mikel (My email) <mikel@test.lindsaar.net>')
157
163
  # a.inspect #=> "#<Mail::Address:14184910 Address: |Mikel <mikel@test.lindsaar.net> (My email)| >"
@@ -159,156 +165,94 @@ module Mail
159
165
  parse unless @parsed
160
166
  "#<#{self.class}:#{self.object_id} Address: |#{to_s}| >"
161
167
  end
162
-
168
+
163
169
  def encoded
164
- @output_type = :encode
165
- format
170
+ format :encode
166
171
  end
167
-
172
+
168
173
  def decoded
169
- @output_type = :decode
170
- format
174
+ format :decode
175
+ end
176
+
177
+ def group
178
+ @data && @data.group
171
179
  end
172
180
 
173
181
  private
174
-
182
+
175
183
  def parse(value = nil)
176
184
  @parsed = true
177
- case
178
- when value.nil?
179
- nil
180
- when value.class == String
181
- self.tree = Mail::AddressList.new(value).address_nodes.first
182
- else
183
- self.tree = value
184
- end
185
- end
186
-
187
-
188
- def get_domain
189
- if tree.respond_to?(:angle_addr) && tree.angle_addr.respond_to?(:addr_spec) && tree.angle_addr.addr_spec.respond_to?(:domain)
190
- @domain_text ||= tree.angle_addr.addr_spec.domain.text_value.strip
191
- elsif tree.respond_to?(:domain)
192
- @domain_text ||= tree.domain.text_value.strip
193
- elsif tree.respond_to?(:addr_spec) && tree.addr_spec.respond_to?(:domain)
194
- tree.addr_spec.domain.text_value.strip
195
- else
196
- nil
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
197
195
  end
198
196
  end
199
197
 
200
198
  def strip_all_comments(string)
201
- unless comments.blank?
199
+ unless Utilities.blank?(comments)
202
200
  comments.each do |comment|
203
- string = string.gsub("(#{comment})", '')
201
+ string = string.gsub("(#{comment})", Constants::EMPTY)
204
202
  end
205
203
  end
206
204
  string.strip
207
205
  end
208
206
 
209
207
  def strip_domain_comments(value)
210
- unless comments.blank?
208
+ unless Utilities.blank?(comments)
211
209
  comments.each do |comment|
212
- if get_domain && get_domain.include?("(#{comment})")
213
- value = value.gsub("(#{comment})", '')
210
+ if @data.domain && @data.domain.include?("(#{comment})")
211
+ value = value.gsub("(#{comment})", Constants::EMPTY)
214
212
  end
215
213
  end
216
214
  end
217
215
  value.to_s.strip
218
216
  end
219
-
220
- def get_comments
221
- if tree.respond_to?(:comments)
222
- @comments = tree.comments.map { |c| unparen(c.text_value.to_str) }
223
- else
224
- @comments = []
225
- end
226
- end
227
-
217
+
228
218
  def get_display_name
229
- if tree.respond_to?(:display_name)
230
- name = unquote(tree.display_name.text_value.strip)
231
- str = strip_all_comments(name.to_s)
232
- elsif comments
233
- if domain
234
- str = strip_domain_comments(format_comments)
235
- else
236
- str = nil
237
- end
238
- else
239
- nil
240
- end
241
-
242
- if str.blank?
243
- nil
244
- else
245
- str
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)
246
223
  end
224
+ str unless Utilities.blank?(str)
247
225
  end
248
-
226
+
249
227
  def get_name
250
228
  if display_name
251
229
  str = display_name
252
- else
253
- if comments
254
- comment_text = comments.join(' ').squeeze(" ")
255
- str = "(#{comment_text})"
256
- end
230
+ elsif comments
231
+ str = "(#{comments.join(Constants::SPACE).squeeze(Constants::SPACE)})"
257
232
  end
258
233
 
259
- if str.blank?
260
- nil
261
- else
262
- unparen(str)
263
- end
264
- end
265
-
266
- # Provides access to the Treetop parse tree for this address
267
- def tree
268
- @tree
269
- end
270
-
271
- def tree=(value)
272
- @tree = value
234
+ Utilities.unparen(str) unless Utilities.blank?(str)
273
235
  end
274
-
236
+
275
237
  def format_comments
276
238
  if comments
277
- comment_text = comments.map {|c| escape_paren(c) }.join(' ').squeeze(" ")
239
+ comment_text = comments.map {|c| Utilities.escape_paren(c) }.join(Constants::SPACE).squeeze(Constants::SPACE)
278
240
  @format_comments ||= "(#{comment_text})"
279
241
  else
280
242
  nil
281
243
  end
282
244
  end
283
-
284
- def obs_domain_list
285
- if tree.respond_to?(:angle_addr)
286
- obs = tree.angle_addr.elements.select { |e| e.respond_to?(:obs_domain_list) }
287
- !obs.empty? ? obs.first.text_value : nil
288
- else
289
- nil
290
- end
291
- end
292
-
245
+
293
246
  def get_local
294
- case
295
- when tree.respond_to?(:local_dot_atom_text)
296
- tree.local_dot_atom_text.text_value
297
- when tree.respond_to?(:angle_addr) && tree.angle_addr.respond_to?(:addr_spec) && tree.angle_addr.addr_spec.respond_to?(:local_part)
298
- tree.angle_addr.addr_spec.local_part.text_value
299
- when tree.respond_to?(:addr_spec) && tree.addr_spec.respond_to?(:local_part)
300
- tree.addr_spec.local_part.text_value
301
- when tree.respond_to?(:angle_addr) && tree.angle_addr.respond_to?(:addr_spec) && tree.angle_addr.addr_spec.respond_to?(:local_dot_atom_text)
302
- # Ignore local dot atom text when in angle brackets
303
- nil
304
- when tree.respond_to?(:addr_spec) && tree.addr_spec.respond_to?(:local_dot_atom_text)
305
- # Ignore local dot atom text when in angle brackets
306
- nil
307
- else
308
- tree && tree.respond_to?(:local_part) ? tree.local_part.text_value : nil
309
- end
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
310
256
  end
311
-
312
-
313
257
  end
314
258
  end
@@ -1,74 +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
- class AddressList # :nodoc:
4
-
6
+ class AddressList #:nodoc:
7
+ attr_reader :addresses, :group_names
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
- if string.blank?
22
- @address_nodes = []
23
- return self
24
- end
25
- parser = Mail::AddressListsParser.new
26
- if tree = parser.parse(string)
27
- @address_nodes = tree.addresses
28
- else
29
- raise Mail::Field::ParseError.new(AddressListsParser, string, parser.failure_reason)
30
- 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
31
28
  end
32
-
33
- # Returns a list of address objects from the parsed line
34
- def addresses
35
- @addresses ||= get_addresses.map do |address_tree|
36
- Mail::Address.new(address_tree)
37
- end
38
- end
39
-
40
- # Returns a list of all recipient syntax trees that are not part of a group
41
- def individual_recipients # :nodoc:
42
- @individual_recipients ||= @address_nodes - group_recipients
43
- end
44
-
45
- # Returns a list of all recipient syntax trees that are part of a group
46
- def group_recipients # :nodoc:
47
- @group_recipients ||= @address_nodes.select { |an| an.respond_to?(:group_name) }
48
- end
49
-
50
- # Returns the names as an array of strings of all groups
51
- def group_names # :nodoc:
52
- group_recipients.map { |g| g.group_name.text_value }
53
- end
54
-
55
- # Returns a list of address syntax trees
56
- def address_nodes # :nodoc:
57
- @address_nodes
58
- end
59
-
60
- private
61
-
62
- def get_addresses
63
- (individual_recipients + group_recipients.map { |g| get_group_addresses(g) }).flatten
64
- end
65
-
66
- def get_group_addresses(g)
67
- if g.group_list.respond_to?(:addresses)
68
- g.group_list.addresses
69
- else
70
- []
71
- end
29
+
30
+ def addresses_grouped_by_group
31
+ addresses.select(&:group).group_by(&:group)
72
32
  end
73
33
  end
74
34
  end
@@ -1,30 +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
- class ContentDispositionElement # :nodoc:
4
-
5
- include Mail::Utilities
6
-
7
- def initialize( string )
8
- parser = Mail::ContentDispositionParser.new
9
- if tree = parser.parse(cleaned(string))
10
- @disposition_type = tree.disposition_type.text_value.downcase
11
- @parameters = tree.parameters
12
- else
13
- raise Mail::Field::ParseError.new(ContentDispositionElement, string, parser.failure_reason)
14
- end
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
15
13
  end
16
-
17
- def disposition_type
18
- @disposition_type
19
- end
20
-
21
- def parameters
22
- @parameters
23
- end
24
-
14
+
15
+ private
25
16
  def cleaned(string)
26
17
  string =~ /(.+);\s*$/ ? $1 : string
27
18
  end
28
-
29
19
  end
30
20
  end
@@ -1,25 +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
- class ContentLocationElement # :nodoc:
4
-
5
- include Mail::Utilities
6
-
7
- def initialize( string )
8
- parser = Mail::ContentLocationParser.new
9
- if tree = parser.parse(string)
10
- @location = tree.location.text_value
11
- else
12
- raise Mail::Field::ParseError.new(ContentLocationElement, string, parser.failure_reason)
13
- end
6
+ class ContentLocationElement #:nodoc:
7
+ attr_reader :location
8
+
9
+ def initialize(string)
10
+ @location = Mail::Parsers::ContentLocationParser.parse(string).location
14
11
  end
15
-
16
- def location
17
- @location
18
- end
19
-
12
+
20
13
  def to_s(*args)
21
14
  location.to_s
22
15
  end
23
-
24
16
  end
25
17
  end
@@ -1,24 +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
- class ContentTransferEncodingElement
4
-
5
- include Mail::Utilities
6
-
7
- def initialize( string )
8
- parser = Mail::ContentTransferEncodingParser.new
9
- case
10
- when string.blank?
11
- @encoding = ''
12
- when tree = parser.parse(string.to_s.downcase)
13
- @encoding = tree.encoding.text_value
14
- else
15
- raise Mail::Field::ParseError.new(ContentTransferEncodingElement, string, parser.failure_reason)
16
- end
6
+ class ContentTransferEncodingElement #:nodoc:
7
+ attr_reader :encoding
8
+
9
+ def initialize(string)
10
+ @encoding = Mail::Parsers::ContentTransferEncodingParser.parse(string).encoding
17
11
  end
18
-
19
- def encoding
20
- @encoding
21
- end
22
-
23
12
  end
24
13
  end