mail 2.5.5 → 2.8.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.
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,52 +1,55 @@
1
1
  # encoding: utf-8
2
- require 'mail/fields/common/parameter_hash'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/fields/parameter_hash'
3
5
 
4
6
  module Mail
5
- class ContentTypeField < StructuredField
7
+ class ContentTypeField < NamedStructuredField #:nodoc:
8
+ NAME = 'Content-Type'
6
9
 
7
- FIELD_NAME = 'content-type'
8
- CAPITALIZED_FIELD = 'Content-Type'
10
+ class << self
11
+ def singular?
12
+ true
13
+ end
14
+
15
+ def with_boundary(type)
16
+ new "#{type}; boundary=#{generate_boundary}"
17
+ end
18
+
19
+ def generate_boundary
20
+ "--==_mimepart_#{Mail.random_tag}"
21
+ end
22
+ end
9
23
 
10
- def initialize(value = nil, charset = 'utf-8')
11
- self.charset = charset
12
- if value.class == Array
24
+ def initialize(value = nil, charset = nil)
25
+ if value.is_a? Array
13
26
  @main_type = value[0]
14
27
  @sub_type = value[1]
15
28
  @parameters = ParameterHash.new.merge!(value.last)
16
29
  else
17
30
  @main_type = nil
18
31
  @sub_type = nil
19
- @parameters = nil
20
- value = strip_field(FIELD_NAME, value)
32
+ value = value.to_s
21
33
  end
22
- ensure_filename_quoted(value)
23
- super(CAPITALIZED_FIELD, value, charset)
24
- self.parse
25
- self
26
- end
27
34
 
28
- def parse(val = value)
29
- unless val.blank?
30
- self.value = val
31
- @element = nil
32
- element
33
- end
35
+ super ensure_filename_quoted(value), charset
34
36
  end
35
37
 
36
38
  def element
37
- begin
38
- @element ||= Mail::ContentTypeElement.new(value)
39
- rescue
40
- attempt_to_clean
41
- end
39
+ @element ||=
40
+ begin
41
+ Mail::ContentTypeElement.new(value)
42
+ rescue Mail::Field::ParseError
43
+ attempt_to_clean
44
+ end
42
45
  end
43
46
 
44
47
  def attempt_to_clean
45
48
  # Sanitize the value, handle special cases
46
- @element ||= Mail::ContentTypeElement.new(sanatize(value))
47
- rescue
49
+ Mail::ContentTypeElement.new(sanitize(value))
50
+ rescue Mail::Field::ParseError
48
51
  # All else fails, just get the MIME media type
49
- @element ||= Mail::ContentTypeElement.new(get_mime_type(value))
52
+ Mail::ContentTypeElement.new(get_mime_type(value))
50
53
  end
51
54
 
52
55
  def main_type
@@ -60,31 +63,22 @@ module Mail
60
63
  def string
61
64
  "#{main_type}/#{sub_type}"
62
65
  end
66
+ alias_method :content_type, :string
63
67
 
64
68
  def default
65
69
  decoded
66
70
  end
67
71
 
68
- alias :content_type :string
69
-
70
72
  def parameters
71
- unless @parameters
73
+ unless defined? @parameters
72
74
  @parameters = ParameterHash.new
73
75
  element.parameters.each { |p| @parameters.merge!(p) }
74
76
  end
75
77
  @parameters
76
78
  end
77
79
 
78
- def ContentTypeField.with_boundary(type)
79
- new("#{type}; boundary=#{generate_boundary}")
80
- end
81
-
82
- def ContentTypeField.generate_boundary
83
- "--==_mimepart_#{Mail.random_tag}"
84
- end
85
-
86
80
  def value
87
- if @value.class == Array
81
+ if @value.is_a? Array
88
82
  "#{@main_type}/#{@sub_type}; #{stringify(parameters)}"
89
83
  else
90
84
  @value
@@ -96,34 +90,17 @@ module Mail
96
90
  end
97
91
 
98
92
  def filename
99
- case
100
- when parameters['filename']
101
- @filename = parameters['filename']
102
- when parameters['name']
103
- @filename = parameters['name']
104
- else
105
- @filename = nil
106
- end
107
- @filename
93
+ @filename ||= parameters['filename'] || parameters['name']
108
94
  end
