mail 2.6.4 → 2.9.0

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 (180) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +208 -156
  3. data/lib/mail/attachments_list.rb +13 -10
  4. data/lib/mail/body.rb +96 -107
  5. data/lib/mail/configuration.rb +2 -0
  6. data/lib/mail/constants.rb +27 -5
  7. data/lib/mail/elements/address.rb +61 -50
  8. data/lib/mail/elements/address_list.rb +11 -19
  9. data/lib/mail/elements/content_disposition_element.rb +9 -16
  10. data/lib/mail/elements/content_location_element.rb +6 -11
  11. data/lib/mail/elements/content_transfer_encoding_element.rb +6 -11
  12. data/lib/mail/elements/content_type_element.rb +16 -23
  13. data/lib/mail/elements/date_time_element.rb +7 -15
  14. data/lib/mail/elements/envelope_from_element.rb +22 -23
  15. data/lib/mail/elements/message_ids_element.rb +18 -13
  16. data/lib/mail/elements/mime_version_element.rb +7 -15
  17. data/lib/mail/elements/phrase_list.rb +12 -10
  18. data/lib/mail/elements/received_element.rb +27 -19
  19. data/lib/mail/encodings/7bit.rb +9 -14
  20. data/lib/mail/encodings/8bit.rb +2 -21
  21. data/lib/mail/encodings/base64.rb +11 -12
  22. data/lib/mail/encodings/binary.rb +3 -22
  23. data/lib/mail/encodings/identity.rb +24 -0
  24. data/lib/mail/encodings/quoted_printable.rb +6 -6
  25. data/lib/mail/encodings/transfer_encoding.rb +38 -29
  26. data/lib/mail/encodings/unix_to_unix.rb +4 -2
  27. data/lib/mail/encodings.rb +83 -56
  28. data/lib/mail/envelope.rb +11 -14
  29. data/lib/mail/field.rb +181 -130
  30. data/lib/mail/field_list.rb +61 -8
  31. data/lib/mail/fields/bcc_field.rb +33 -52
  32. data/lib/mail/fields/cc_field.rb +27 -49
  33. data/lib/mail/fields/comments_field.rb +26 -37
  34. data/lib/mail/fields/common_address_field.rb +162 -0
  35. data/lib/mail/fields/common_date_field.rb +56 -0
  36. data/lib/mail/fields/common_field.rb +77 -0
  37. data/lib/mail/fields/common_message_id_field.rb +41 -0
  38. data/lib/mail/fields/content_description_field.rb +6 -14
  39. data/lib/mail/fields/content_disposition_field.rb +11 -38
  40. data/lib/mail/fields/content_id_field.rb +23 -51
  41. data/lib/mail/fields/content_location_field.rb +10 -25
  42. data/lib/mail/fields/content_transfer_encoding_field.rb +30 -31
  43. data/lib/mail/fields/content_type_field.rb +53 -84
  44. data/lib/mail/fields/date_field.rb +22 -52
  45. data/lib/mail/fields/from_field.rb +27 -49
  46. data/lib/mail/fields/in_reply_to_field.rb +37 -49
  47. data/lib/mail/fields/keywords_field.rb +17 -31
  48. data/lib/mail/fields/message_id_field.rb +24 -71
  49. data/lib/mail/fields/mime_version_field.rb +18 -30
  50. data/lib/mail/fields/named_structured_field.rb +10 -0
  51. data/lib/mail/fields/named_unstructured_field.rb +10 -0
  52. data/lib/mail/fields/optional_field.rb +9 -8
  53. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +13 -11
  54. data/lib/mail/fields/received_field.rb +42 -57
  55. data/lib/mail/fields/references_field.rb +34 -49
  56. data/lib/mail/fields/reply_to_field.rb +27 -49
  57. data/lib/mail/fields/resent_bcc_field.rb +27 -49
  58. data/lib/mail/fields/resent_cc_field.rb +27 -49
  59. data/lib/mail/fields/resent_date_field.rb +4 -30
  60. data/lib/mail/fields/resent_from_field.rb +27 -49
  61. data/lib/mail/fields/resent_message_id_field.rb +4 -29
  62. data/lib/mail/fields/resent_sender_field.rb +26 -56
  63. data/lib/mail/fields/resent_to_field.rb +27 -49
  64. data/lib/mail/fields/return_path_field.rb +49 -54
  65. data/lib/mail/fields/sender_field.rb +33 -55
  66. data/lib/mail/fields/structured_field.rb +2 -30
  67. data/lib/mail/fields/subject_field.rb +8 -11
  68. data/lib/mail/fields/to_field.rb +27 -49
  69. data/lib/mail/fields/unstructured_field.rb +31 -47
  70. data/lib/mail/fields.rb +9 -0
  71. data/lib/mail/header.rb +71 -110
  72. data/lib/mail/mail.rb +34 -37
  73. data/lib/mail/matchers/attachment_matchers.rb +15 -0
  74. data/lib/mail/matchers/has_sent_mail.rb +21 -1
  75. data/lib/mail/message.rb +126 -127
  76. data/lib/mail/multibyte/chars.rb +24 -181
  77. data/lib/mail/multibyte/unicode.rb +11 -11
  78. data/lib/mail/multibyte/utils.rb +26 -43
  79. data/lib/mail/multibyte.rb +55 -16
  80. data/lib/mail/network/delivery_methods/exim.rb +8 -11
  81. data/lib/mail/network/delivery_methods/file_delivery.rb +15 -18
  82. data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  83. data/lib/mail/network/delivery_methods/sendmail.rb +32 -35
  84. data/lib/mail/network/delivery_methods/smtp.rb +125 -68
  85. data/lib/mail/network/delivery_methods/smtp_connection.rb +11 -16
  86. data/lib/mail/network/delivery_methods/test_mailer.rb +12 -13
  87. data/lib/mail/network/retriever_methods/base.rb +13 -13
  88. data/lib/mail/network/retriever_methods/imap.rb +25 -9
  89. data/lib/mail/network/retriever_methods/pop3.rb +25 -23
  90. data/lib/mail/network/retriever_methods/test_retriever.rb +3 -2
  91. data/lib/mail/network.rb +1 -0
  92. data/lib/mail/parser_tools.rb +15 -0
  93. data/lib/mail/parsers/address_lists_parser.rb +33228 -116
  94. data/lib/mail/parsers/address_lists_parser.rl +183 -0
  95. data/lib/mail/parsers/content_disposition_parser.rb +885 -49
  96. data/lib/mail/parsers/content_disposition_parser.rl +93 -0
  97. data/lib/mail/parsers/content_location_parser.rb +812 -23
  98. data/lib/mail/parsers/content_location_parser.rl +82 -0
  99. data/lib/mail/parsers/content_transfer_encoding_parser.rb +512 -21
  100. data/lib/mail/parsers/content_transfer_encoding_parser.rl +75 -0
  101. data/lib/mail/parsers/content_type_parser.rb +1039 -55
  102. data/lib/mail/parsers/content_type_parser.rl +94 -0
  103. data/lib/mail/parsers/date_time_parser.rb +880 -25
  104. data/lib/mail/parsers/date_time_parser.rl +73 -0
  105. data/lib/mail/parsers/envelope_from_parser.rb +3672 -40
  106. data/lib/mail/parsers/envelope_from_parser.rl +93 -0
  107. data/lib/mail/parsers/message_ids_parser.rb +5149 -25
  108. data/lib/mail/parsers/message_ids_parser.rl +97 -0
  109. data/lib/mail/parsers/mime_version_parser.rb +500 -26
  110. data/lib/mail/parsers/mime_version_parser.rl +72 -0
  111. data/lib/mail/parsers/phrase_lists_parser.rb +873 -22
  112. data/lib/mail/parsers/phrase_lists_parser.rl +94 -0
  113. data/lib/mail/parsers/received_parser.rb +8779 -43
  114. data/lib/mail/parsers/received_parser.rl +95 -0
  115. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  116. data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  117. data/lib/mail/parsers/rfc2045_mime.rl +16 -0
  118. data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  119. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  120. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  121. data/lib/mail/parsers/rfc5322.rl +74 -0
  122. data/lib/mail/parsers/rfc5322_address.rl +72 -0
  123. data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
  124. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  125. data/lib/mail/parsers.rb +11 -25
  126. data/lib/mail/part.rb +25 -29
  127. data/lib/mail/parts_list.rb +62 -6
  128. data/lib/mail/smtp_envelope.rb +57 -0
  129. data/lib/mail/utilities.rb +361 -74
  130. data/lib/mail/version.rb +2 -2
  131. data/lib/mail/yaml.rb +30 -0
  132. data/lib/mail.rb +4 -37
  133. metadata +125 -67
  134. data/CHANGELOG.rdoc +0 -787
  135. data/CONTRIBUTING.md +0 -60
  136. data/Dependencies.txt +0 -2
  137. data/Gemfile +0 -11
  138. data/Rakefile +0 -29
  139. data/TODO.rdoc +0 -9
  140. data/lib/mail/check_delivery_params.rb +0 -21
  141. data/lib/mail/core_extensions/smtp.rb +0 -25
  142. data/lib/mail/core_extensions/string/access.rb +0 -146
  143. data/lib/mail/core_extensions/string/multibyte.rb +0 -79
  144. data/lib/mail/core_extensions/string.rb +0 -21
  145. data/lib/mail/fields/common/address_container.rb +0 -17
  146. data/lib/mail/fields/common/common_address.rb +0 -136
  147. data/lib/mail/fields/common/common_date.rb +0 -36
  148. data/lib/mail/fields/common/common_field.rb +0 -61
  149. data/lib/mail/fields/common/common_message_id.rb +0 -49
  150. data/lib/mail/multibyte/exceptions.rb +0 -9
  151. data/lib/mail/parsers/ragel/common.rl +0 -185
  152. data/lib/mail/parsers/ragel/parser_info.rb +0 -61
  153. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
  154. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
  155. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
  156. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
  157. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
  158. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
  159. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
  160. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
  161. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
  162. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
  163. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
  164. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
  165. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2149
  166. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
  167. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
  168. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
  169. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
  170. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
  171. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
  172. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
  173. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
  174. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
  175. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
  176. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
  177. data/lib/mail/parsers/ragel/ruby.rb +0 -40
  178. data/lib/mail/parsers/ragel.rb +0 -18
  179. data/lib/mail/version_specific/ruby_1_8.rb +0 -126
  180. data/lib/mail/version_specific/ruby_1_9.rb +0 -223
