actionmailer 3.0.0.beta → 3.0.0.beta2

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 CHANGED
@@ -1,7 +1,15 @@
1
- *Rails 3.0 (pending)*
1
+ *Rails 3.0.0 [beta 2] (April 1st, 2010)*
2
+
3
+ * Added interceptors and observers from Mail [ML]
4
+
5
+ ActionMailer::Base.register_interceptor calls Mail.register_interceptor
6
+ ActionMailer::Base.register_observer calls Mail.register_observer
2
7
 
3
8
  * Whole new API added with tests. See base.rb for full details. Old API is deprecated.
4
9
 
10
+
11
+ *Rails 3.0.0 [beta 1] (February 4, 2010)*
12
+
5
13
  * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted
6
14
 
7
15
  * Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'}
data/README CHANGED
@@ -101,7 +101,7 @@ Example:
101
101
  This Mailman can be the target for Postfix or other MTAs. In Rails, you would use the runner in the
102
102
  trivial case like this:
103
103
 
104
- ./script/runner 'Mailman.receive(STDIN.read)'
104
+ rails runner 'Mailman.receive(STDIN.read)'
105
105
 
106
106
  However, invoking Rails in the runner for each mail to be received is very resource intensive. A single
107
107
  instance of Rails should be run within a daemon if it is going to be utilized to process more than just
data/lib/action_mailer.rb CHANGED
@@ -34,6 +34,7 @@ require 'active_support/core_ext/array/uniq_by'
34
34
  require 'active_support/core_ext/module/attr_internal'
35
35
  require 'active_support/core_ext/module/delegation'
36
36
  require 'active_support/core_ext/string/inflections'
37
+ require 'active_support/lazy_load_hooks'
37
38
 
38
39
  module ActionMailer
39
40
  extend ::ActiveSupport::Autoload
@@ -1,6 +1,8 @@
1
1
  require 'mail'
2
2
  require 'action_mailer/tmail_compat'
3
3
  require 'action_mailer/collector'
4
+ require 'active_support/core_ext/array/wrap'
5
+ require 'active_support/core_ext/object/blank'
4
6
 
5
7
  module ActionMailer #:nodoc:
6
8
  # Action Mailer allows you to send email from your application using a mailer model and views.
@@ -9,7 +11,7 @@ module ActionMailer #:nodoc:
9
11
  #
10
12
  # To use Action Mailer, you need to create a mailer model.
11
13
  #
12
- # $ script/generate mailer Notifier
14
+ # $ rails generate mailer Notifier
13
15
  #
14
16
  # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods
15
17
  # within the model which are then used to set variables to be used in the mail template, to
@@ -181,6 +183,18 @@ module ActionMailer #:nodoc:
181
183
  # and the second being a <tt>application/pdf</tt> with a Base64 encoded copy of the file.pdf book
182
184
  # with the filename +free_book.pdf+.
183
185
  #
186
+ # = Observing and Intercepting Mails
187
+ #
188
+ # ActionMailer provides hooks into the Mail observer and interceptor methods. These allow you to
189
+ # register objects that are called during the mail delivery life cycle.
190
+ #
191
+ # An observer object must implement the <tt>:delivered_email(message)</tt> method which will be
192
+ # called once for every email sent after the email has been sent.
193
+ #
194
+ # An interceptor object must implement the <tt>:delivering_email(message)</tt> method which will be
195
+ # called before the email is sent, allowing you to make modifications to the email before it hits
196
+ # the delivery agents. Your object should make and needed modifications directly to the passed
197
+ # in Mail::Message instance.
184
198
  #
185
199
  # = Configuration options
186
200
  #
@@ -255,16 +269,17 @@ module ActionMailer #:nodoc:
255
269
 
256
270
  include AbstractController::Logger
257
271
  include AbstractController::Rendering
258
- include AbstractController::LocalizedCache
259
272
  include AbstractController::Layouts
260
273
  include AbstractController::Helpers
261
274
  include AbstractController::Translation
262
- include AbstractController::Compatibility
263
275
 
264
276
  helper ActionMailer::MailHelper
265
277
 
266
278
  include ActionMailer::OldApi
267
279
  include ActionMailer::DeprecatedApi
280
+
281
+ delegate :register_observer, :to => Mail
282
+ delegate :register_interceptor, :to => Mail
268
283
 
269
284
  private_class_method :new #:nodoc:
270
285
 
@@ -276,6 +291,8 @@ module ActionMailer #:nodoc:
276
291
  :parts_order => [ "text/plain", "text/enriched", "text/html" ]
277
292
  }.freeze
278
293
 
294
+ ActiveSupport.run_load_hooks(:action_mailer, self)
295
+
279
296
  class << self
280
297
 
281
298
  def mailer_name
