actionmailer 1.3.6 → 2.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 actionmailer might be problematic. Click here for more details.

Files changed (96) hide show
  1. data/CHANGELOG +40 -28
  2. data/MIT-LICENSE +1 -1
  3. data/README +2 -2
  4. data/Rakefile +4 -3
  5. data/install.rb +1 -1
  6. data/lib/action_mailer.rb +5 -3
  7. data/lib/action_mailer/base.rb +57 -36
  8. data/lib/action_mailer/helpers.rb +4 -4
  9. data/lib/action_mailer/part.rb +2 -5
  10. data/lib/action_mailer/test_case.rb +59 -0
  11. data/lib/action_mailer/test_helper.rb +67 -0
  12. data/lib/action_mailer/vendor.rb +14 -0
  13. data/lib/action_mailer/vendor/{text → text-format-0.6.3/text}/format.rb +0 -0
  14. data/lib/action_mailer/vendor/tmail-1.1.0/tmail.rb +4 -0
  15. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/Makefile +19 -0
  16. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/address.rb +6 -3
  17. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/attachments.rb +10 -2
  18. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/base64.rb +52 -0
  19. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/compat.rb +39 -0
  20. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/config.rb +5 -3
  21. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/core_extensions.rb +67 -0
  22. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/encode.rb +23 -9
  23. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/facade.rb +0 -0
  24. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/header.rb +23 -6
  25. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/info.rb +0 -0
  26. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/interface.rb +540 -0
  27. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/loader.rb +0 -0
  28. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/mail.rb +20 -5
  29. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/mailbox.rb +5 -3
  30. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/mbox.rb +0 -0
  31. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/net.rb +5 -3
  32. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/obsolete.rb +5 -3
  33. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/parser.rb +234 -281
  34. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/parser.y +381 -0
  35. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/port.rb +5 -3
  36. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/quoting.rb +12 -1
  37. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/scanner.rb +5 -3
  38. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/scanner_r.rb +1 -1
  39. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/stringio.rb +6 -4
  40. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/tmail.rb +0 -0
  41. data/lib/action_mailer/vendor/{tmail → tmail-1.1.0/tmail}/utils.rb +50 -7
  42. data/lib/action_mailer/vendor/{tmail/base64.rb → tmail-1.1.0/tmail/version.rb} +7 -40
  43. data/lib/action_mailer/version.rb +3 -3
  44. data/lib/actionmailer.rb +1 -0
  45. data/test/abstract_unit.rb +19 -0
  46. data/test/delivery_method_test.rb +51 -0
  47. data/test/fixtures/first_mailer/share.erb +1 -0
  48. data/test/fixtures/first_mailer/share.rhtml +0 -1
  49. data/test/fixtures/helper_mailer/use_example_helper.erb +1 -0
  50. data/test/fixtures/helper_mailer/use_example_helper.rhtml +0 -0
  51. data/test/fixtures/helper_mailer/use_helper.erb +1 -0
  52. data/test/fixtures/helper_mailer/use_helper.rhtml +0 -1
  53. data/test/fixtures/helper_mailer/use_helper_method.erb +1 -0
  54. data/test/fixtures/helper_mailer/use_helper_method.rhtml +0 -1
  55. data/test/fixtures/helper_mailer/use_mail_helper.erb +5 -0
  56. data/test/fixtures/helper_mailer/use_mail_helper.rhtml +0 -5
  57. data/test/fixtures/helpers/{test_helper.rb → example_helper.rb} +2 -2
  58. data/test/fixtures/path.with.dots/funky_path_mailer/multipart_with_template_path_with_dots.erb +1 -0
  59. data/test/fixtures/path.with.dots/funky_path_mailer/multipart_with_template_path_with_dots.rhtml +0 -1
  60. data/test/fixtures/raw_base64_decoded_string +0 -0
  61. data/test/fixtures/raw_base64_encoded_string +1 -0
  62. data/test/fixtures/raw_email_with_invalid_characters_in_content_type +104 -0
  63. data/test/fixtures/raw_email_with_nested_attachment +100 -0
  64. data/test/fixtures/second_mailer/share.erb +1 -0
  65. data/test/fixtures/second_mailer/share.rhtml +0 -1
  66. data/test/fixtures/templates/signed_up.erb +3 -0
  67. data/test/fixtures/templates/signed_up.rhtml +0 -3
  68. data/test/fixtures/test_mailer/_subtemplate.text.plain.erb +1 -0
  69. data/test/fixtures/test_mailer/custom_templating_extension.text.html.haml +6 -0
  70. data/test/fixtures/test_mailer/custom_templating_extension.text.plain.haml +6 -0
  71. data/test/fixtures/test_mailer/implicitly_multipart_example.ignored.erb +1 -0
  72. data/test/fixtures/test_mailer/implicitly_multipart_example.ignored.rhtml +0 -1
  73. data/test/fixtures/test_mailer/implicitly_multipart_example.text.html.erb +10 -0
  74. data/test/fixtures/test_mailer/implicitly_multipart_example.text.html.rhtml +0 -10
  75. data/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.erb +2 -0
  76. data/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.rhtml +0 -2
  77. data/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.erb +1 -0
  78. data/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.rhtml +0 -1
  79. data/test/fixtures/test_mailer/included_subtemplate.text.plain.erb +1 -0
  80. data/test/fixtures/test_mailer/rxml_template.builder +2 -0
  81. data/test/fixtures/test_mailer/rxml_template.rxml +2 -0
  82. data/test/fixtures/test_mailer/signed_up.erb +3 -0
  83. data/test/fixtures/test_mailer/signed_up.rhtml +0 -3
  84. data/test/fixtures/test_mailer/signed_up_with_url.erb +5 -0
  85. data/test/fixtures/test_mailer/signed_up_with_url.rhtml +0 -3
  86. data/test/mail_helper_test.rb +10 -6
  87. data/test/mail_render_test.rb +45 -2
  88. data/test/mail_service_test.rb +150 -27
  89. data/test/quoting_test.rb +57 -3
  90. data/test/test_helper_test.rb +117 -0
  91. data/test/tmail_test.rb +9 -0
  92. data/test/url_test.rb +10 -2
  93. metadata +69 -32
  94. data/lib/action_mailer/vendor/tmail.rb +0 -3
  95. data/test/fixtures/helper_mailer/use_test_helper.rhtml +0 -1
  96. data/test/fixtures/raw_email11 +0 -34