@@ -1,45 +1,44 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- #
5
- #
3
+
6
4
  module Mail
7
- class ContentTransferEncodingField < StructuredField
8
-
9
- FIELD_NAME = 'content-transfer-encoding'
10
- CAPITALIZED_FIELD = 'Content-Transfer-Encoding'
11
-
12
- def initialize(value = nil, charset = 'utf-8')
13
- self.charset = charset
14
- value = '7bit' if value.to_s =~ /7-?bits?/i
15
- value = '8bit' if value.to_s =~ /8-?bits?/i
16
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
17
- self.parse
18
- self
5
+ class ContentTransferEncodingField < NamedStructuredField #:nodoc:
6
+ NAME = 'Content-Transfer-Encoding'
7
+
8
+ def self.singular?
9
+ true
19
10
  end
20
-
21
- def parse(val = value)
22
- unless Utilities.blank?(val)
23
- @element = Mail::ContentTransferEncodingElement.new(val)
11
+
12
+ def self.normalize_content_transfer_encoding(value)
13
+ case value
14
+ when /7-?bits?/i
15
+ '7bit'
16
+ when /8-?bits?/i
17
+ '8bit'
18
+ else
19
+ value
24
20
  end
25
21
  end
26
-
22
+
23
+ def initialize(value = nil, charset = nil)
24
+ super self.class.normalize_content_transfer_encoding(value), charset
25
+ end
26
+
27
27
  def element
