actionmailer 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionmailer might be problematic. Click here for more details.
- data/CHANGELOG +11 -0
- data/install.rb +7 -38
- data/lib/action_mailer/base.rb +49 -20
- data/lib/action_mailer/vendor/tmail/port.rb +2 -2
- data/lib/action_mailer/vendor/tmail/quoting.rb +3 -2
- data/rakefile +4 -4
- data/test/mail_service_test.rb +85 -6
- metadata +3 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
*0.9.0* (19th April, 2005)
|
2
|
+
|
3
|
+
* Added that deliver_* will now return the email that was sent
|
4
|
+
|
5
|
+
* Added that quoting to UTF-8 only happens if the characters used are in that range #955 [Jamis Buck]
|
6
|
+
|
7
|
+
* Fixed quoting for all address headers, not just to #955 [Jamis Buck]
|
8
|
+
|
9
|
+
* Fixed unquoting of emails that doesn't have an explicit charset #1036 [wolfgang@stufenlos.net]
|
10
|
+
|
11
|
+
|
1
12
|
*0.8.1* (27th March, 2005)
|
2
13
|
|
3
14
|
* Fixed that if charset was found that the end of a mime part declaration TMail would throw an error #919 [lon@speedymac.com]
|
data/install.rb
CHANGED
@@ -18,44 +18,13 @@ unless $sitedir
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
makedirs = %w{ action_mailer/vendor action_mailer/vendor/text action_mailer/vendor/tmail }
|
22
|
-
makedirs.each {|f| File::makedirs(File.join($sitedir, *f.split(/\//)))}
|
23
|
-
|
24
|
-
# deprecated files that should be removed
|
25
|
-
# deprecated = %w{ }
|
26
|
-
|
27
|
-
# files to install in library path
|
28
|
-
files = %w-
|
29
|
-
action_mailer.rb
|
30
|
-
action_mailer/base.rb
|
31
|
-
action_mailer/mail_helper.rb
|
32
|
-
action_mailer/vendor/text/format.rb
|
33
|
-
action_mailer/vendor/tmail.rb
|
34
|
-
action_mailer/vendor/tmail/address.rb
|
35
|
-
action_mailer/vendor/tmail/base64.rb
|
36
|
-
action_mailer/vendor/tmail/config.rb
|
37
|
-
action_mailer/vendor/tmail/encode.rb
|
38
|
-
action_mailer/vendor/tmail/facade.rb
|
39
|
-
action_mailer/vendor/tmail/header.rb
|
40
|
-
action_mailer/vendor/tmail/info.rb
|
41
|
-
action_mailer/vendor/tmail/loader.rb
|
42
|
-
action_mailer/vendor/tmail/mail.rb
|
43
|
-
action_mailer/vendor/tmail/mailbox.rb
|
44
|
-
action_mailer/vendor/tmail/mbox.rb
|
45
|
-
action_mailer/vendor/tmail/net.rb
|
46
|
-
action_mailer/vendor/tmail/obsolete.rb
|
47
|
-
action_mailer/vendor/tmail/parser.rb
|
48
|
-
action_mailer/vendor/tmail/port.rb
|
49
|
-
action_mailer/vendor/tmail/scanner.rb
|
50
|
-
action_mailer/vendor/tmail/scanner_r.rb
|
51
|
-
action_mailer/vendor/tmail/stringio.rb
|
52
|
-
action_mailer/vendor/tmail/tmail.rb
|
53
|
-
action_mailer/vendor/tmail/utils.rb
|
54
|
-
-
|
55
|
-
|
56
21
|
# the acual gruntwork
|
57
22
|
Dir.chdir("lib")
|
58
|
-
|
59
|
-
|
60
|
-
|
23
|
+
|
24
|
+
Find.find("action_mailer", "action_mailer.rb") { |f|
|
25
|
+
if f[-3..-1] == ".rb"
|
26
|
+
File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true)
|
27
|
+
else
|
28
|
+
File::makedirs(File.join($sitedir, *f.split(/\//)))
|
29
|
+
end
|
61
30
|
}
|
data/lib/action_mailer/base.rb
CHANGED
@@ -58,8 +58,6 @@ module ActionMailer #:nodoc:
|
|
58
58
|
#
|
59
59
|
# * <tt>default_charset</tt> - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also
|
60
60
|
# pick a different charset from inside a method with <tt>@encoding</tt>.
|
61
|
-
#
|
62
|
-
# * <tt>encode_subject</tt> - Whether or not to encode the subject with the active charset. Defaults to true.
|
63
61
|
class Base
|
64
62
|
private_class_method :new #:nodoc:
|
65
63
|
|
@@ -91,24 +89,20 @@ module ActionMailer #:nodoc:
|
|
91
89
|
@@default_charset = "utf-8"
|
92
90
|
cattr_accessor :default_charset
|
93
91
|
|
94
|
-
|
95
|
-
cattr_accessor :encode_subject
|
96
|
-
|
97
|
-
attr_accessor :recipients, :subject, :body, :from, :sent_on, :headers, :bcc, :cc, :charset, :encode_subject
|
92
|
+
attr_accessor :recipients, :subject, :body, :from, :sent_on, :headers, :bcc, :cc, :charset
|
98
93
|
|
99
94
|
def initialize
|
100
95
|
@bcc = @cc = @from = @recipients = @sent_on = @subject = @body = nil
|
101
96
|
@charset = @@default_charset.dup
|
102
|
-
@encode_subject = @@encode_subject
|
103
97
|
@headers = {}
|
104
98
|
end
|
105
99
|
|
106
100
|
class << self
|
107
101
|
def method_missing(method_symbol, *parameters)#:nodoc:
|
108
102
|
case method_symbol.id2name
|
109
|
-
when /^create_([_a-z]*)/
|
103
|
+
when /^create_([_a-z]\w*)/
|
110
104
|
create_from_action($1, *parameters)
|
111
|
-
when /^deliver_([_a-z]*)/
|
105
|
+
when /^deliver_([_a-z]\w*)/
|
112
106
|
begin
|
113
107
|
deliver(send("create_" + $1, *parameters))
|
114
108
|
rescue Object => e
|
@@ -117,18 +111,16 @@ module ActionMailer #:nodoc:
|
|
117
111
|
end
|
118
112
|
end
|
119
113
|
|
120
|
-
def mail(to, subject, body, from, timestamp = nil, headers = {},
|
121
|
-
encode = @@encode_subject, charset = @@default_charset
|
122
|
-
) #:nodoc:
|
114
|
+
def mail(to, subject, body, from, timestamp = nil, headers = {}, charset = @@default_charset) #:nodoc:
|
123
115
|
deliver(create(to, subject, body, from, timestamp, headers, charset))
|
124
116
|
end
|
125
117
|
|
126
|
-
def create(to, subject, body, from, timestamp = nil, headers = {},
|
127
|
-
encode = @@encode_subject, charset = @@default_charset
|
128
|
-
) #:nodoc:
|
118
|
+
def create(to, subject, body, from, timestamp = nil, headers = {}, charset = @@default_charset) #:nodoc:
|
129
119
|
m = TMail::Mail.new
|
130
|
-
m.
|
131
|
-
|
120
|
+
m.body = body
|
121
|
+
m.subject, = quote_any_if_necessary(charset, subject)
|
122
|
+
m.to, m.from = quote_any_address_if_necessary(charset, to, from)
|
123
|
+
|
132
124
|
m.date = timestamp.respond_to?("to_time") ? timestamp.to_time : (timestamp || Time.now)
|
133
125
|
|
134
126
|
m.set_content_type "text", "plain", { "charset" => charset }
|
@@ -143,6 +135,7 @@ module ActionMailer #:nodoc:
|
|
143
135
|
def deliver(mail) #:nodoc:
|
144
136
|
logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil?
|
145
137
|
send("perform_delivery_#{delivery_method}", mail) if perform_deliveries
|
138
|
+
return mail
|
146
139
|
end
|
147
140
|
|
148
141
|
def quoted_printable(text, charset)#:nodoc:
|
@@ -150,6 +143,42 @@ module ActionMailer #:nodoc:
|
|
150
143
|
"=?#{charset}?Q?#{text}?="
|
151
144
|
end
|
152
145
|
|
146
|
+
CHARS_NEEDING_QUOTING = /[\000-\011\013\014\016-\037\177-\377]/
|
147
|
+
|
148
|
+
# Quote the given text if it contains any "illegal" characters
|
149
|
+
def quote_if_necessary(text, charset)
|
150
|
+
(text =~ CHARS_NEEDING_QUOTING) ?
|
151
|
+
quoted_printable(text, charset) :
|
152
|
+
text
|
153
|
+
end
|
154
|
+
|
155
|
+
# Quote any of the given strings if they contain any "illegal" characters
|
156
|
+
def quote_any_if_necessary(charset, *args)
|
157
|
+
args.map { |v| quote_if_necessary(v, charset) }
|
158
|
+
end
|
159
|
+
|
160
|
+
# Quote the given address if it needs to be. The address may be a
|
161
|
+
# regular email address, or it can be a phrase followed by an address in
|
162
|
+
# brackets. The phrase is the only part that will be quoted, and only if
|
163
|
+
# it needs to be. This allows extended characters to be used in the
|
164
|
+
# "to", "from", "cc", and "bcc" headers.
|
165
|
+
def quote_address_if_necessary(address, charset)
|
166
|
+
if Array === address
|
167
|
+
address.map { |a| quote_address_if_necessary(a, charset) }
|
168
|
+
elsif address =~ /^(\S.*)\s+(<.*>)$/
|
169
|
+
address = $2
|
170
|
+
phrase = quote_if_necessary($1.gsub(/^['"](.*)['"]$/, '\1'), charset)
|
171
|
+
"#{phrase} #{address}"
|
172
|
+
else
|
173
|
+
address
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Quote any of the given addresses, if they need to be.
|
178
|
+
def quote_any_address_if_necessary(charset, *args)
|
179
|
+
args.map { |v| quote_address_if_necessary(v, charset) }
|
180
|
+
end
|
181
|
+
|
153
182
|
def receive(raw_email)
|
154
183
|
logger.info "Received mail:\n #{raw_email}" unless logger.nil?
|
155
184
|
new.receive(TMail::Mail.parse(raw_email))
|
@@ -185,10 +214,10 @@ module ActionMailer #:nodoc:
|
|
185
214
|
|
186
215
|
mail = create(mailer.recipients, mailer.subject, mailer.body,
|
187
216
|
mailer.from, mailer.sent_on, mailer.headers,
|
188
|
-
mailer.
|
217
|
+
mailer.charset)
|
189
218
|
|
190
|
-
mail.bcc = mailer.bcc unless mailer.bcc.nil?
|
191
|
-
mail.cc = mailer.cc unless mailer.cc.nil?
|
219
|
+
mail.bcc = quote_address_if_necessary(mailer.bcc, mailer.charset) unless mailer.bcc.nil?
|
220
|
+
mail.cc = quote_address_if_necessary(mailer.cc, mailer.charset) unless mailer.cc.nil?
|
192
221
|
|
193
222
|
return mail
|
194
223
|
end
|
@@ -303,11 +303,11 @@ module TMail
|
|
303
303
|
alias eql? ==
|
304
304
|
|
305
305
|
def hash
|
306
|
-
@buffer.
|
306
|
+
@buffer.object_id.hash
|
307
307
|
end
|
308
308
|
|
309
309
|
def inspect
|
310
|
-
"#<#{self.class}:id=#{sprintf '0x%x', @buffer.
|
310
|
+
"#<#{self.class}:id=#{sprintf '0x%x', @buffer.object_id}>"
|
311
311
|
end
|
312
312
|
|
313
313
|
def reproducible?
|
@@ -9,7 +9,8 @@ begin
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def unquoted_body(to_charset = 'utf-8')
|
12
|
-
|
12
|
+
from_charset = header['content-type']['charset'] rescue 'us-ascii'
|
13
|
+
Unquoter.unquote_and_convert_to(quoted_body, to_charset, from_charset)
|
13
14
|
end
|
14
15
|
|
15
16
|
def body(to_charset = 'utf-8', &block)
|
@@ -97,4 +98,4 @@ rescue LoadError => e
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
end
|
100
|
-
end
|
101
|
+
end
|
data/rakefile
CHANGED
@@ -8,7 +8,7 @@ require 'rake/contrib/rubyforgepublisher'
|
|
8
8
|
|
9
9
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
10
|
PKG_NAME = 'actionmailer'
|
11
|
-
PKG_VERSION = '0.
|
11
|
+
PKG_VERSION = '0.9.0' + PKG_BUILD
|
12
12
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
13
13
|
|
14
14
|
RELEASE_NAME = "REL #{PKG_VERSION}"
|
@@ -52,7 +52,7 @@ spec = Gem::Specification.new do |s|
|
|
52
52
|
s.rubyforge_project = "actionmailer"
|
53
53
|
s.homepage = "http://www.rubyonrails.org"
|
54
54
|
|
55
|
-
s.add_dependency('actionpack', '= 1.
|
55
|
+
s.add_dependency('actionpack', '= 1.8.0' + PKG_BUILD)
|
56
56
|
|
57
57
|
s.has_rdoc = true
|
58
58
|
s.requirements << 'none'
|
@@ -73,12 +73,12 @@ end
|
|
73
73
|
|
74
74
|
desc "Publish the API documentation"
|
75
75
|
task :pgem => [:package] do
|
76
|
-
Rake::SshFilePublisher.new("davidhh@
|
76
|
+
Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
|
77
77
|
end
|
78
78
|
|
79
79
|
desc "Publish the API documentation"
|
80
80
|
task :pdoc => [:rdoc] do
|
81
|
-
Rake::SshDirPublisher.new("davidhh@
|
81
|
+
Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.com", "public_html/am", "doc").upload
|
82
82
|
end
|
83
83
|
|
84
84
|
desc "Publish the release files to RubyForge."
|
data/test/mail_service_test.rb
CHANGED
@@ -33,7 +33,7 @@ class TestMailer < ActionMailer::Base
|
|
33
33
|
|
34
34
|
def iso_charset(recipient)
|
35
35
|
@recipients = recipient
|
36
|
-
@subject = "testing
|
36
|
+
@subject = "testing isø charsets"
|
37
37
|
@from = "system@loudthinking.com"
|
38
38
|
@sent_on = Time.local 2004, 12, 12
|
39
39
|
@cc = "nobody@loudthinking.com"
|
@@ -50,9 +50,29 @@ class TestMailer < ActionMailer::Base
|
|
50
50
|
@cc = "nobody@loudthinking.com"
|
51
51
|
@bcc = "root@loudthinking.com"
|
52
52
|
@body = "Nothing to see here."
|
53
|
-
@encode_subject = false
|
54
53
|
end
|
55
54
|
|
55
|
+
def extended_headers(recipient)
|
56
|
+
@recipients = recipient
|
57
|
+
@subject = "testing extended headers"
|
58
|
+
@from = "Grytøyr <stian1@example.net>"
|
59
|
+
@sent_on = Time.local 2004, 12, 12
|
60
|
+
@cc = "Grytøyr <stian2@example.net>"
|
61
|
+
@bcc = "Grytøyr <stian3@example.net>"
|
62
|
+
@body = "Nothing to see here."
|
63
|
+
@charset = "iso-8859-1"
|
64
|
+
end
|
65
|
+
|
66
|
+
def utf8_body(recipient)
|
67
|
+
@recipients = recipient
|
68
|
+
@subject = "testing utf-8 body"
|
69
|
+
@from = "Foo áëô îü <extended@example.net>"
|
70
|
+
@sent_on = Time.local 2004, 12, 12
|
71
|
+
@cc = "Foo áëô îü <extended@example.net>"
|
72
|
+
@bcc = "Foo áëô îü <extended@example.net>"
|
73
|
+
@body = "åœö blah"
|
74
|
+
@charset = "utf-8"
|
75
|
+
end
|
56
76
|
end
|
57
77
|
|
58
78
|
TestMailer.template_root = File.dirname(__FILE__) + "/fixtures"
|
@@ -82,7 +102,7 @@ class ActionMailerTest < Test::Unit::TestCase
|
|
82
102
|
def test_signed_up
|
83
103
|
expected = new_mail
|
84
104
|
expected.to = @recipient
|
85
|
-
expected.subject =
|
105
|
+
expected.subject = "[Signed up] Welcome #{@recipient}"
|
86
106
|
expected.body = "Hello there, \n\nMr. #{@recipient}"
|
87
107
|
expected.from = "system@loudthinking.com"
|
88
108
|
expected.date = Time.local(2004, 12, 12)
|
@@ -100,7 +120,7 @@ class ActionMailerTest < Test::Unit::TestCase
|
|
100
120
|
def test_cancelled_account
|
101
121
|
expected = new_mail
|
102
122
|
expected.to = @recipient
|
103
|
-
expected.subject =
|
123
|
+
expected.subject = "[Cancelled] Goodbye #{@recipient}"
|
104
124
|
expected.body = "Goodbye, Mr. #{@recipient}"
|
105
125
|
expected.from = "system@loudthinking.com"
|
106
126
|
expected.date = Time.local(2004, 12, 12)
|
@@ -118,7 +138,7 @@ class ActionMailerTest < Test::Unit::TestCase
|
|
118
138
|
def test_cc_bcc
|
119
139
|
expected = new_mail
|
120
140
|
expected.to = @recipient
|
121
|
-
expected.subject =
|
141
|
+
expected.subject = "testing bcc/cc"
|
122
142
|
expected.body = "Nothing to see here."
|
123
143
|
expected.from = "system@loudthinking.com"
|
124
144
|
expected.cc = "nobody@loudthinking.com"
|
@@ -143,7 +163,7 @@ class ActionMailerTest < Test::Unit::TestCase
|
|
143
163
|
def test_iso_charset
|
144
164
|
expected = new_mail( "iso-8859-1" )
|
145
165
|
expected.to = @recipient
|
146
|
-
expected.subject = encode "testing
|
166
|
+
expected.subject = encode "testing isø charsets", "iso-8859-1"
|
147
167
|
expected.body = "Nothing to see here."
|
148
168
|
expected.from = "system@loudthinking.com"
|
149
169
|
expected.cc = "nobody@loudthinking.com"
|
@@ -228,5 +248,64 @@ EOF
|
|
228
248
|
assert_equal "This_is_a_test\n2 + 2 =3D 4\n", mail.quoted_body
|
229
249
|
end
|
230
250
|
|
251
|
+
def test_extended_headers
|
252
|
+
@recipient = "Grytøyr <test@localhost>"
|
253
|
+
|
254
|
+
expected = new_mail "iso-8859-1"
|
255
|
+
expected.to = TestMailer.quote_address_if_necessary @recipient, "iso-8859-1"
|
256
|
+
expected.subject = "testing extended headers"
|
257
|
+
expected.body = "Nothing to see here."
|
258
|
+
expected.from = TestMailer.quote_address_if_necessary "Grytøyr <stian1@example.net>", "iso-8859-1"
|
259
|
+
expected.cc = TestMailer.quote_address_if_necessary "Grytøyr <stian2@example.net>", "iso-8859-1"
|
260
|
+
expected.bcc = TestMailer.quote_address_if_necessary "Grytøyr <stian3@example.net>", "iso-8859-1"
|
261
|
+
expected.date = Time.local 2004, 12, 12
|
262
|
+
|
263
|
+
created = nil
|
264
|
+
assert_nothing_raised do
|
265
|
+
created = TestMailer.create_extended_headers @recipient
|
266
|
+
end
|
267
|
+
|
268
|
+
assert_not_nil created
|
269
|
+
assert_equal expected.encoded, created.encoded
|
270
|
+
|
271
|
+
assert_nothing_raised do
|
272
|
+
TestMailer.deliver_extended_headers @recipient
|
273
|
+
end
|
274
|
+
|
275
|
+
assert_not_nil ActionMailer::Base.deliveries.first
|
276
|
+
assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_utf8_body_is_not_quoted
|
280
|
+
@recipient = "Foo áëô îü <extended@example.net>"
|
281
|
+
expected = new_mail "utf-8"
|
282
|
+
expected.to = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
283
|
+
expected.subject = "testing utf-8 body"
|
284
|
+
expected.body = "åœö blah"
|
285
|
+
expected.from = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
286
|
+
expected.cc = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
287
|
+
expected.bcc = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
288
|
+
expected.date = Time.local 2004, 12, 12
|
289
|
+
|
290
|
+
created = TestMailer.create_utf8_body @recipient
|
291
|
+
assert_match(/åœö blah/, created.encoded)
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_multiple_utf8_recipients
|
295
|
+
@recipient = ["\"Foo áëô îü\" <extended@example.net>", "\"Example Recipient\" <me@example.com>"]
|
296
|
+
expected = new_mail "utf-8"
|
297
|
+
expected.to = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
298
|
+
expected.subject = "testing utf-8 body"
|
299
|
+
expected.body = "åœö blah"
|
300
|
+
expected.from = TestMailer.quote_address_if_necessary @recipient.first, "utf-8"
|
301
|
+
expected.cc = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
302
|
+
expected.bcc = TestMailer.quote_address_if_necessary @recipient, "utf-8"
|
303
|
+
expected.date = Time.local 2004, 12, 12
|
304
|
+
|
305
|
+
created = TestMailer.create_utf8_body @recipient
|
306
|
+
assert_match(/\nFrom: =\?utf-8\?Q\?Foo_.*?\?= <extended@example.net>\r/, created.encoded)
|
307
|
+
assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= <extended@example.net>, Example Recipient <me/, created.encoded)
|
308
|
+
end
|
309
|
+
|
231
310
|
end
|
232
311
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.8
|
|
3
3
|
specification_version: 1
|
4
4
|
name: actionmailer
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.9.0
|
7
|
+
date: 2005-04-19
|
8
8
|
summary: Service layer for easy email delivery and testing.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -85,5 +85,5 @@ dependencies:
|
|
85
85
|
-
|
86
86
|
- "="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 1.
|
88
|
+
version: 1.8.0
|
89
89
|
version:
|