109
95
 
110
- # TODO: Fix this up
111
96
  def encoded
112
- if parameters.length > 0
113
- p = ";\r\n\s#{parameters.encoded}"
114
- else
115
- p = ""
116
- end
117
- "#{CAPITALIZED_FIELD}: #{content_type}#{p}\r\n"
97
+ p = ";\r\n\s#{parameters.encoded}" if parameters && parameters.length > 0
98
+ "#{name}: #{content_type}#{p}\r\n"
118
99
  end
119
100
 
120
101
  def decoded
121
- if parameters.length > 0
122
- p = "; #{parameters.decoded}"
123
- else
124
- p = ""
125
- end
126
- "#{content_type}" + p
102
+ p = "; #{parameters.decoded}" if parameters && parameters.length > 0
103
+ "#{content_type}#{p}"
127
104
  end
128
105
 
129
106
  private
@@ -139,30 +116,24 @@ module Mail
139
116
 
140
117
  # Various special cases from random emails found that I am not going to change
141
118
  # the parser for
142
- def sanatize( val )
143
-
119
+ def sanitize(val)
144
120
  # TODO: check if there are cases where whitespace is not a separator
145
121
  val = val.
146
122
  gsub(/\s*=\s*/,'='). # remove whitespaces around equal sign
147
- tr(' ',';').
148
- squeeze(';').
149
- gsub(';', '; '). #use '; ' as a separator (or EOL)
123
+ gsub(/[; ]+/, '; '). #use '; ' as a separator (or EOL)
150
124
  gsub(/;\s*$/,'') #remove trailing to keep examples below
151
125
 
152
- if val =~ /(boundary=(\S*))/i
153
- val = "#{$`.downcase}boundary=#{$2}#{$'.downcase}"
126
+ if val =~ /((boundary|name|filename)=(\S*))/i
127
+ val = "#{$`.downcase}#{$2}=#{$3}#{$'.downcase}"
154
128
  else
155
129
  val.downcase!
156
130
  end
157
131
 
158
132
  case
159
- when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;;+(.*)$/i
160
- # Handles 'text/plain;; format="flowed"' (double semi colon)
161
- "#{$1}/#{$2}; #{$3}"
162
133
  when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
163
134
  # Microsoft helper:
164
135
  # Handles 'type/subtype;ISO-8559-1'
165
- "#{$1}/#{$2}; charset=#{quote_atom($3)}"
136
+ "#{$1}/#{$2}; charset=#{Utilities.quote_atom($3)}"
166
137
  when val.chomp =~ /^text;?$/i
167
138
  # Handles 'text;' and 'text'
168
139
  "text/plain;"
@@ -171,7 +142,7 @@ module Mail
171
142
  "text/plain; #{$2}"
172
143
  when val =~ /([\w\-]+\/[\w\-]+);\scharset="charset="(\w+)""/i
173
144
  # Handles text/html; charset="charset="GB2312""
174
- "#{$1}; charset=#{quote_atom($2)}"
145
+ "#{$1}; charset=#{Utilities.quote_atom($2)}"
175
146
  when val =~ /([\w\-]+\/[\w\-]+);\s+(.*)/i
176
147
  type = $1
177
148
  # Handles misquoted param values
@@ -179,19 +150,19 @@ module Mail
179
150
  # and: audio/x-midi;\r\n\sname=Part .exe
180
151
  params = $2.to_s.split(/\s+/)
181
152
  params = params.map { |i| i.to_s.chomp.strip }