@@ -0,0 +1,381 @@
1
+ #
2
+ # parser.y
3
+ #
4
+ # Copyright (c) 1998-2007 Minero Aoki
5
+ #
6
+ # This program is free software.
7
+ # You can distribute/modify this program under the terms of
8
+ # the GNU Lesser General Public License version 2.1.
9
+ #
10
+
11
+ class TMail::Parser
12
+
13
+ options no_result_var
14
+
15
+ rule
16
+
17
+ content : DATETIME datetime { val[1] }
18
+ | RECEIVED received { val[1] }
19
+ | MADDRESS addrs_TOP { val[1] }
20
+ | RETPATH retpath { val[1] }
21
+ | KEYWORDS keys { val[1] }
22
+ | ENCRYPTED enc { val[1] }
23
+ | MIMEVERSION version { val[1] }
24
+ | CTYPE ctype { val[1] }
25
+ | CENCODING cencode { val[1] }
26
+ | CDISPOSITION cdisp { val[1] }
27
+ | ADDRESS addr_TOP { val[1] }
28
+ | MAILBOX mbox { val[1] }
29
+
30
+ datetime : day DIGIT ATOM DIGIT hour zone
31
+ # 0 1 2 3 4 5
32
+ # date month year
33
+ {
34
+ t = Time.gm(val[3].to_i, val[2], val[1].to_i, 0, 0, 0)
35
+ (t + val[4] - val[5]).localtime
36
+ }
37
+
38
+ day : /* none */
39
+ | ATOM ','
40
+
41
+ hour : DIGIT ':' DIGIT
42
+ {
43
+ (val[0].to_i * 60 * 60) +
44
+ (val[2].to_i * 60)
45
+ }
46
+ | DIGIT ':' DIGIT ':' DIGIT
47
+ {
48
+ (val[0].to_i * 60 * 60) +
49
+ (val[2].to_i * 60) +
50
+ (val[4].to_i)
51
+ }
52
+
53
+ zone : ATOM
54
+ {
55
+ timezone_string_to_unixtime(val[0])
56
+ }
57
+
58
+ received : from by via with id for received_datetime
59
+ {
60
+ val
61
+ }
62
+
63
+ from : /* none */
64
+ | FROM received_domain
65
+ {
66
+ val[1]
67
+ }
68
+
69
+ by : /* none */
70
+ | BY received_domain
71
+ {
72
+ val[1]
73
+ }
74
+
75
+ received_domain
76
+ : domain
77
+ {
78
+ join_domain(val[0])
79
+ }
80
+ | domain '@' domain
81
+ {
82
+ join_domain(val[2])
83
+ }
84
+ | domain DOMLIT
85
+ {
86
+ join_domain(val[0])
87
+ }
88
+
89
+ via : /* none */
90
+ | VIA ATOM
91
+ {
92
+ val[1]
93
+ }
94
+
95
+ with : /* none */
96
+ {
97
+ []
98
+ }
99
+ | with WITH ATOM
100
+ {
101
+ val[0].push val[2]
102
+ val[0]
103
+ }
104
+
105
+ id : /* none */
106
+ | ID msgid
107
+ {
108
+ val[1]
109
+ }
110
+ | ID ATOM
111
+ {
112
+ val[1]
113
+ }
114
+
115
+ for : /* none */
116
+ | FOR received_addrspec
117
+ {
118
+ val[1]
119
+ }
120
+
121
+ received_addrspec
122
+ : routeaddr
123
+ {
124
+ val[0].spec
125
+ }
126
+ | spec
127
+ {
128
+ val[0].spec
129
+ }
130
+
131
+ received_datetime
132
+ : /* none */
133
+ | ';' datetime
134
+ {
135
+ val[1]
136
+ }
137
+
138
+ addrs_TOP : addrs
139
+ | group_bare
140
+ | addrs commas group_bare
141
+
142
+ addr_TOP : mbox
143
+ | group
144
+ | group_bare
145
+
146
+ retpath : addrs_TOP
147
+ | '<' '>' { [ Address.new(nil, nil) ] }
148
+
149
+ addrs : addr
150
+ {
151
+ val
152
+ }
153
+ | addrs commas addr
154
+ {
155
+ val[0].push val[2]
156
+ val[0]
157
+ }
158
+
159
+ addr : mbox
160
+ | group
161
+
162
+ mboxes : mbox
163
+ {
164
+ val
165
+ }
166
+ | mboxes commas mbox
167
+ {
168
+ val[0].push val[2]
169
+ val[0]
170
+ }
171
+
172
+ mbox : spec
173
+ | routeaddr
174
+ | addr_phrase routeaddr
175
+ {
176
+ val[1].phrase = Decoder.decode(val[0])
177
+ val[1]
178
+ }
179
+
180
+ group : group_bare ';'
181
+
182
+ group_bare: addr_phrase ':' mboxes
183
+ {
184
+ AddressGroup.new(val[0], val[2])
185
+ }
186
+ | addr_phrase ':' { AddressGroup.new(val[0], []) }
187
+
188
+ addr_phrase
189
+ : local_head { val[0].join('.') }
190
+ | addr_phrase local_head { val[0] << ' ' << val[1].join('.') }
191
+
192
+ routeaddr : '<' routes spec '>'
193
+ {
194
+ val[2].routes.replace val[1]
195
+ val[2]
196
+ }
197
+ | '<' spec '>'
198
+ {
199
+ val[1]
200
+ }
201
+
202
+ routes : at_domains ':'
203
+
204
+ at_domains: '@' domain { [ val[1].join('.') ] }
205
+ | at_domains ',' '@' domain { val[0].push val[3].join('.'); val[0] }
206
+
207
+ spec : local '@' domain { Address.new( val[0], val[2] ) }
208
+ | local { Address.new( val[0], nil ) }
209
+
210
+ local: local_head
211
+ | local_head '.' { val[0].push ''; val[0] }
212
+
213
+ local_head: word
214
+ { val }
215
+ | local_head dots word
216
+ {
217
+ val[1].times do
218
+ val[0].push ''
219
+ end
220
+ val[0].push val[2]
221
+ val[0]
222
+ }
223
+
224
+ domain : domword
225
+ { val }
226
+ | domain dots domword
227
+ {
228
+ val[1].times do
229
+ val[0].push ''
230
+ end
231
+ val[0].push val[2]
232
+ val[0]
233
+ }
234
+
235
+ dots : '.' { 0 }
236
+ | '.' '.' { 1 }
237
+
238
+ word : atom
239
+ | QUOTED
240
+ | DIGIT
241
+
242
+ domword : atom
243
+ | DOMLIT
244
+ | DIGIT
245
+
246
+ commas : ','
247
+ | commas ','
248
+
249
+ msgid : '<' spec '>'
250
+ {
251
+ val[1] = val[1].spec
252
+ val.join('')
253
+ }
254
+
255
+ keys : phrase { val }
256
+ | keys ',' phrase { val[0].push val[2]; val[0] }
257
+
258
+ phrase : word
259
+ | phrase word { val[0] << ' ' << val[1] }
260
+
261
+ enc : word
262
+ {
263
+ val.push nil
264
+ val
265
+ }
266
+ | word word
267
+ {
268
+ val
269
+ }
270
+
271
+ version : DIGIT '.' DIGIT
272
+ {
273
+ [ val[0].to_i, val[2].to_i ]
274
+ }
275
+
276
+ ctype : TOKEN '/' TOKEN params opt_semicolon
277
+ {
278
+ [ val[0].downcase, val[2].downcase, decode_params(val[3]) ]
279
+ }
280
+ | TOKEN params opt_semicolon
281
+ {
282
+ [ val[0].downcase, nil, decode_params(val[1]) ]
283
+ }
284
+
285
+ params : /* none */
286
+ {
287
+ {}
288
+ }
289
+ | params ';' TOKEN '=' QUOTED
290
+ {
291
+ val[0][ val[2].downcase ] = ('"' + val[4].to_s + '"')
292
+ val[0]
293
+ }
294
+ | params ';' TOKEN '=' TOKEN
295
+ {
296
+ val[0][ val[2].downcase ] = val[4]
297
+ val[0]
298
+ }
299
+
300
+ cencode : TOKEN
301
+ {
302
+ val[0].downcase
303
+ }
304
+
305
+ cdisp : TOKEN params opt_semicolon
306
+ {
307
+ [ val[0].downcase, decode_params(val[1]) ]
308
+ }
309
+
310
+ opt_semicolon
311
+ :
312
+ | ';'
313
+
314
+ atom : ATOM
315
+ | FROM
316
+ | BY
317
+ | VIA
318
+ | WITH
319
+ | ID
320
+ | FOR
321
+
322
+ end
323
+
324
+
325
+ ---- header
326
+ #
327
+ # parser.rb
328
+ #
329
+ # Copyright (c) 1998-2007 Minero Aoki
330
+ #
331
+ # This program is free software.
332
+ # You can distribute/modify this program under the terms of
333
+ # the GNU Lesser General Public License version 2.1.
334
+ #
335
+
336
+ require 'tmail/scanner'
337
+ require 'tmail/utils'
338
+
339
+ ---- inner
340
+
341
+ include TextUtils
342
+
343
+ def self.parse( ident, str, cmt = nil )
344
+ new.parse(ident, str, cmt)
345
+ end
346
+
347
+ MAILP_DEBUG = false
348
+
349
+ def initialize
350
+ self.debug = MAILP_DEBUG
351
+ end
352
+
353
+ def debug=( flag )
354
+ @yydebug = flag && Racc_debug_parser
355
+ @scanner_debug = flag
356
+ end
357
+
358
+ def debug
359
+ @yydebug
360
+ end
361
+
362
+ def parse( ident, str, comments = nil )
363
+ @scanner = Scanner.new(str, ident, comments)
364
+ @scanner.debug = @scanner_debug
365
+ @first = [ident, ident]
366
+ result = yyparse(self, :parse_in)
367
+ comments.map! {|c| to_kcode(c) } if comments
368
+ result
369
+ end
370
+
371
+ private
372
+
373
+ def parse_in( &block )
374
+ yield @first
375
+ @scanner.scan(&block)
376
+ end
377
+
378
+ def on_error( t, val, vstack )
379
+ raise SyntaxError, "parse error on token #{racc_token2str t}"
380
+ end
381
+
@@ -1,6 +1,8 @@
1
- #
2
- # port.rb
3
- #
1
+ =begin rdoc
2
+
3
+ = Port class
4
+
5
+ =end
4
6
  #--