@@ -452,10 +469,27 @@ module ActionMailer #:nodoc:
452
469
  # field for the 'envelope from' value.
453
470
  #
454
471
  # If you do not pass a block to the +mail+ method, it will find all templates in the
455
- # template path that match the method name that it is being called from, it will then
456
- # create parts for each of these templates intelligently, making educated guesses
457
- # on correct content type and sequence, and return a fully prepared Mail::Message
458
- # ready to call <tt>:deliver</tt> on to send.
472
+ # view paths using by default the mailer name and the method name that it is being
473
+ # called from, it will then create parts for each of these templates intelligently,
474
+ # making educated guesses on correct content type and sequence, and return a fully
475
+ # prepared Mail::Message ready to call <tt>:deliver</tt> on to send.
476
+ #
477
+ # For example:
478
+ #
479
+ # class Notifier < ActionMailer::Base
480
+ # default :from => 'no-reply@test.lindsaar.net',
481
+ #
482
+ # def welcome
483
+ # mail(:to => 'mikel@test.lindsaar.net')
484
+ # end
485
+ # end
486
+ #
487
+ # Will look for all templates at "app/views/notifier" with name "welcome". However, those
488
+ # can be customized:
489
+ #
490
+ # mail(:template_path => 'notifications', :template_name => 'another')
491
+ #
492
+ # And now it will look for all templates at "app/views/notifications" with name "another".
459
493
  #
460
494
  # If you do pass a block, you can render specific templates of your choice:
461
495
  #
@@ -493,7 +527,7 @@ module ActionMailer #:nodoc:
493
527
 
494
528
  # Merge defaults from class
495
529
  headers = headers.reverse_merge(self.class.default)
496
- charset = headers[:charset]
530
+ charset = headers.delete(:charset)
497
531
 
498
532
  # Quote fields
499
533
  headers[:subject] ||= default_i18n_subject
@@ -514,13 +548,11 @@ module ActionMailer #:nodoc:
514
548
  end
515
549
 
516
550
  # Set configure delivery behavior
517
- wrap_delivery_behavior!(headers[:delivery_method])
551
+ wrap_delivery_behavior!(headers.delete(:delivery_method))
518
552
 
519
- # Remove headers already treated and assign all others
520
- headers.except!(:subject, :to, :from, :cc, :bcc, :reply_to)
521
- headers.except!(:body, :parts_order, :content_type, :charset, :delivery_method)
553
+ # Remove any missing configuration header and assign all others
554
+ headers.except!(:parts_order, :content_type)
522
555
  headers.each { |k, v| m[k] = v }
523
-
524
556
  m
525
557
  end
526
558
 
@@ -548,31 +580,36 @@ module ActionMailer #:nodoc:
548
580
  # TODO: Move this into Mail
549
581
  def quote_fields!(headers, charset) #:nodoc:
550
582
  m = @_message
551
- m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject]
552
- m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to]
553
- m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from]
554
- m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc]
555
- m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc]
556
- m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to]
583
+ m.subject ||= quote_if_necessary(headers.delete(:subject), charset) if headers[:subject]
584
+ m.to ||= quote_address_if_necessary(headers.delete(:to), charset) if headers[:to]
585
+ m.from ||= quote_address_if_necessary(headers.delete(:from), charset) if headers[:from]
586
+ m.cc ||= quote_address_if_necessary(headers.delete(:cc), charset) if headers[:cc]
587
+ m.bcc ||= quote_address_if_necessary(headers.delete(:bcc), charset) if headers[:bcc]
588
+ m.reply_to ||= quote_address_if_necessary(headers.delete(:reply_to), charset) if headers[:reply_to]
557
589
  end
558
590
 
559
591
  def collect_responses_and_parts_order(headers) #:nodoc:
560
592
  responses, parts_order = [], nil
561
593
 
562
594
  if block_given?
563
- collector = ActionMailer::Collector.new(self) { render(action_name) }
595
+ collector = ActionMailer::Collector.new(lookup_context) { render(action_name) }
564
596
  yield(collector)
565
597
  parts_order = collector.responses.map { |r| r[:content_type] }
566
598
  responses = collector.responses
567
599
  elsif headers[:body]
568
600
  responses << {
569
- :body => headers[:body],
601
+ :body => headers.delete(:body),
570
602
  :content_type => self.class.default[:content_type] || "text/plain"
571
603
  }
572
604
  else
573
- each_template do |template|
605
+ templates_path = headers.delete(:template_path) || self.class.mailer_name
606
+ templates_name = headers.delete(:template_name) || action_name
607
+
608
+ each_template(templates_path, templates_name) do |template|
609
+ self.formats = template.formats
610
+
574
611
  responses << {
575
- :body => render_to_body(:_template => template),
612
+ :body => render(:template => template),
576
613
  :content_type => template.mime_type.to_s
577
614
  }
