mail 1.6.0 → 2.0.3
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.
- data/CHANGELOG.rdoc +37 -0
- data/README.rdoc +9 -10
- data/Rakefile +1 -1
- data/lib/mail.rb +3 -3
- data/lib/mail/attachments_list.rb +76 -0
- data/lib/mail/body.rb +16 -16
- data/lib/mail/configuration.rb +35 -111
- data/lib/mail/encodings/encodings.rb +4 -0
- data/lib/mail/fields/common/address_container.rb +16 -0
- data/lib/mail/fields/common/common_address.rb +28 -3
- data/lib/mail/fields/return_path_field.rb +4 -0
- data/lib/mail/mail.rb +69 -57
- data/lib/mail/message.rb +169 -58
- data/lib/mail/network/delivery_methods/file_delivery.rb +32 -10
- data/lib/mail/network/delivery_methods/sendmail.rb +52 -14
- data/lib/mail/network/delivery_methods/smtp.rb +85 -68
- data/lib/mail/network/delivery_methods/test_mailer.rb +7 -2
- data/lib/mail/network/retriever_methods/imap.rb +7 -6
- data/lib/mail/network/retriever_methods/pop3.rb +48 -73
- data/lib/mail/parts_list.rb +34 -0
- data/lib/mail/vendor/treetop-1.4.3/examples/lambda_calculus/arithmetic.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/examples/lambda_calculus/lambda_calculus.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler/metagrammar.rb +1 -1
- data/lib/mail/vendor/treetop.rb +1 -1
- data/lib/mail/version.rb +3 -3
- metadata +5 -5
- data/lib/mail/attachment.rb +0 -107
- data/lib/mail/network/deliverable.rb +0 -15
- data/lib/mail/network/retrievable.rb +0 -19
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,40 @@
|
|
1
|
+
== Sat Jan 23 05:32:53 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
2
|
+
|
3
|
+
* Version bump to 2.0.3
|
4
|
+
* Made body.sort_parts! recursive, to do the entire body
|
5
|
+
* Added ability to use << on the results returned by the various address fields, ie, mail.to << 'new@address' now works
|
6
|
+
* Message now adds multipart/mixed as the content type if nothing is set and there are parts to the message
|
7
|
+
* Added #display_names and #addrs to all address fields. #addrs returns the actual Mail::Address object for each address in the field.
|
8
|
+
* Body should call to_s on given input... incase someone gave it an IO.readlines result (Array)
|
9
|
+
*
|
10
|
+
|
11
|
+
== Thu Jan 21 05:27:17 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
12
|
+
|
13
|
+
* Version bump to 2.0.2
|
14
|
+
* Major change to attachments, add_file now only accepts
|
15
|
+
{:filename => 'full/path/to/file.png'} or
|
16
|
+
{:filename => 'file.png', :content => 'string of file content'}
|
17
|
+
you can also now do mail.attachments['filename.png'] = File.read('path/to/file.png')
|
18
|
+
which is nice too!
|
19
|
+
|
20
|
+
== Fri Jan 15 09:20:51 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
21
|
+
|
22
|
+
* Rewrote all network classes to not use singletons. Means different Mail::Message objects can have different delivery methods.
|
23
|
+
* Added examples for how to send via GMail, MobileMe, Sendmail, File etc.
|
24
|
+
* Version bump to 2.0.0 as Network API changed drastically, now not a singleton class.
|
25
|
+
* Fixed that return-path should only return one address
|
26
|
+
|
27
|
+
== Thu Jan 14 10:41:22 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
28
|
+
|
29
|
+
* Version update to 1.6.0 - API change on mail.address_fields to always return arrays
|
30
|
+
* Updated all message.address_field methods to always return arrays, so mail.from #=> ['one@address.com'] now, is least surprise
|
31
|
+
* Updated handling of empty group lists so it didn't crash
|
32
|
+
|
33
|
+
== Thu Jan 12 10:41:47 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
34
|
+
|
35
|
+
* Version 1.5.3, handling invalid input on fields. Highly recommended update
|
36
|
+
* Updated fields to always try parsing the given data (unless blank). This allows mail to catch invalid input and return UnstructuredFields. Makes mail a lot more resistant to invalid input.
|
37
|
+
|
1
38
|
== Fri 8 Jan 2010 00:00:08 UTC Mikel Lindsaar <raasdnil@gmail.com>
|
2
39
|
|
3
40
|
* Version bump to 1.5.2
|
data/README.rdoc
CHANGED
@@ -230,7 +230,7 @@ what you are doing.
|
|
230
230
|
to 'you@test.lindsaar.net'
|
231
231
|
subject 'Here is the image you wanted'
|
232
232
|
body File.read('body.txt')
|
233
|
-
add_file '/somefile.png'
|
233
|
+
add_file '/full/path/to/somefile.png'
|
234
234
|
end
|
235
235
|
|
236
236
|
or
|
@@ -244,11 +244,12 @@ or
|
|
244
244
|
to 'you@test.lindsaar.net'
|
245
245
|
subject 'Here is the image you wanted'
|
246
246
|
body File.read('body.txt')
|
247
|
-
add_file {:filename => 'somefile.png', :
|
247
|
+
add_file {:filename => 'somefile.png', :content => File.read('/somefile.png')}
|
248
248
|
end
|
249
249
|
|
250
250
|
mail.deliver!
|
251
251
|
|
252
|
+
|
252
253
|
=== Getting emails from a pop server:
|
253
254
|
|
254
255
|
The most recent email:
|
@@ -451,7 +452,7 @@ You can just read the file off an absolute path, Mail will try
|
|
451
452
|
to guess the mime_type and will encode the file in Base64 for you.
|
452
453
|
|
453
454
|
@mail = Mail.new
|
454
|
-
@mail.add_file(
|
455
|
+
@mail.add_file("/path/to/file.jpg")
|
455
456
|
@mail.parts.first.attachment? #=> true
|
456
457
|
@mail.parts.first.content_transfer_encoding.to_s #=> 'base64'
|
457
458
|
@mail.attachments.first.mime_type #=> 'image/jpg'
|
@@ -462,8 +463,7 @@ Or You can pass in file_data and give it a filename, again, mail
|
|
462
463
|
will try and guess the mime_type for you.
|
463
464
|
|
464
465
|
@mail = Mail.new
|
465
|
-
|
466
|
-
@mail.add_file(:filename => 'myfile.pdf', :data => file_data)
|
466
|
+
@mail.attachments['myfile.pdf'] = File.read('path/to/myfile.pdf')
|
467
467
|
@mail.parts.first.attachment? #=> true
|
468
468
|
@mail.attachments.first.mime_type #=> 'application/pdf'
|
469
469
|
@mail.attachments.first.decoded == File.read('path/to/myfile.pdf') #=> true
|
@@ -473,9 +473,8 @@ than mail (this should be rarely needed)
|
|
473
473
|
|
474
474
|
@mail = Mail.new
|
475
475
|
file_data = File.read('path/to/myfile.pdf')
|
476
|
-
@mail.
|
477
|
-
|
478
|
-
:mime_type => 'application/x-pdf')
|
476
|
+
@mail.attachments['myfile.pdf'] = { :mime_type => 'application/x-pdf',
|
477
|
+
:content => File.read('path/to/myfile.pdf') }
|
479
478
|
@mail.parts.first.mime_type #=> 'application/x-pdf'
|
480
479
|
|
481
480
|
Of course... Mail will round trip an attachment as well
|
@@ -491,7 +490,7 @@ Of course... Mail will round trip an attachment as well
|
|
491
490
|
content_type 'text/html; charset=UTF-8'
|
492
491
|
body '<h1>Funky Title</h1><p>Here is the attachment you wanted</p>'
|
493
492
|
end
|
494
|
-
add_file
|
493
|
+
add_file '/path/to/myfile.pdf'
|
495
494
|
end
|
496
495
|
|
497
496
|
@round_tripped_mail = Mail.new(@mail.encoded)
|
@@ -507,7 +506,7 @@ sending emails, the TestMailer can do this for you.
|
|
507
506
|
require 'mail'
|
508
507
|
=> true
|
509
508
|
Mail.defaults do
|
510
|
-
delivery_method
|
509
|
+
delivery_method :test
|
511
510
|
end
|
512
511
|
=> #<Mail::Configuration:0x19345a8 @delivery_method=Mail::TestMailer>
|
513
512
|
Mail.deliveries
|
data/Rakefile
CHANGED
data/lib/mail.rb
CHANGED
@@ -46,24 +46,24 @@ module Mail # :doc:
|
|
46
46
|
require 'mail/patterns'
|
47
47
|
require 'mail/utilities'
|
48
48
|
require 'mail/configuration'
|
49
|
-
require 'mail/network/deliverable'
|
50
49
|
require 'mail/network/delivery_methods/smtp'
|
51
50
|
require 'mail/network/delivery_methods/file_delivery'
|
52
51
|
require 'mail/network/delivery_methods/sendmail'
|
53
52
|
require 'mail/network/delivery_methods/test_mailer'
|
54
|
-
require 'mail/network/retrievable'
|
55
53
|
require 'mail/network/retriever_methods/pop3'
|
56
54
|
require 'mail/network/retriever_methods/imap'
|
57
55
|
|
58
56
|
require 'mail/message'
|
59
57
|
require 'mail/part'
|
60
58
|
require 'mail/header'
|
59
|
+
require 'mail/parts_list'
|
60
|
+
require 'mail/attachments_list'
|
61
61
|
require 'mail/body'
|
62
62
|
require 'mail/field'
|
63
63
|
require 'mail/field_list'
|
64
|
-
require 'mail/attachment'
|
65
64
|
|
66
65
|
# Load in all common header fields modules
|
66
|
+
require 'mail/fields/common/address_container'
|
67
67
|
require 'mail/fields/common/common_address'
|
68
68
|
require 'mail/fields/common/common_date'
|
69
69
|
require 'mail/fields/common/common_field'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Mail
|
2
|
+
class AttachmentsList < Array
|
3
|
+
|
4
|
+
def initialize(parts_list)
|
5
|
+
@parts_list = parts_list
|
6
|
+
parts_list.map { |p|
|
7
|
+
if p.parts.empty?
|
8
|
+
p if p.attachment?
|
9
|
+
else
|
10
|
+
p.attachments
|
11
|
+
end
|
12
|
+
}.flatten.compact.each { |a| self << a }
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the attachment by filename or at index.
|
17
|
+
#
|
18
|
+
# mail.attachments['test.png'] = File.read('test.png')
|
19
|
+
# mail.attachments['test.jpg'] = File.read('test.jpg')
|
20
|
+
#
|
21
|
+
# mail.attachments['test.png'].filename #=> 'test.png'
|
22
|
+
# mail.attachments[1].filename #=> 'test.jpg'
|
23
|
+
def [](index_value)
|
24
|
+
if index_value.is_a?(Fixnum)
|
25
|
+
self.fetch(index_value)
|
26
|
+
else
|
27
|
+
self.select { |a| a.filename == index_value }.first
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def []=(name, value)
|
32
|
+
default_values = { :content_type => "#{set_mime_type(name)}; filename=\"#{name}\"",
|
33
|
+
:content_transfer_encoding => 'Base64',
|
34
|
+
:content_disposition => "attachment; filename=\"#{name}\"" }
|
35
|
+
|
36
|
+
if value.is_a?(Hash)
|
37
|
+
|
38
|
+
default_values[:body] = value.delete(:content) if value[:content]
|
39
|
+
|
40
|
+
default_values[:body] = value.delete(:data) if value[:data]
|
41
|
+
|
42
|
+
# Only force encode base64 if the user has not specified an encoding
|
43
|
+
if value[:transfer_encoding]
|
44
|
+
default_values[:content_transfer_encoding] = value.delete(:transfer_encoding)
|
45
|
+
elsif value[:encoding]
|
46
|
+
default_values[:content_transfer_encoding] = value.delete(:encoding)
|
47
|
+
else
|
48
|
+
default_values[:body] = Mail::Encodings::Base64.encode(default_values[:body])
|
49
|
+
end
|
50
|
+
|
51
|
+
if value[:mime_type]
|
52
|
+
default_values[:content_type] = value.delete(:mime_type)
|
53
|
+
end
|
54
|
+
|
55
|
+
hash = default_values.merge(value)
|
56
|
+
else
|
57
|
+
default_values[:body] = Mail::Encodings::Base64.encode(value)
|
58
|
+
hash = default_values
|
59
|
+
end
|
60
|
+
|
61
|
+
@parts_list << Part.new(hash)
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_mime_type(filename)
|
65
|
+
# Have to do this because MIME::Types is not Ruby 1.9 safe yet
|
66
|
+
if RUBY_VERSION >= '1.9'
|
67
|
+
new_file = String.new(filename).force_encoding(Encoding::BINARY)
|
68
|
+
ext = new_file.split('.'.force_encoding(Encoding::BINARY)).last
|
69
|
+
filename = "file.#{ext}".force_encoding('US-ASCII')
|
70
|
+
end
|
71
|
+
@mime_type = MIME::Types.type_for(filename).first
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/lib/mail/body.rb
CHANGED
@@ -31,11 +31,18 @@ module Mail
|
|
31
31
|
@preamble = nil
|
32
32
|
@epilogue = nil
|
33
33
|
@part_sort_order = [ "text/plain", "text/enriched", "text/html" ]
|
34
|
-
@parts =
|
34
|
+
@parts = Mail::PartsList.new
|
35
35
|
if string.blank?
|
36
36
|
@raw_source = ''
|
37
37
|
else
|
38
|
-
|
38
|
+
# Do join first incase we have been given an Array in Ruby 1.9
|
39
|
+
if string.respond_to?(:join)
|
40
|
+
@raw_source = string.join('')
|
41
|
+
elsif string.respond_to?(:to_s)
|
42
|
+
@raw_source = string.to_s
|
43
|
+
else
|
44
|
+
raise "You can only assign a string or an object that responds_to? :join or :to_s to a body."
|
45
|
+
end
|
39
46
|
end
|
40
47
|
@encoding = nil
|
41
48
|
set_charset
|
@@ -103,15 +110,12 @@ module Mail
|
|
103
110
|
#
|
104
111
|
# sort_parts! is also called from :encode, so there is no need for you to call this explicitly
|
105
112
|
def sort_parts!
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# in the meantime, it works :)
|
111
|
-
a_order = order.index(a[:content_type].string.downcase) || 10000
|
112
|
-
b_order = order.index(b[:content_type].string.downcase) || 10000
|
113
|
-
a_order <=> b_order
|
113
|
+
@parts.each do |p|
|
114
|
+
p.body.set_sort_order(@part_sort_order)
|
115
|
+
@parts.sort!(@part_sort_order)
|
116
|
+
p.body.sort_parts!
|
114
117
|
end
|
118
|
+
# @parts.sort!(@part_sort_order)
|
115
119
|
end
|
116
120
|
|
117
121
|
# Returns the raw source that the body was initialized with, without
|
@@ -144,10 +148,6 @@ module Mail
|
|
144
148
|
decoded
|
145
149
|
end
|
146
150
|
|
147
|
-
def to_str
|
148
|
-
to_s
|
149
|
-
end
|
150
|
-
|
151
151
|
def charset
|
152
152
|
@charset
|
153
153
|
end
|
@@ -207,7 +207,7 @@ module Mail
|
|
207
207
|
if @parts
|
208
208
|
@parts << val
|
209
209
|
else
|
210
|
-
@parts = [val]
|
210
|
+
@parts = Mail::PartsList.new[val]
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
@@ -218,7 +218,7 @@ module Mail
|
|
218
218
|
self.preamble = parts[0].to_s.strip
|
219
219
|
# Make the epilogue equal to the epilogue (if any)
|
220
220
|
self.epilogue = parts[-1].to_s.sub('--', '').strip
|
221
|
-
|
221
|
+
parts[1...-1].to_a.each { |part| @parts << Mail::Part.new(part) }
|
222
222
|
self
|
223
223
|
end
|
224
224
|
|
data/lib/mail/configuration.rb
CHANGED
@@ -7,134 +7,58 @@ require 'singleton'
|
|
7
7
|
module Mail
|
8
8
|
|
9
9
|
# The Configuration class is a Singleton used to hold the default
|
10
|
-
# configuration for all
|
10
|
+
# configuration for all Mail objects.
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# See Mail.defaults for more information.
|
12
|
+
# Each new mail object gets a copy of these values at initialization
|
13
|
+
# which can be overwritten on a per mail object basis.
|
16
14
|
class Configuration
|
17
15
|
include Singleton
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
if block_given?
|
22
|
-
instance_eval(&block)
|
23
|
-
end
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
# Allows you to specify the SMTP Server by passing the hostname
|
28
|
-
# or IP Address as a String with an optional port number as a
|
29
|
-
# string or integer.
|
30
|
-
#
|
31
|
-
# Defaults to 127.0.0.1 and port 25.
|
32
|
-
#
|
33
|
-
# Example:
|
34
|
-
#
|
35
|
-
# Mail.defaults.do
|
36
|
-
# smtp '127.0.0.1'
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# Mail.defaults do
|
40
|
-
# smtp '127.0.0.1', 25
|
41
|
-
# end
|
42
|
-
def smtp(*args, &block)
|
43
|
-
if args.size > 0
|
44
|
-
host_array = [args[0], (args[1].to_i > 0 ? args[1] : 25)]
|
45
|
-
end
|
46
|
-
set_settings(Mail::SMTP, host_array, &block)
|
47
|
-
end
|
17
|
+
@delivery_method = nil
|
18
|
+
@retriever_method = nil
|
48
19
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# in your own delivery class, in which case this will be set.
|
53
|
-
def delivery_method(value = nil)
|
54
|
-
value ? @delivery_method = lookup_delivery_method(value) : @delivery_method ||= Mail::SMTP
|
20
|
+
def delivery_method(method = nil, settings = {})
|
21
|
+
return @delivery_method if @delivery_method && method.nil?
|
22
|
+
@delivery_method = lookup_delivery_method(method).new(settings)
|
55
23
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# enable_tls
|
72
|
-
# end
|
73
|
-
# end
|
74
|
-
def pop3(*args, &block)
|
75
|
-
if args.size > 0
|
76
|
-
host_array = [args[0], (args[1].to_i > 0 ? args[1] : 110)]
|
24
|
+
|
25
|
+
def lookup_delivery_method(method)
|
26
|
+
case method
|
27
|
+
when nil
|
28
|
+
Mail::SMTP
|
29
|
+
when :smtp
|
30
|
+
Mail::SMTP
|
31
|
+
when :sendmail
|
32
|
+
Mail::Sendmail
|
33
|
+
when :file
|
34
|
+
Mail::FileDelivery
|
35
|
+
when :test
|
36
|
+
Mail::TestMailer
|
37
|
+
else
|
38
|
+
method
|
77
39
|
end
|
78
|
-
set_settings(Mail::POP3, host_array, &block)
|
79
40
|
end
|
80
41
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
path sendmail_path
|
85
|
-
end
|
42
|
+
def retriever_method(method = nil, settings = {})
|
43
|
+
return @retriever_method if @retriever_method && method.nil?
|
44
|
+
@retriever_method = lookup_retriever_method(method).new(settings)
|
86
45
|
end
|
87
46
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
47
|
+
def lookup_retriever_method(method)
|
48
|
+
case method
|
49
|
+
when nil
|
50
|
+
Mail::POP3
|
51
|
+
when :pop3
|
52
|
+
Mail::POP3
|
53
|
+
else
|
54
|
+
method
|
55
|
+
end
|
94
56
|
end
|
95
57
|
|
96
58
|
def param_encode_language(value = nil)
|
97
59
|
value ? @encode_language = value : @encode_language ||= 'en'
|
98
60
|
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def set_settings(klass, host_array = nil, &block)
|
103
|
-
if host_array
|
104
|
-
klass.instance.settings do
|
105
|
-
host host_array[0]
|
106
|
-
port host_array[1]
|
107
|
-
end
|
108
|
-
end
|
109
|
-
klass.instance.settings(&block)
|
110
|
-
end
|
111
|
-
|
112
|
-
def lookup_delivery_method(method)
|
113
|
-
case method
|
114
|
-
when :smtp || nil
|
115
|
-
Mail::SMTP
|
116
|
-
when :sendmail
|
117
|
-
Mail::Sendmail
|
118
|
-
when :file
|
119
|
-
Mail::FileDelivery
|
120
|
-
when :test
|
121
|
-
Mail::TestMailer
|
122
|
-
else
|
123
|
-
method
|
124
|
-
end
|
125
|
-
end
|
126
61
|
|
127
|
-
def lookup_retriever_method(method)
|
128
|
-
case method
|
129
|
-
when :pop3 || nil
|
130
|
-
Mail::POP3
|
131
|
-
# when :imap
|
132
|
-
# Mail::IMAP
|
133
|
-
else
|
134
|
-
method
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
62
|
end
|
139
63
|
|
140
64
|
end
|