182
- params = params.map { |i| i.split(/\s*\=\s*/) }
183
- params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
153
+ params = params.map { |i| i.split(/\s*\=\s*/, 2) }
154
+ params = params.map { |i| "#{i[0]}=#{Utilities.dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
184
155
  "#{type}; #{params}"
185
156
  when val =~ /^\s*$/
186
157
  'text/plain'
187
158
  else
188
- ''
159
+ val
189
160
  end
190
161
  end
191
162
 
192
- def get_mime_type( val )
193
- case
194
- when val =~ /^([\w\-]+)\/([\w\-]+);.+$/i
163
+ def get_mime_type(val)
164
+ case val
165
+ when /^([\w\-]+)\/([\w\-]+);.+$/i
195
166
  "#{$1}/#{$2}"
196
167
  else
197
168
  'text/plain'
@@ -1,57 +1,29 @@
1
1
  # encoding: utf-8
2
- #
3
- # = Date Field
4
- #
5
- # The Date field inherits from StructuredField and handles the Date: header
6
- # field in the email.
7
- #
8
- # Sending date to a mail message will instantiate a Mail::Field object that
9
- # has a DateField as its field type. This includes all Mail::CommonAddress
10
- # module instance methods.
11
- #
12
- # There must be excatly one Date field in an RFC2822 email.
13
- #
14
- # == Examples:
15
- #
16
- # mail = Mail.new
17
- # mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
18
- # mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
19
- # mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
20
- # mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
21
- # mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
22
- # mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
23
- #
24
- require 'mail/fields/common/common_date'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_date_field'
25
4
 
26
5
  module Mail
27
- class DateField < StructuredField
28
-
29
- include Mail::CommonDate
30
-
31
- FIELD_NAME = 'date'
32
- CAPITALIZED_FIELD = "Date"
33
-
34
- def initialize(value = nil, charset = 'utf-8')
35
- self.charset = charset
36
- if value.blank?
37
- value = ::DateTime.now.strftime('%a, %d %b %Y %H:%M:%S %z')
38
- else
39
- value = strip_field(FIELD_NAME, value)
40
- value.to_s.gsub!(/\(.*?\)/, '')
41
- value = ::DateTime.parse(value.to_s.squeeze(" ")).strftime('%a, %d %b %Y %H:%M:%S %z')
42
- end
43
- super(CAPITALIZED_FIELD, value, charset)
44
- rescue ArgumentError => e
45
- raise e unless "invalid date"==e.message
46
- end
47
-
48
- def encoded
49
- do_encode(CAPITALIZED_FIELD)
50
- end
51
-
52
- def decoded
53
- do_decode
54
- end
55
-
6
+ # = Date Field
7
+ #
8
+ # The Date field inherits from StructuredField and handles the Date: header
9
+ # field in the email.
10
+ #
11
+ # Sending date to a mail message will instantiate a Mail::Field object that
12
+ # has a DateField as its field type. This includes all Mail::CommonAddress
13
+ # module instance methods.
14
+ #
15
+ # There must be excatly one Date field in an RFC2822 email.
16
+ #
17
+ # == Examples:
18
+ #
19
+ # mail = Mail.new
20
+ # mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
21
+ # mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
22
+ # mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
23
+ # mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
24
+ # mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
25
+ # mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
26
+ class DateField < CommonDateField #:nodoc:
27
+ NAME = 'Date'
56
28
  end
57
29
  end
@@ -1,55 +1,34 @@
1
1
  # encoding: utf-8
2
- #
3
- # = From Field
4
- #
5
- # The From field inherits from StructuredField and handles the From: header
6
- # field in the email.
7
- #
8
- # Sending from to a mail message will instantiate a Mail::Field object that
9
- # has a FromField as its field type. This includes all Mail::CommonAddress
10
- # module instance metods.
11
- #
12
- # Only one From field can appear in a header, though it can have multiple
13
- # addresses and groups of addresses.
14
- #
15
- # == Examples:
16
- #
17
- # mail = Mail.new
18
- # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
19
- # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
20
- # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
21
- # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
22
- # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
23
- #
24
- # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
25
- # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
26
- # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
27
- # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
28
- #
29
- require 'mail/fields/common/common_address'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_address_field'
30
4
 
31
5
  module Mail
32
- class FromField < StructuredField
33
-
34
- include Mail::CommonAddress
35
-
36
- FIELD_NAME = 'from'
37
- CAPITALIZED_FIELD = 'From'
38
-
39
- def initialize(value = nil, charset = 'utf-8')
40
- self.charset = charset
41
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
42
- self.parse
43
- self
44
- end
45
-
46
- def encoded
47
- do_encode(CAPITALIZED_FIELD)
48
- end
49
-
50
- def decoded
51
- do_decode
52
- end
53
-
6
+ # = From Field
7
+ #
8
+ # The From field inherits from StructuredField and handles the From: header
9
+ # field in the email.
10
+ #
11
+ # Sending from to a mail message will instantiate a Mail::Field object that
12
+ # has a FromField as its field type. This includes all Mail::CommonAddress
13
+ # module instance metods.
14
+ #
15
+ # Only one From field can appear in a header, though it can have multiple
16
+ # addresses and groups of addresses.
17
+ #
18
+ # == Examples:
19
+ #
20
+ # mail = Mail.new
21
+ # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
22
+ # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
23
+ # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
24
+ # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
25
+ # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
26
+ #
27
+ # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
28
+ # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
29
+ # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
30
+ # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
31
+ class FromField < CommonAddressField #:nodoc:
32
+ NAME = 'From'
54
33
  end
55
34
  end
@@ -1,56 +1,46 @@
1
1
  # encoding: utf-8
2
- #
3
- # = In-Reply-To Field
4
- #
5
- # The In-Reply-To field inherits from StructuredField and handles the
6
- # In-Reply-To: header field in the email.
7
- #
8
- # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
9
- # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
10
- # module instance metods.
11
- #
12
- # Note that, the #message_ids method will return an array of message IDs without the
13
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
14
- #
15
- # Only one InReplyTo field can appear in a header, though it can have multiple
16
- # Message IDs.
17
- #
18
- # == Examples:
19
- #
20
- # mail = Mail.new
21
- # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
22
- # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
23
- # mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
24
- # mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
25
- # mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
26
- #
27
- # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
28
- #
29
- require 'mail/fields/common/common_message_id'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_message_id_field'
30
4
 
31
5
  module Mail
32
- class InReplyToField < StructuredField
33
-
34
- include Mail::CommonMessageId
35
-
36
- FIELD_NAME = 'in-reply-to'
37
- CAPITALIZED_FIELD = 'In-Reply-To'
38
-
39
- def initialize(value = nil, charset = 'utf-8')
40
- self.charset = charset
41
- value = value.join("\r\n\s") if value.is_a?(Array)
42
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
43
- self.parse
44
- self
45
- end
46
-
47
- def encoded
48
- do_encode(CAPITALIZED_FIELD)
6
+ # = In-Reply-To Field
7
+ #
8
+ # The In-Reply-To field inherits from StructuredField and handles the
9
+ # In-Reply-To: header field in the email.
10
+ #
11
+ # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
12
+ # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
13
+ # module instance metods.
14
+ #
15
+ # Note that, the #message_ids method will return an array of message IDs without the
16
+ # enclosing angle brackets which per RFC are not syntactically part of the message id.
17
+ #
18
+ # Only one InReplyTo field can appear in a header, though it can have multiple
19
+ # Message IDs.
20
+ #
21
+ # == Examples:
22
+ #
23
+ # mail = Mail.new
24
+ # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
25
+ # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
26
+ # mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
27
+ # mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
28
+ # mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
29
+ #
30
+ # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
31
+ class InReplyToField < CommonMessageIdField #:nodoc:
32
+ NAME = 'In-Reply-To'
33
+
34
+ def self.singular?
35
+ true
49
36
  end
50
-
51
- def decoded
52
- do_decode
37
+
38
+ def initialize(value = nil, charset = nil)
39
+ if value.is_a?(Array)
40
+ super value.join("\r\n\s"), charset
41
+ else
42
+ super
43
+ end
53
44
  end
54
-
55
45
  end
56
46
  end
@@ -1,44 +1,31 @@
1
1
  # encoding: utf-8
2
- #
3
- # keywords = "Keywords:" phrase *("," phrase) CRLF
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+
4
5
  module Mail
5
- class KeywordsField < StructuredField
6
-
7
- FIELD_NAME = 'keywords'
8
- CAPITALIZED_FIELD = 'Keywords'
9
-
10
- def initialize(value = nil, charset = 'utf-8')
11
- self.charset = charset
12
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
13
- self.parse
14
- self
15
- end
6
+ # keywords = "Keywords:" phrase *("," phrase) CRLF
7
+ class KeywordsField < NamedStructuredField #:nodoc:
8
+ NAME = 'Keywords'
16
9
 
17
- def parse(val = value)
18
- unless val.blank?
19
- @phrase_list ||= PhraseList.new(value)
20
- end
10
+ def element
11
+ @element ||= PhraseList.new(value)
21
12
  end
22
-
23
- def phrase_list
24
- @phrase_list ||= PhraseList.new(value)
25
- end
26
-
13
+
27
14
  def keywords
28
- phrase_list.phrases
29
- end
30
-
31
- def encoded
32
- "#{CAPITALIZED_FIELD}: #{keywords.join(",\r\n ")}\r\n"
33
- end
34
-
35
- def decoded
36
- keywords.join(', ')
15
+ element.phrases
37
16
  end
38
17
 
39
18
  def default
40
19
  keywords
41
20
  end
42
-
21
+
22
+ private
23
+ def do_decode
24
+ keywords.join(', ')
25
+ end
26
+
27
+ def do_encode
28
+ "#{name}: #{keywords.join(",\r\n ")}\r\n"
29
+ end
43
30
  end
44
31
  end
@@ -1,82 +1,37 @@
1
1
  # encoding: utf-8
2
- #
3
- # = Message-ID Field
4
- #
5
- # The Message-ID field inherits from StructuredField and handles the
6
- # Message-ID: header field in the email.
7
- #
8
- # Sending message_id to a mail message will instantiate a Mail::Field object that
9
- # has a MessageIdField as its field type. This includes all Mail::CommonMessageId
10
- # module instance metods.
11
- #
12
- # Only one MessageId field can appear in a header, and syntactically it can only have
13
- # one Message ID. The message_ids method call has been left in however as it will only
14
- # return the one message id, ie, an array of length 1.
15
- #
16
- # Note that, the #message_ids method will return an array of message IDs without the
17
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
18
- #
19
- # == Examples:
20
- #
21
- # mail = Mail.new
22
- # mail.message_id = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
23
- # mail.message_id #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
24
- # mail[:message_id] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
25
- # mail['message_id'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
26
- # mail['Message-ID'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
27
- #
28
- # mail[:message_id].message_id #=> 'F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom'
29
- # mail[:message_id].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
30
- #
31
- require 'mail/fields/common/common_message_id'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/common_message_id_field'
4
+ require 'mail/utilities'
32
5
 
33
6
  module Mail
34
- class MessageIdField < StructuredField
35
-
36
- include Mail::CommonMessageId
37
-
38
- FIELD_NAME = 'message-id'
39
- CAPITALIZED_FIELD = 'Message-ID'
40
-
41
- def initialize(value = nil, charset = 'utf-8')
42
- self.charset = charset
43
- @uniq = 1
44
- if value.blank?
45
- self.name = CAPITALIZED_FIELD
46
- self.value = generate_message_id
47
- else
48
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
49
- end
50
- self.parse
51
- self
7
+ # Only one Message-ID field may appear in a header.
8
+ #
9
+ # Note that parsed Message IDs do not contain their enclosing angle
10
+ # brackets which, per RFC, are not part of the ID.
11
+ #
12
+ # mail = Mail.new
13
+ # mail.message_id = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
14
+ # mail.message_id #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
15
+ # mail[:message_id] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
16
+ # mail['message_id'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
17
+ # mail['Message-ID'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::MessageIdField:0x180e1c4
18
+ #
19
+ # mail[:message_id].message_id #=> 'F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom'
20
+ # mail[:message_id].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
21
+ class MessageIdField < CommonMessageIdField #:nodoc:
22
+ NAME = 'Message-ID'
52
23
 
24
+ def self.singular?
25
+ true
53
26
  end
54
-
55
- def name
56
- 'Message-ID'
27
+
28
+ def initialize(value = nil, charset = nil)
29
+ value = Mail::Utilities.generate_message_id if Utilities.blank?(value)
30
+ super value, charset
57
31
  end
58
-
32
+
59
33
  def message_ids
60
34
  [message_id]
61
35
  end
62
-
63
- def to_s
64
- "<#{message_id}>"
65
- end
66
-
67
- def encoded
68
- do_encode(CAPITALIZED_FIELD)
69
- end
70
-
71
- def decoded
72
- do_decode
73
- end
74
-
75
- private
76
-
77
- def generate_message_id
78
- "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
79
- end
80
-
81
36
  end
82
37
  end