28
28
  @element ||= Mail::ContentTransferEncodingElement.new(value)
29
29
  end
30
-
30
+
31
31
  def encoding
32
32
  element.encoding
33
33
  end
34
-
35
- # TODO: Fix this up
36
- def encoded
37
- "#{CAPITALIZED_FIELD}: #{encoding}\r\n"
38
- end
39
-
40
- def decoded
41
- encoding
42
- end
43
-
34
+
35
+ private
36
+ def do_encode
37
+ "#{name}: #{encoding}\r\n"
38
+ end
39
+
40
+ def do_decode
41
+ encoding
42
+ end
44
43
  end
45
44
  end
@@ -1,53 +1,53 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common/parameter_hash'
4
3
 
5
4
  module Mail
6
- class ContentTypeField < StructuredField
5
+ class ContentTypeField < NamedStructuredField #:nodoc:
6
+ NAME = 'Content-Type'
7
7
 
8
- FIELD_NAME = 'content-type'
9
- CAPITALIZED_FIELD = 'Content-Type'
8
+ class << self
9
+ def singular?
10
+ true
11
+ end
12
+
13
+ def with_boundary(type)
14
+ new "#{type}; boundary=#{generate_boundary}"
15
+ end
16
+
17
+ def generate_boundary
18
+ "--==_mimepart_#{Mail.random_tag}"
19
+ end
20
+ end
10
21
 