578
615
  end
@@ -581,10 +618,10 @@ module ActionMailer #:nodoc:
581
618
  [responses, parts_order]
582
619
  end
583
620
 
584
- def each_template(&block) #:nodoc:
585
- self.class.view_paths.each do |load_paths|
586
- templates = load_paths.find_all(action_name, {}, self.class.mailer_name)
587
- templates = templates.uniq_by { |t| t.details[:formats] }
621
+ def each_template(paths, name, &block) #:nodoc:
622
+ Array.wrap(paths).each do |path|
623
+ templates = lookup_context.find_all(name, path)
624
+ templates = templates.uniq_by { |t| t.formats }
588
625
 
589
626
  unless templates.empty?
590
627
  templates.each(&block)
@@ -11,7 +11,6 @@ module ActionMailer #:nodoc:
11
11
  @context = context
12
12
  @responses = []
13
13
  @default_render = block
14
- @default_formats = context.formats
15
14
  end
16
15
 
17
16
  def any(*args, &block)
@@ -21,16 +20,11 @@ module ActionMailer #:nodoc:
21
20
  end
22
21
  alias :all :any
23
22
 
24
- def custom(mime, options={}, &block)
23
+ def custom(mime, options={})
25
24
  options.reverse_merge!(:content_type => mime.to_s)
26
- @context.formats = [mime.to_sym]
27
- options[:body] = if block
28
- block.call
29
- else
30
- @default_render.call
31
- end
25
+ @context.freeze_formats([mime.to_sym])
26
+ options[:body] = block_given? ? yield : @default_render.call
32
27
  @responses << options
33
- @context.formats = @default_formats
34
28
  end
35
29
  end
36
30
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/object/try'
2
+ require 'active_support/core_ext/object/blank'
2
3
 
3
4
  module ActionMailer
4
5
  module OldApi #:nodoc:
@@ -31,9 +32,6 @@ module ActionMailer
31
32
  # replies to this message.
32
33
  adv_attr_accessor :reply_to
33
34
 
34
- # Specify additional headers to be added to the message.
35
- adv_attr_accessor :headers
36
-
37
35
  # Specify the order in which parts should be sorted, based on content-type.
38
36
  # This defaults to the value for the +default_implicit_parts_order+.
39
37
  adv_attr_accessor :implicit_parts_order
@@ -206,8 +204,9 @@ module ActionMailer
206
204
  if String === @body
207
205
  @parts.unshift create_inline_part(@body)
208
206
  elsif @parts.empty? || @parts.all? { |p| p.content_disposition =~ /^attachment/ }
209
- self.class.view_paths.first.find_all(@template, {}, @mailer_name).each do |template|
210
- @parts << create_inline_part(render_to_body(:_template => template), template.mime_type)
207
+ lookup_context.find_all(@template, @mailer_name).each do |template|
208
+ self.formats = template.formats
209
+ @parts << create_inline_part(render(:template => template), template.mime_type)
211
210
  end
212
211
 
213
212
  if @parts.size > 1
@@ -22,7 +22,7 @@ module ActionMailer
22
22
  # A quick-and-dirty regexp for determining whether a string contains any
23
23
  # characters that need escaping.
24
24
  if !defined?(CHARS_NEEDING_QUOTING)
25
- CHARS_NEEDING_QUOTING = /[\000-\011\013\014\016-\037\177-\377]/
25
+ CHARS_NEEDING_QUOTING = Regexp.new('[\000-\011\013\014\016-\037\177-\377]', nil, 'n')
26
26
  end
27
27
 
28
28
  # Quote the given text if it contains any "illegal" characters
@@ -3,23 +3,25 @@ require "rails"
3
3
 
4
4
  module ActionMailer
5
5
  class Railtie < Rails::Railtie
6
- railtie_name :action_mailer
6
+ config.action_mailer = ActiveSupport::OrderedOptions.new
7
7
 
8
- require "action_mailer/railties/subscriber"
9
- subscriber ActionMailer::Railties::Subscriber.new
8
+ initializer "action_mailer.url_for", :before => :load_environment_config do |app|
9
+ ActiveSupport.on_load(:action_mailer) { include app.routes.url_helpers }
10
+ end
11
+
12
+ require "action_mailer/railties/log_subscriber"
13
+ log_subscriber :action_mailer, ActionMailer::Railties::LogSubscriber.new
10
14
 
11
15
  initializer "action_mailer.logger" do
12
- ActionMailer::Base.logger ||= Rails.logger
16
+ ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger }
13
17
  end
14
18
 
15
19
  initializer "action_mailer.set_configs" do |app|