5
7
  # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
8
  #
@@ -1,3 +1,8 @@
1
+ =begin rdoc
2
+
3
+ = Quoting methods
4
+
5
+ =end
1
6
  module TMail
2
7
  class Mail
3
8
  def subject(to_charset = 'utf-8')
@@ -8,6 +13,12 @@ module TMail
8
13
  from_charset = sub_header("content-type", "charset")
9
14
  case (content_transfer_encoding || "7bit").downcase
10
15
  when "quoted-printable"
16
+ # the default charset is set to iso-8859-1 instead of 'us-ascii'.
17
+ # This is needed as many mailer do not set the charset but send in ISO. This is only used if no charset is set.
18
+ if !from_charset.blank? && from_charset.downcase == 'us-ascii'
19
+ from_charset = 'iso-8859-1'
20
+ end
21
+
11
22
  Unquoter.unquote_quoted_printable_and_convert_to(quoted_body,
12
23
  to_charset, from_charset, true)
13
24
  when "base64"
@@ -78,7 +89,7 @@ module TMail
78
89
  end
79
90
 
80
91
  def unquote_base64_and_convert_to(text, to, from)
81
- convert_to(Base64.decode(text).first, to, from)
92
+ convert_to(Base64.decode(text), to, from)
82
93
  end
83
94
 