11
- def initialize(value = nil, charset = 'utf-8')
12
- self.charset = charset
13
- if value.class == Array
22
+ def initialize(value = nil, charset = nil)
23
+ if value.is_a? Array
14
24
  @main_type = value[0]
15
25
  @sub_type = value[1]
16
26
  @parameters = ParameterHash.new.merge!(value.last)
17
27
  else
18
28
  @main_type = nil
19
29
  @sub_type = nil
20
- @parameters = nil
21
- value = strip_field(FIELD_NAME, value)
30
+ value = value.to_s
22
31
  end
23
- value = ensure_filename_quoted(value)
24
- super(CAPITALIZED_FIELD, value, charset)
25
- self.parse
26
- self
27
- end
28
32
 
29
- def parse(val = value)
30
- unless Utilities.blank?(val)
31
- self.value = val
32
- @element = nil
33
- element
34
- end
33
+ super ensure_filename_quoted(value), charset
35
34
  end
36
35
 
37
36
  def element
38
- begin
39
- @element ||= Mail::ContentTypeElement.new(value)
40
- rescue
41
- attempt_to_clean
42
- end
37
+ @element ||=
38
+ begin
39
+ Mail::ContentTypeElement.new(value)
40
+ rescue Mail::Field::ParseError
41
+ attempt_to_clean
42
+ end
43
43
  end
44
44
 
45
45
  def attempt_to_clean
46
46
  # Sanitize the value, handle special cases
47
- @element ||= Mail::ContentTypeElement.new(sanatize(value))
48
- rescue
47
+ Mail::ContentTypeElement.new(sanitize(value))
48
+ rescue Mail::Field::ParseError
49
49
  # All else fails, just get the MIME media type
50
- @element ||= Mail::ContentTypeElement.new(get_mime_type(value))
50
+ Mail::ContentTypeElement.new(get_mime_type(value))
51
51
  end
52
52
 
53
53
  def main_type
@@ -61,31 +61,22 @@ module Mail
61
61
  def string
62
62
  "#{main_type}/#{sub_type}"
63
63
  end
64
+ alias_method :content_type, :string
64
65
 
65
66
  def default
66
67
  decoded
67
68
  end
68
69
 
69
- alias :content_type :string
70
-
71
70
  def parameters
72
- unless @parameters
71
+ unless defined? @parameters
73
72
  @parameters = ParameterHash.new
74
73
  element.parameters.each { |p| @parameters.merge!(p) }
75
74
  end
76
75
  @parameters
77
76
  end
78
77
 
79
- def ContentTypeField.with_boundary(type)
80
- new("#{type}; boundary=#{generate_boundary}")
81
- end
82
-
83
- def ContentTypeField.generate_boundary
84
- "--==_mimepart_#{Mail.random_tag}"
85
- end
86
-
87
78
  def value
88
- if @value.class == Array
79
+ if @value.is_a? Array
89
80
  "#{@main_type}/#{@sub_type}; #{stringify(parameters)}"
90
81
  else
91
82
  @value
@@ -97,34 +88,17 @@ module Mail
97
88
  end
98
89
 
99
90
  def filename
100
- case
101
- when parameters['filename']
102
- @filename = parameters['filename']
103
- when parameters['name']
104
- @filename = parameters['name']
105
- else
106
- @filename = nil
107
- end
108
- @filename
91
+ @filename ||= parameters['filename'] || parameters['name']
109
92
  end
110
93
 
111
- # TODO: Fix this up
112
94
  def encoded
113
- if parameters.length > 0
114
- p = ";\r\n\s#{parameters.encoded}"
115
- else
116
- p = ""
117
- end
118
- "#{CAPITALIZED_FIELD}: #{content_type}#{p}\r\n"
95
+ p = ";\r\n\s#{parameters.encoded}" if parameters && parameters.length > 0
96
+ "#{name}: #{content_type}#{p}\r\n"
119
97
  end