16
- app.config.action_mailer.each do |k,v|
17
- ActionMailer::Base.send "#{k}=", v
20
+ ActiveSupport.on_load(:action_mailer) do
21
+ app.config.action_mailer.each do |k,v|
22
+ send "#{k}=", v
23
+ end
18
24
  end
19
25
  end
20
-
21
- initializer "action_mailer.url_for" do |app|
22
- ActionMailer::Base.send(:include, ActionController::UrlFor) if defined?(ActionController)
23
- end
24
26
  end
25
- end
27
+ end
@@ -1,8 +1,10 @@
1
+ require 'active_support/core_ext/array/wrap'
2
+
1
3
  module ActionMailer
2
4
  module Railties
3
- class Subscriber < Rails::Subscriber
5
+ class LogSubscriber < Rails::LogSubscriber
4
6
  def deliver(event)
5
- recipients = Array(event.payload[:to]).join(', ')
7
+ recipients = Array.wrap(event.payload[:to]).join(', ')
6
8
  info("\nSent mail to #{recipients} (%1.fms)" % event.duration)
7
9
  debug(event.payload[:mail])
8
10
  end
@@ -17,4 +19,4 @@ module ActionMailer
17
19
  end
18
20
  end
19
21
  end
20
- end
22
+ end
@@ -2,8 +2,9 @@ module ActionMailer
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
- TINY = "0.beta"
5
+ TINY = 0
6
+ BUILD = "beta2"
6
7
 
7
- STRING = [MAJOR, MINOR, TINY].join('.')
8
+ STRING = [MAJOR, MINOR, TINY, BUILD].join('.')
8
9
  end
9
10
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionmailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta
4
+ prerelease: true
5
+ segments:
6
+ - 3
7
+ - 0
8
+ - 0
9
+ - beta2
10
+ version: 3.0.0.beta2
5
11
  platform: ruby
6
12
  authors:
7
13
  - David Heinemeier Hansson
@@ -9,40 +15,54 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-04 00:00:00 -08:00
18
+ date: 2010-04-01 00:00:00 -07:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: actionpack
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
20
25
  requirements:
21
26
  - - "="
22
27
  - !ruby/object:Gem::Version
23
- version: 3.0.0.beta
24
- version:
28
+ segments:
29
+ - 3
30
+ - 0
31
+ - 0
32
+ - beta2
33
+ version: 3.0.0.beta2
34
+ type: :runtime
35
+ version_requirements: *id001
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: mail
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
30
40
  requirements:
31
41
  - - ~>
32
42
  - !ruby/object:Gem::Version
33
- version: 2.1.2
34
- version:
43
+ segments:
44
+ - 2
45
+ - 1
46
+ - 5
47
+ - 3
48
+ version: 2.1.5.3
49
+ type: :runtime
50
+ version_requirements: *id002
35
51
  - !ruby/object:Gem::Dependency
36
52
  name: text-format
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
40
55
  requirements:
41
56
  - - ~>
42
57
  - !ruby/object:Gem::Version
58
+ segments:
59
+ - 1
60
+ - 0
61
+ - 0
43
62
  version: 1.0.0
44
- version:
45
- description: Email composition, delivery, and recieval framework (part of Rails).
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ description: Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments.
46
66
  email: david@loudthinking.com
47
67
  executables: []
48
68
 
@@ -63,7 +83,7 @@ files:
63
83
  - lib/action_mailer/old_api.rb
64
84
  - lib/action_mailer/quoting.rb
65
85
  - lib/action_mailer/railtie.rb
66
- - lib/action_mailer/railties/subscriber.rb
86
+ - lib/action_mailer/railties/log_subscriber.rb
67
87
  - lib/action_mailer/test_case.rb
68
88
  - lib/action_mailer/test_helper.rb
69
89
  - lib/action_mailer/tmail_compat.rb
@@ -82,20 +102,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
82
102
  requirements:
83
103
  - - ">="
84
104
  - !ruby/object:Gem::Version
85
- version: "0"
86
- version:
105
+ segments:
106
+ - 1
107
+ - 8
108
+ - 7
109
+ version: 1.8.7
87
110
  required_rubygems_version: !ruby/object:Gem::Requirement
88
111
  requirements:
89
112
  - - ">"
90
113
  - !ruby/object:Gem::Version
114
+ segments:
115
+ - 1
116
+ - 3
117
+ - 1
91
118
  version: 1.3.1
92
- version:
93
119
  requirements:
94
120
  - none
95
121
  rubyforge_project: actionmailer
96
- rubygems_version: 1.3.5
122
+ rubygems_version: 1.3.6
97
123
  signing_key:
98
124
  specification_version: 3
99
- summary: Email composition, delivery, and recieval framework (part of Rails).
125
+ summary: Email composition, delivery, and receiving framework (part of Rails).
100
126
  test_files: []
101
127