mail 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mail might be problematic. Click here for more details.

Files changed (107) hide show
  1. data/.gitignore +4 -0
  2. data/Manifest.txt +106 -0
  3. data/README.rdoc +441 -0
  4. data/Rakefile +38 -0
  5. data/lib/mail.rb +86 -0
  6. data/lib/mail/attachment.rb +90 -0
  7. data/lib/mail/body.rb +149 -0
  8. data/lib/mail/configuration.rb +90 -0
  9. data/lib/mail/core_extensions.rb +6 -0
  10. data/lib/mail/core_extensions/blank.rb +41 -0
  11. data/lib/mail/core_extensions/nil.rb +15 -0
  12. data/lib/mail/core_extensions/string.rb +31 -0
  13. data/lib/mail/elements/address.rb +293 -0
  14. data/lib/mail/elements/address_list.rb +62 -0
  15. data/lib/mail/elements/content_disposition_element.rb +34 -0
  16. data/lib/mail/elements/content_transfer_encoding_element.rb +21 -0
  17. data/lib/mail/elements/content_type_element.rb +39 -0
  18. data/lib/mail/elements/date_time_element.rb +26 -0
  19. data/lib/mail/elements/envelope_from_element.rb +34 -0
  20. data/lib/mail/elements/message_ids_element.rb +29 -0
  21. data/lib/mail/elements/mime_version_element.rb +26 -0
  22. data/lib/mail/elements/phrase_list.rb +21 -0
  23. data/lib/mail/elements/received_element.rb +30 -0
  24. data/lib/mail/encodings/base64.rb +17 -0
  25. data/lib/mail/encodings/encodings.rb +24 -0
  26. data/lib/mail/encodings/quoted_printable.rb +26 -0
  27. data/lib/mail/envelope.rb +35 -0
  28. data/lib/mail/field.rb +202 -0
  29. data/lib/mail/field_list.rb +33 -0
  30. data/lib/mail/fields/bcc_field.rb +40 -0
  31. data/lib/mail/fields/cc_field.rb +40 -0
  32. data/lib/mail/fields/comments_field.rb +41 -0
  33. data/lib/mail/fields/common/common_address.rb +62 -0
  34. data/lib/mail/fields/common/common_date.rb +35 -0
  35. data/lib/mail/fields/common/common_field.rb +128 -0
  36. data/lib/mail/fields/common/common_message_id.rb +35 -0
  37. data/lib/mail/fields/content_description_field.rb +15 -0
  38. data/lib/mail/fields/content_disposition_field.rb +34 -0
  39. data/lib/mail/fields/content_id_field.rb +50 -0
  40. data/lib/mail/fields/content_transfer_encoding_field.rb +28 -0
  41. data/lib/mail/fields/content_type_field.rb +50 -0
  42. data/lib/mail/fields/date_field.rb +44 -0
  43. data/lib/mail/fields/from_field.rb +40 -0
  44. data/lib/mail/fields/in_reply_to_field.rb +42 -0
  45. data/lib/mail/fields/keywords_field.rb +22 -0
  46. data/lib/mail/fields/message_id_field.rb +70 -0
  47. data/lib/mail/fields/mime_version_field.rb +42 -0
  48. data/lib/mail/fields/optional_field.rb +11 -0
  49. data/lib/mail/fields/received_field.rb +49 -0
  50. data/lib/mail/fields/references_field.rb +42 -0
  51. data/lib/mail/fields/reply_to_field.rb +40 -0
  52. data/lib/mail/fields/resent_bcc_field.rb +40 -0
  53. data/lib/mail/fields/resent_cc_field.rb +40 -0
  54. data/lib/mail/fields/resent_date_field.rb +16 -0
  55. data/lib/mail/fields/resent_from_field.rb +40 -0
  56. data/lib/mail/fields/resent_message_id_field.rb +20 -0
  57. data/lib/mail/fields/resent_sender_field.rb +48 -0
  58. data/lib/mail/fields/resent_to_field.rb +40 -0
  59. data/lib/mail/fields/return_path_field.rb +34 -0
  60. data/lib/mail/fields/sender_field.rb +48 -0
  61. data/lib/mail/fields/structured_field.rb +32 -0
  62. data/lib/mail/fields/subject_field.rb +14 -0
  63. data/lib/mail/fields/to_field.rb +40 -0
  64. data/lib/mail/fields/unstructured_field.rb +27 -0
  65. data/lib/mail/header.rb +213 -0
  66. data/lib/mail/mail.rb +120 -0
  67. data/lib/mail/message.rb +648 -0
  68. data/lib/mail/network/deliverable.rb +42 -0
  69. data/lib/mail/network/retrievable.rb +63 -0
  70. data/lib/mail/parsers/address_lists.rb +61 -0
  71. data/lib/mail/parsers/address_lists.treetop +19 -0
  72. data/lib/mail/parsers/content_disposition.rb +358 -0
  73. data/lib/mail/parsers/content_disposition.treetop +45 -0
  74. data/lib/mail/parsers/content_transfer_encoding.rb +179 -0
  75. data/lib/mail/parsers/content_transfer_encoding.treetop +25 -0
  76. data/lib/mail/parsers/content_type.rb +507 -0
  77. data/lib/mail/parsers/content_type.treetop +58 -0
  78. data/lib/mail/parsers/date_time.rb +111 -0
  79. data/lib/mail/parsers/date_time.treetop +11 -0
  80. data/lib/mail/parsers/envelope_from.rb +188 -0
  81. data/lib/mail/parsers/envelope_from.treetop +32 -0
  82. data/lib/mail/parsers/message_ids.rb +42 -0
  83. data/lib/mail/parsers/message_ids.treetop +15 -0
  84. data/lib/mail/parsers/mime_version.rb +141 -0
  85. data/lib/mail/parsers/mime_version.treetop +19 -0
  86. data/lib/mail/parsers/phrase_lists.rb +42 -0
  87. data/lib/mail/parsers/phrase_lists.treetop +15 -0
  88. data/lib/mail/parsers/received.rb +68 -0
  89. data/lib/mail/parsers/received.treetop +11 -0
  90. data/lib/mail/parsers/rfc2045.rb +406 -0
  91. data/lib/mail/parsers/rfc2045.treetop +35 -0
  92. data/lib/mail/parsers/rfc2822.rb +5005 -0
  93. data/lib/mail/parsers/rfc2822.treetop +402 -0
  94. data/lib/mail/parsers/rfc2822_obsolete.rb +3607 -0
  95. data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
  96. data/lib/mail/part.rb +120 -0
  97. data/lib/mail/patterns.rb +42 -0
  98. data/lib/mail/utilities.rb +142 -0
  99. data/lib/mail/version.rb +10 -0
  100. data/lib/mail/version_specific/multibyte.rb +62 -0
  101. data/lib/mail/version_specific/multibyte/chars.rb +701 -0
  102. data/lib/mail/version_specific/multibyte/exceptions.rb +8 -0
  103. data/lib/mail/version_specific/multibyte/unicode_database.rb +71 -0
  104. data/lib/mail/version_specific/ruby_1_8.rb +61 -0
  105. data/lib/mail/version_specific/ruby_1_8_string.rb +88 -0
  106. data/lib/mail/version_specific/ruby_1_9.rb +49 -0
  107. metadata +192 -0
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ # Include this module to make a class "deliverable".
4
+ # It uses the defaults set in Configuration to retrieve SMTP settings.
5
+ #
6
+ # Thanks to Nicolas Fouché for this wrapper
7
+ #
8
+ module Mail
9
+ module Deliverable
10
+
11
+ # Send the message via SMTP.
12
+ # The from and to attributes are optional. If not set, they are retrieve from the Message.
13
+ def deliver!(from = nil, to = nil, rfc2822 = nil)
14
+ config = Mail::Configuration.instance
15
+ if config.smtp.blank? || config.smtp[0].blank?
16
+ raise ArgumentError.new('Please call +Mail.defaults+ to set the SMTP configuration')
17
+ end
18
+
19
+ # TODO: use the "return-path" field by default instead of the "from" field ? (see ActionMailer)
20
+ from ||= self.from.addresses.first if self.respond_to?(:from) && self.from
21
+ raise ArgumentError.new('An author -from- is required to send a message') if from.blank?
22
+ to ||= self.to.addresses if self.respond_to?(:to) && self.to
23
+ raise ArgumentError.new('At least one recipient -from- is required to send a message') if to.blank?
24
+ rfc2822 ||= self.encoded if self.respond_to?(:encoded)
25
+ raise ArgumentError.new('A encoded content is required to send a message') if rfc2822.blank?
26
+
27
+ smtp = Net::SMTP.new(config.smtp[0], config.smtp[1] || 25)
28
+ if config.tls?
29
+ smtp.enable_tls(OpenSSL::SSL::VERIFY_NONE)
30
+ else
31
+ smtp.enable_starttls_auto if smtp.respond_to?(:enable_starttls_auto)
32
+ end
33
+
34
+ smtp.start(helo = 'localhost.localdomain', config.user, config.pass, authentication = :plain) do |smtp|
35
+ smtp.sendmail(rfc2822, from, to)
36
+ end
37
+
38
+ self
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ # Include this module to retrieve emails via POP3. Each email retrieved is given to a new instance of the "includer".
4
+ # This module uses the defaults set in Configuration to retrieve POP3 settings.
5
+ #
6
+ # Thanks to Nicolas Fouché for this wrapper
7
+ #
8
+ module Mail
9
+ module Retrievable
10
+
11
+ module ClassMethods
12
+
13
+ # Get all emails via POP3.
14
+ # TODO :limit option
15
+ # TODO :order option
16
+ def pop3_get_all_mail(&block)
17
+ config = Mail::Configuration.instance
18
+ if config.pop3.blank? || config.pop3[0].blank?
19
+ raise ArgumentError.new('Please call +Mail.defaults+ to set the POP3 configuration')
20
+ end
21
+
22
+ pop3_start do |pop3|
23
+ if block_given?
24
+ pop3.each_mail do |pop_mail|
25
+ yield self.new(pop_mail.pop)
26
+ end
27
+ else
28
+ emails = []
29
+ pop3.each_mail do |pop_mail|
30
+ emails << self.new(pop_mail.pop)
31
+ end
32
+ emails
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ private
39
+
40
+ def pop3_start(config = Mail::Configuration.instance, &block)
41
+ raise ArgumentError.new("Mail::Retrievable#pop3_start takes a block") unless block_given?
42
+
43
+ pop3 = Net::POP3.new(config.pop3[0], config.pop3[1] || 110, isapop = false)
44
+ pop3.enable_ssl(verify = OpenSSL::SSL::VERIFY_NONE) if config.tls?
45
+ pop3.start(config.user, config.pass)
46
+
47
+ yield pop3
48
+ ensure
49
+ if defined?(pop3) && pop3 && pop3.started?
50
+ pop3.reset # This clears all "deleted" marks from messages.
51
+ pop3.finish
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ def self.included(receiver)
58
+ receiver.extend ClassMethods
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,61 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Mail
5
+ module AddressLists
6
+ include Treetop::Runtime
7
+
8
+ def root
9
+ @root || :primary_address
10
+ end
11
+
12
+ include RFC2822
13
+
14
+ module PrimaryAddress0
15
+ def addresses
16
+ [first_addr] + other_addr.elements.map { |o| o.addr_value }
17
+ end
18
+ end
19
+
20
+ module PrimaryAddress1
21
+ def addresses
22
+ [first_addr] + other_addr.elements.map { |o| o.addr_value }
23
+ end
24
+ end
25
+
26
+ def _nt_primary_address
27
+ start_index = index
28
+ if node_cache[:primary_address].has_key?(index)
29
+ cached = node_cache[:primary_address][index]
30
+ @index = cached.interval.end if cached
31
+ return cached
32
+ end
33
+
34
+ i0 = index
35
+ r1 = _nt_address_list
36
+ r1.extend(PrimaryAddress0)
37
+ if r1
38
+ r0 = r1
39
+ else
40
+ r2 = _nt_obs_addr_list
41
+ r2.extend(PrimaryAddress1)
42
+ if r2
43
+ r0 = r2
44
+ else
45
+ @index = i0
46
+ r0 = nil
47
+ end
48
+ end
49
+
50
+ node_cache[:primary_address][start_index] = r0
51
+
52
+ r0
53
+ end
54
+
55
+ end
56
+
57
+ class AddressListsParser < Treetop::Runtime::CompiledParser
58
+ include AddressLists
59
+ end
60
+
61
+ end
@@ -0,0 +1,19 @@
1
+ module Mail
2
+ grammar AddressLists
3
+
4
+ include RFC2822
5
+
6
+ rule primary_address
7
+ address_list {
8
+ def addresses
9
+ [first_addr] + other_addr.elements.map { |o| o.addr_value }
10
+ end
11
+ } / obs_addr_list {
12
+ def addresses
13
+ [first_addr] + other_addr.elements.map { |o| o.addr_value }
14
+ end
15
+ }
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,358 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Mail
5
+ module ContentDisposition
6
+ include Treetop::Runtime
7
+
8
+ def root
9
+ @root || :content_disposition
10
+ end
11
+
12
+ include RFC2822
13
+
14
+ include RFC2045
15
+
16
+ module ContentDisposition0
17
+ def CFWS1
18
+ elements[0]
19
+ end
20
+
21
+ def parameter
22
+ elements[2]
23
+ end
24
+
25
+ def CFWS2
26
+ elements[3]
27
+ end
28
+ end
29
+
30
+ module ContentDisposition1
31
+ def disposition_type
32
+ elements[0]
33
+ end
34
+
35
+ def param_hashes
36
+ elements[1]
37
+ end
38
+ end
39
+
40
+ module ContentDisposition2
41
+ def parameters
42
+ param_hashes.elements.map do |param|
43
+ param.parameter.param_hash
44
+ end
45
+ end
46
+ end
47
+
48
+ def _nt_content_disposition
49
+ start_index = index
50
+ if node_cache[:content_disposition].has_key?(index)
51
+ cached = node_cache[:content_disposition][index]
52
+ @index = cached.interval.end if cached
53
+ return cached
54
+ end
55
+
56
+ i0, s0 = index, []
57
+ r1 = _nt_disposition_type
58
+ s0 << r1
59
+ if r1
60
+ s2, i2 = [], index
61
+ loop do
62
+ i3, s3 = index, []
63
+ r4 = _nt_CFWS
64
+ s3 << r4
65
+ if r4
66
+ if has_terminal?(";", false, index)
67
+ r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
68
+ @index += 1
69
+ else
70
+ terminal_parse_failure(";")
71
+ r5 = nil
72
+ end
73
+ s3 << r5
74
+ if r5
75
+ r6 = _nt_parameter
76
+ s3 << r6
77
+ if r6
78
+ r7 = _nt_CFWS
79
+ s3 << r7
80
+ end
81
+ end
82
+ end
83
+ if s3.last
84
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
85
+ r3.extend(ContentDisposition0)
86
+ else
87
+ @index = i3
88
+ r3 = nil
89
+ end
90
+ if r3
91
+ s2 << r3
92
+ else
93
+ break
94
+ end
95
+ end
96
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
97
+ s0 << r2
98
+ end
99
+ if s0.last
100
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
101
+ r0.extend(ContentDisposition1)
102
+ r0.extend(ContentDisposition2)
103
+ else
104
+ @index = i0
105
+ r0 = nil
106
+ end
107
+
108
+ node_cache[:content_disposition][start_index] = r0
109
+
110
+ r0
111
+ end
112
+
113
+ def _nt_disposition_type
114
+ start_index = index
115
+ if node_cache[:disposition_type].has_key?(index)
116
+ cached = node_cache[:disposition_type][index]
117
+ @index = cached.interval.end if cached
118
+ return cached
119
+ end
120
+
121
+ i0 = index
122
+ if has_terminal?("inline", false, index)
123
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 6))
124
+ @index += 6
125
+ else
126
+ terminal_parse_failure("inline")
127
+ r1 = nil
128
+ end
129
+ if r1
130
+ r0 = r1
131
+ else
132
+ if has_terminal?("attachment", false, index)
133
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 10))
134
+ @index += 10
135
+ else
136
+ terminal_parse_failure("attachment")
137
+ r2 = nil
138
+ end
139
+ if r2
140
+ r0 = r2
141
+ else
142
+ r3 = _nt_extension_token
143
+ if r3
144
+ r0 = r3
145
+ else
146
+ @index = i0
147
+ r0 = nil
148
+ end
149
+ end
150
+ end
151
+
152
+ node_cache[:disposition_type][start_index] = r0
153
+
154
+ r0
155
+ end
156
+
157
+ def _nt_extension_token
158
+ start_index = index
159
+ if node_cache[:extension_token].has_key?(index)
160
+ cached = node_cache[:extension_token][index]
161
+ @index = cached.interval.end if cached
162
+ return cached
163
+ end
164
+
165
+ i0 = index
166
+ r1 = _nt_ietf_token
167
+ if r1
168
+ r0 = r1
169
+ else
170
+ r2 = _nt_x_token
171
+ if r2
172
+ r0 = r2
173
+ else
174
+ @index = i0
175
+ r0 = nil
176
+ end
177
+ end
178
+
179
+ node_cache[:extension_token][start_index] = r0
180
+
181
+ r0
182
+ end
183
+
184
+ module Parameter0
185
+ def attr
186
+ elements[1]
187
+ end
188
+
189
+ def val
190
+ elements[3]
191
+ end
192
+
193
+ end
194
+
195
+ module Parameter1
196
+ def param_hash
197
+ {attr.text_value => val.text_value}
198
+ end
199
+ end
200
+
201
+ def _nt_parameter
202
+ start_index = index
203
+ if node_cache[:parameter].has_key?(index)
204
+ cached = node_cache[:parameter][index]
205
+ @index = cached.interval.end if cached
206
+ return cached
207
+ end
208
+
209
+ i0, s0 = index, []
210
+ r2 = _nt_CFWS
211
+ if r2
212
+ r1 = r2
213
+ else
214
+ r1 = instantiate_node(SyntaxNode,input, index...index)
215
+ end
216
+ s0 << r1
217
+ if r1
218
+ r3 = _nt_attribute
219
+ s0 << r3
220
+ if r3
221
+ if has_terminal?("=", false, index)
222
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
223
+ @index += 1
224
+ else
225
+ terminal_parse_failure("=")
226
+ r4 = nil
227
+ end
228
+ s0 << r4
229
+ if r4
230
+ r5 = _nt_value
231
+ s0 << r5
232
+ if r5
233
+ r7 = _nt_CFWS
234
+ if r7
235
+ r6 = r7
236
+ else
237
+ r6 = instantiate_node(SyntaxNode,input, index...index)
238
+ end
239
+ s0 << r6
240
+ end
241
+ end
242
+ end
243
+ end
244
+ if s0.last
245
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
246
+ r0.extend(Parameter0)
247
+ r0.extend(Parameter1)
248
+ else
249
+ @index = i0
250
+ r0 = nil
251
+ end
252
+
253
+ node_cache[:parameter][start_index] = r0
254
+
255
+ r0
256
+ end
257
+
258
+ def _nt_attribute
259
+ start_index = index
260
+ if node_cache[:attribute].has_key?(index)
261
+ cached = node_cache[:attribute][index]
262
+ @index = cached.interval.end if cached
263
+ return cached
264
+ end
265
+
266
+ s0, i0 = [], index
267
+ loop do
268
+ r1 = _nt_token
269
+ if r1
270
+ s0 << r1
271
+ else
272
+ break
273
+ end
274
+ end
275
+ if s0.empty?
276
+ @index = i0
277
+ r0 = nil
278
+ else
279
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
280
+ end
281
+
282
+ node_cache[:attribute][start_index] = r0
283
+
284
+ r0
285
+ end
286
+
287
+ module Value0
288
+ def text_value
289
+ quoted_content.text_value
290
+ end
291
+ end
292
+
293
+ def _nt_value
294
+ start_index = index
295
+ if node_cache[:value].has_key?(index)
296
+ cached = node_cache[:value][index]
297
+ @index = cached.interval.end if cached
298
+ return cached
299
+ end
300
+
301
+ i0 = index
302
+ r1 = _nt_quoted_string
303
+ r1.extend(Value0)
304
+ if r1
305
+ r0 = r1
306
+ else
307
+ s2, i2 = [], index
308
+ loop do
309
+ i3 = index
310
+ r4 = _nt_token
311
+ if r4
312
+ r3 = r4
313
+ else
314
+ if has_terminal?('\G[\\x3d]', true, index)
315
+ r5 = true
316
+ @index += 1
317
+ else
318
+ r5 = nil
319
+ end
320
+ if r5
321
+ r3 = r5
322
+ else
323
+ @index = i3
324
+ r3 = nil
325
+ end
326
+ end
327
+ if r3
328
+ s2 << r3
329
+ else
330
+ break
331
+ end
332
+ end
333
+ if s2.empty?
334
+ @index = i2
335
+ r2 = nil
336
+ else
337
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
338
+ end
339
+ if r2
340
+ r0 = r2
341
+ else
342
+ @index = i0
343
+ r0 = nil
344
+ end
345
+ end
346
+
347
+ node_cache[:value][start_index] = r0
348
+
349
+ r0
350
+ end
351
+
352
+ end
353
+
354
+ class ContentDispositionParser < Treetop::Runtime::CompiledParser
355
+ include ContentDisposition
356
+ end
357
+
358
+ end