120
98
 
121
99
  def decoded
122
- if parameters.length > 0
123
- p = "; #{parameters.decoded}"
124
- else
125
- p = ""
126
- end
127
- "#{content_type}" + p
100
+ p = "; #{parameters.decoded}" if parameters && parameters.length > 0
101
+ "#{content_type}#{p}"
128
102
  end
129
103
 
130
104
  private
@@ -140,39 +114,34 @@ module Mail
140
114
 
141
115
  # Various special cases from random emails found that I am not going to change
142
116
  # the parser for
143
- def sanatize( val )
144
-
117
+ def sanitize(val)
145
118
  # TODO: check if there are cases where whitespace is not a separator
146
119
  val = val.
147
120
  gsub(/\s*=\s*/,'='). # remove whitespaces around equal sign
148
- tr(' ',';').
149
- squeeze(';').
150
- gsub(';', '; '). #use '; ' as a separator (or EOL)
121
+ gsub(/[; ]+/, '; '). #use '; ' as a separator (or EOL)
151
122
  gsub(/;\s*$/,'') #remove trailing to keep examples below
152
123
 
153
- if val =~ /(boundary=(\S*))/i
154
- val = "#{$`.downcase}boundary=#{$2}#{$'.downcase}"
124
+ if val =~ /((boundary|name|filename)=(\S*))/i
125
+ val = "#{$`.downcase}#{$2}=#{$3}#{$'.downcase}"
155
126
  else
156
127
  val.downcase!
157
128
  end
158
129
 
130
+ val_chomp = val.chomp
159
131
  case
160
- when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;;+(.*)$/i
161
- # Handles 'text/plain;; format="flowed"' (double semi colon)
162
- "#{$1}/#{$2}; #{$3}"
163
- when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
132
+ when val_chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
164
133
  # Microsoft helper:
165
134
  # Handles 'type/subtype;ISO-8559-1'
166
- "#{$1}/#{$2}; charset=#{quote_atom($3)}"
167
- when val.chomp =~ /^text;?$/i
135
+ "#{$1}/#{$2}; charset=#{Utilities.quote_atom($3)}"
136
+ when /^text;?$/i.match?(val_chomp)
168
137
  # Handles 'text;' and 'text'
169
138
  "text/plain;"
170
- when val.chomp =~ /^(\w+);\s(.*)$/i
139
+ when val_chomp =~ /^(\w+);\s(.*)$/i
171
140
  # Handles 'text; <parameters>'
172
141
  "text/plain; #{$2}"
173
142
  when val =~ /([\w\-]+\/[\w\-]+);\scharset="charset="(\w+)""/i
174
143
  # Handles text/html; charset="charset="GB2312""
175
- "#{$1}; charset=#{quote_atom($2)}"
144
+ "#{$1}; charset=#{Utilities.quote_atom($2)}"
176
145
  when val =~ /([\w\-]+\/[\w\-]+);\s+(.*)/i
177
146
  type = $1
178
147
  # Handles misquoted param values
@@ -180,19 +149,19 @@ module Mail
180
149
  # and: audio/x-midi;\r\n\sname=Part .exe
181
150
  params = $2.to_s.split(/\s+/)
182
151
  params = params.map { |i| i.to_s.chomp.strip }