84
95
  begin
@@ -1,6 +1,8 @@
1
- #
2
- # scanner.rb
3
- #
1
+ =begin rdoc
2
+
3
+ = Scanner for TMail
4
+
5
+ =end
4
6
  #--
5
7
  # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
8
  #
@@ -44,7 +44,7 @@ module TMail
44
44
  }
45
45
 
46
46
  alnum = 'a-zA-Z0-9'
47
- atomsyms = %q[ _#!$%&`'*+-{|}~^@/=? ].strip
47
+ atomsyms = %q[ _#!$%&`'*+-{|}~^/=? ].strip
48
48
  tokensyms = %q[ _#!$%&`'*+-{|}~^@. ].strip
49
49
 
50
50
  atomchars = alnum + Regexp.quote(atomsyms)
@@ -1,6 +1,8 @@
1
- #
2
- # stringio.rb
3
- #
1
+ =begin rdoc
2
+
3
+ = String handling class
4
+
5
+ =end
4
6
  #--
5
7
  # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
8
  #
@@ -218,7 +220,7 @@ class StringOutput#:nodoc:
218
220
  alias pos size
219
221
 
220
222
  def inspect
221
- "#<#{self.class}:#{@dest ? 'open' : 'closed'},#{id}>"
223
+ "#<#{self.class}:#{@dest ? 'open' : 'closed'},#{object_id}>"
222
224
  end
223
225
 
224
226
  def print( *args )