183
- params = params.map { |i| i.split(/\s*\=\s*/) }
184
- params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
152
+ params = params.map { |i| i.split(/\s*\=\s*/, 2) }
153
+ params = params.map { |i| "#{i[0]}=#{Utilities.dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
185
154
  "#{type}; #{params}"
186
- when val =~ /^\s*$/
155
+ when /^\s*$/.match?(val)
187
156
  'text/plain'
188
157
  else
189
- ''
158
+ val
190
159
  end
191
160
  end
192
161
 
193
- def get_mime_type( val )
194
- case
195
- when val =~ /^([\w\-]+)\/([\w\-]+);.+$/i
162
+ def get_mime_type(val)
163
+ case val
164
+ when /^([\w\-]+)\/([\w\-]+);.+$/i
196
165
  "#{$1}/#{$2}"
197
166
  else
198
167
  'text/plain'
@@ -1,58 +1,28 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # = Date Field
5
- #
6
- # The Date field inherits from StructuredField and handles the Date: header
7
- # field in the email.
8
- #
9
- # Sending date to a mail message will instantiate a Mail::Field object that
10
- # has a DateField as its field type. This includes all Mail::CommonAddress
11
- # module instance methods.
12
- #
13
- # There must be excatly one Date field in an RFC2822 email.
14
- #
15
- # == Examples:
16
- #
17
- # mail = Mail.new
18
- # mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
19
- # mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
20
- # mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
21
- # mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
22
- # mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
23
- # mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
24
- #
25
- require 'mail/fields/common/common_date'
26
3
 
27
4
  module Mail
28
- class DateField < StructuredField
29
-
30
- include Mail::CommonDate
31
-
32
- FIELD_NAME = 'date'
33
- CAPITALIZED_FIELD = "Date"
34
-
35
- def initialize(value = nil, charset = 'utf-8')
36
- self.charset = charset
37
- if Utilities.blank?(value)
38
- value = ::DateTime.now.strftime('%a, %d %b %Y %H:%M:%S %z')
39
- else
40
- value = strip_field(FIELD_NAME, value)
41
- value.to_s.gsub!(/\(.*?\)/, '')
42
- value = ::DateTime.parse(value.to_s.squeeze(" ")).strftime('%a, %d %b %Y %H:%M:%S %z')
43
- end
44
- super(CAPITALIZED_FIELD, value, charset)
45
- rescue ArgumentError => e
46
- raise e unless "invalid date"==e.message
47
- end
48
-
49
- def encoded
50
- do_encode(CAPITALIZED_FIELD)
51
- end
52
-
53
- def decoded
54
- do_decode
55
- end
56
-
5
+ # = Date Field
6
+ #
7
+ # The Date field inherits from StructuredField and handles the Date: header
8
+ # field in the email.
9
+ #
10
+ # Sending date to a mail message will instantiate a Mail::Field object that
11
+ # has a DateField as its field type. This includes all Mail::CommonAddress
12
+ # module instance methods.
13
+ #
14
+ # There must be excatly one Date field in an RFC2822 email.
15
+ #
16
+ # == Examples:
17
+ #
18
+ # mail = Mail.new
19
+ # mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
20
+ # mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
21
+ # mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
22
+ # mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
23
+ # mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
24
+ # mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
25
+ class DateField < CommonDateField #:nodoc:
26
+ NAME = 'Date'
57
27
  end
58
28
  end
@@ -1,55 +1,33 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # = From Field
5
- #
6
- # The From field inherits from StructuredField and handles the From: header
7
- # field in the email.
8
- #
9
- # Sending from to a mail message will instantiate a Mail::Field object that
10
- # has a FromField as its field type. This includes all Mail::CommonAddress
11
- # module instance metods.
12
- #
13
- # Only one From field can appear in a header, though it can have multiple
14
- # addresses and groups of addresses.
15
- #
16
- # == Examples:
17
- #
18
- # mail = Mail.new
19
- # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
20
- # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
21
- # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
22
- # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
23
- # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
24
- #
25
- # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
26
- # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
27
- # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
28
- # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
29
- #
30
- require 'mail/fields/common/common_address'
31
3
 
32
4
  module Mail
33
- class FromField < StructuredField
34
-
35
- include Mail::CommonAddress
36
-
37
- FIELD_NAME = 'from'
38
- CAPITALIZED_FIELD = 'From'
39
-
40
- def initialize(value = nil, charset = 'utf-8')
41
- self.charset = charset
42
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
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
-
5
+ # = From Field
6
+ #
7
+ # The From field inherits from StructuredField and handles the From: header
8
+ # field in the email.
9
+ #
10
+ # Sending from to a mail message will instantiate a Mail::Field object that
11
+ # has a FromField as its field type. This includes all Mail::CommonAddress
12
+ # module instance metods.
13
+ #
14
+ # Only one From field can appear in a header, though it can have multiple
15
+ # addresses and groups of addresses.
16
+ #
17
+ # == Examples:
18
+ #
19
+ # mail = Mail.new
20
+ # mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
21
+ # mail.from #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
22
+ # mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
23
+ # mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
24
+ # mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
25
+ #
26
+ # mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
27
+ # mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
28
+ # mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
29
+ # mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
30
+ class FromField < CommonAddressField #:nodoc:
31
+ NAME = 'From'
54
32
  end
55
33
  end
@@ -1,57 +1,45 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # = In-Reply-To Field
5
- #
6
- # The In-Reply-To field inherits from StructuredField and handles the
7
- # In-Reply-To: header field in the email.
8
- #
9
- # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
10
- # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
11
- # module instance metods.
12
- #
13
- # Note that, the #message_ids method will return an array of message IDs without the
14
- # enclosing angle brackets which per RFC are not syntactically part of the message id.
15
- #
16
- # Only one InReplyTo field can appear in a header, though it can have multiple
17
- # Message IDs.
18
- #
19
- # == Examples:
20
- #
21
- # mail = Mail.new
22
- # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
23
- # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
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
- # mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
27
- #
28
- # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
29
- #
30
- require 'mail/fields/common/common_message_id'
31
3
 
32
4
  module Mail
33
- class InReplyToField < StructuredField
34
-
35
- include Mail::CommonMessageId
36
-
37
- FIELD_NAME = 'in-reply-to'
38
- CAPITALIZED_FIELD = 'In-Reply-To'
39
-
40
- def initialize(value = nil, charset = 'utf-8')
41
- self.charset = charset
42
- value = value.join("\r\n\s") if value.is_a?(Array)
43
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
44
- self.parse
45
- self
46
- end
47
-
48
- def encoded
49
- do_encode(CAPITALIZED_FIELD)
5
+ # = In-Reply-To Field
6
+ #
7
+ # The In-Reply-To field inherits from StructuredField and handles the
8
+ # In-Reply-To: header field in the email.
9
+ #
10
+ # Sending in_reply_to to a mail message will instantiate a Mail::Field object that
11
+ # has a InReplyToField as its field type. This includes all Mail::CommonMessageId
12
+ # module instance metods.
13
+ #
14
+ # Note that, the #message_ids method will return an array of message IDs without the
15
+ # enclosing angle brackets which per RFC are not syntactically part of the message id.
16
+ #
17
+ # Only one InReplyTo field can appear in a header, though it can have multiple
18
+ # Message IDs.
19
+ #
20
+ # == Examples:
21
+ #
22
+ # mail = Mail.new
23
+ # mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
24
+ # mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
25
+ # mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
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
+ #
29
+ # mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
30
+ class InReplyToField < CommonMessageIdField #:nodoc:
31
+ NAME = 'In-Reply-To'
32
+
33
+ def self.singular?
34
+ true
50
35
  end
51
-
52
- def decoded
53
- do_decode
36
+
37
+ def initialize(value = nil, charset = nil)
38
+ if value.is_a?(Array)
39
+ super value.join("\r\n\s"), charset
40
+ else
41
+ super
42
+ end
54
43
  end
55
-
56
44
  end
57
45
  end
@@ -1,44 +1,30 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- #
4
- # keywords = "Keywords:" phrase *("," phrase) CRLF
3
+
5
4
  module Mail
6
- class KeywordsField < StructuredField
7
-
8
- FIELD_NAME = 'keywords'
9
- CAPITALIZED_FIELD = 'Keywords'
10
-
11
- def initialize(value = nil, charset = 'utf-8')
12
- self.charset = charset
13
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
14
- self
15
- end
5
+ # keywords = "Keywords:" phrase *("," phrase) CRLF
6
+ class KeywordsField < NamedStructuredField #:nodoc:
7
+ NAME = 'Keywords'
16
8
 
17
- def parse(val = value)
18
- unless Utilities.blank?(val)
19
- @phrase_list ||= PhraseList.new(value)
20
- end
9
+ def element
10
+ @element ||= PhraseList.new(value)
21
11
  end
22
-
23
- def phrase_list
24
- @phrase_list ||= PhraseList.new(value)
25
- end
26
-
12
+
27
13
  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(', ')
14
+ element.phrases
37
15
  end
38
16
 
39
17
  def default
40
18
  keywords
41
19
  end
42
-
20
+
21
+ private
22
+ def do_decode
23
+ keywords.join(', ')
24
+ end
25
+
26
+ def do_encode
27
+ "#{name}: #{keywords.join(",\r\n ")}\r\n"
28
+ end
43
29
  end
44
30
  end