aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer/lib/action_mailer
diff options
context:
space:
mode:
authorMatthew Rudy Jacobs <MatthewRudyJacobs@gmail.com>2009-10-28 09:17:59 +0000
committerYehuda Katz <wycats@gmail.com>2009-11-01 02:23:47 +0100
commitf4f76772fb5c25357a54baaa9cd20f7e9a1cd653 (patch)
treec3095ca798d006fa5750538d862cf5fcc35da6ba /actionmailer/lib/action_mailer
parent3f560386125adabe441facf2514ad53425e4af4e (diff)
downloadrails-f4f76772fb5c25357a54baaa9cd20f7e9a1cd653.tar.gz
rails-f4f76772fb5c25357a54baaa9cd20f7e9a1cd653.tar.bz2
rails-f4f76772fb5c25357a54baaa9cd20f7e9a1cd653.zip
abstract all of the ActionMailer delivery methods into their own classes. thereby the following are equivalent
ActionMailer::Base.delivery_method = :smtp ActionMailer::Base.delivery_method = ActionMailer::DeliveryMethod::Smtp we could equally set our own custom object as long as it provides the instance method :perform_delivery(mail) eg. class MySmsDeliveryMethod def perform_delivery(mail) Sms.send(mail['to'], mail['body']) end end MySmsMailer.delivery_method = MySmsDeliveryMethod.new Signed-off-by: José Valim <jose.valim@gmail.com>
Diffstat (limited to 'actionmailer/lib/action_mailer')
-rw-r--r--actionmailer/lib/action_mailer/base.rb75
-rw-r--r--actionmailer/lib/action_mailer/delivery_method.rb58
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/file.rb21
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/sendmail.rb22
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/smtp.rb31
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/test.rb12
6 files changed, 157 insertions, 62 deletions
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index df3bfb3620..898356075f 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -1,5 +1,3 @@
-require 'tmpdir'
-
require "active_support/core_ext/class"
# Use the old layouts until actionmailer gets refactored
require "action_controller/legacy/layout"
@@ -232,7 +230,7 @@ module ActionMailer #:nodoc:
# * <tt>raise_delivery_errors</tt> - Whether or not errors should be raised if the email fails to be delivered.
#
# * <tt>delivery_method</tt> - Defines a delivery method. Possible values are <tt>:smtp</tt> (default), <tt>:sendmail</tt>, <tt>:test</tt>,
- # and <tt>:file</tt>.
+ # and <tt>:file</tt>. Or you may provide a custom delivery method object eg. MyOwnDeliveryMethodClass.new
#
# * <tt>perform_deliveries</tt> - Determines whether <tt>deliver_*</tt> methods are actually carried out. By default they are,
# but this can be turned off to help functional testing.
@@ -270,35 +268,21 @@ module ActionMailer #:nodoc:
cattr_accessor :logger
- @@smtp_settings = {
- :address => "localhost",
- :port => 25,
- :domain => 'localhost.localdomain',
- :user_name => nil,
- :password => nil,
- :authentication => nil,
- :enable_starttls_auto => true,
- }
- cattr_accessor :smtp_settings
-
- @@sendmail_settings = {
- :location => '/usr/sbin/sendmail',
- :arguments => '-i -t'
- }
- cattr_accessor :sendmail_settings
-
- @@file_settings = {
- :location => defined?(Rails) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
- }
-
- cattr_accessor :file_settings
+ class << self
+ delegate :settings, :settings=, :to => ActionMailer::DeliveryMethod::File, :prefix => :file
+ delegate :settings, :settings=, :to => ActionMailer::DeliveryMethod::Sendmail, :prefix => :sendmail
+ delegate :settings, :settings=, :to => ActionMailer::DeliveryMethod::Smtp, :prefix => :smtp
+
+ def delivery_method=(method_name)
+ @delivery_method = ActionMailer::DeliveryMethod.lookup_method(method_name)
+ end
+ end
+ self.delivery_method = :smtp
+ superclass_delegating_reader :delivery_method
@@raise_delivery_errors = true
cattr_accessor :raise_delivery_errors
- superclass_delegating_accessor :delivery_method
- self.delivery_method = :smtp
-
@@perform_deliveries = true
cattr_accessor :perform_deliveries
@@ -552,7 +536,7 @@ module ActionMailer #:nodoc:
ActiveSupport::Notifications.instrument(:deliver_mail, :mail => @mail) do
begin
- __send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
+ self.delivery_method.perform_delivery(mail) if perform_deliveries
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
raise e if raise_delivery_errors
end
@@ -720,39 +704,6 @@ module ActionMailer #:nodoc:
@mail = m
end
- def perform_delivery_smtp(mail)
- destinations = mail.destinations
- mail.ready_to_send
- sender = (mail['return-path'] && mail['return-path'].spec) || mail['from']
-
- smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
- smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
- smtp.start(smtp_settings[:domain], smtp_settings[:user_name], smtp_settings[:password],
- smtp_settings[:authentication]) do |smtp|
- smtp.sendmail(mail.encoded, sender, destinations)
- end
- end
-
- def perform_delivery_sendmail(mail)
- sendmail_args = sendmail_settings[:arguments]
- sendmail_args += " -f \"#{mail['return-path']}\"" if mail['return-path']
- IO.popen("#{sendmail_settings[:location]} #{sendmail_args}","w+") do |sm|
- sm.print(mail.encoded.gsub(/\r/, ''))
- sm.flush
- end
- end
-
- def perform_delivery_test(mail)
- deliveries << mail
- end
-
- def perform_delivery_file(mail)
- FileUtils.mkdir_p file_settings[:location]
-
- (mail.to + mail.cc + mail.bcc).uniq.each do |to|
- File.open(File.join(file_settings[:location], to), 'a') { |f| f.write(mail) }
- end
- end
end
Base.class_eval do
diff --git a/actionmailer/lib/action_mailer/delivery_method.rb b/actionmailer/lib/action_mailer/delivery_method.rb
new file mode 100644
index 0000000000..ffba3c418c
--- /dev/null
+++ b/actionmailer/lib/action_mailer/delivery_method.rb
@@ -0,0 +1,58 @@
+require "active_support/core_ext/class"
+module ActionMailer
+ module DeliveryMethod
+
+ autoload :File, 'action_mailer/delivery_method/file'
+ autoload :Sendmail, 'action_mailer/delivery_method/sendmail'
+ autoload :Smtp, 'action_mailer/delivery_method/smtp'
+ autoload :Test, 'action_mailer/delivery_method/test'
+
+ # Creates a new DeliveryMethod object according to the given options.
+ #
+ # If no arguments are passed to this method, then a new
+ # ActionMailer::DeliveryMethod::Stmp object will be returned.
+ #
+ # If you pass a Symbol as the first argument, then a corresponding
+ # delivery method class under the ActionMailer::DeliveryMethod namespace
+ # will be created.
+ # For example:
+ #
+ # ActionMailer::DeliveryMethod.lookup_method(:sendmail)
+ # # => returns a new ActionMailer::DeliveryMethod::Sendmail object
+ #
+ # If the first argument is not a Symbol, then it will simply be returned:
+ #
+ # ActionMailer::DeliveryMethod.lookup_method(MyOwnDeliveryMethod.new)
+ # # => returns MyOwnDeliveryMethod.new
+ def self.lookup_method(delivery_method)
+ case delivery_method
+ when Symbol
+ method_name = delivery_method.to_s.camelize
+ method_class = ActionMailer::DeliveryMethod.const_get(method_name)
+ method_class.new()
+ when nil
+ Smtp.new
+ else
+ delivery_method
+ end
+ end
+
+ # An abstract delivery method class. There are multiple delivery method
+ # classes, documented under
+ # See the classes under the ActionMailer::DeliveryMethod, e.g.
+ # ActionMailer::DeliveryMethod::Smtp.
+ # Smtp is the default delivery method for production
+ # while Test is used in testing.
+ #
+ # each delivery method exposes just one method
+ #
+ # delivery_method = ActionMailer::DeliveryMethod::Smtp.new
+ #
+ # delivery_method.perform_delivery(mail) # send the mail via smtp
+ class Method
+ superclass_delegating_accessor :settings
+ self.settings = {}
+ end
+
+ end
+end
diff --git a/actionmailer/lib/action_mailer/delivery_method/file.rb b/actionmailer/lib/action_mailer/delivery_method/file.rb
new file mode 100644
index 0000000000..8807a05221
--- /dev/null
+++ b/actionmailer/lib/action_mailer/delivery_method/file.rb
@@ -0,0 +1,21 @@
+require 'tmpdir'
+module ActionMailer
+ module DeliveryMethod
+
+ # A delivery method implementation which writes all mails to a file.
+ class File < Method
+
+ self.settings = {
+ :location => defined?(Rails) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
+ }
+
+ def perform_delivery(mail)
+ FileUtils.mkdir_p settings[:location]
+
+ (mail.to + mail.cc + mail.bcc).uniq.each do |to|
+ ::File.open(::File.join(settings[:location], to), 'a') { |f| f.write(mail) }
+ end
+ end
+ end
+ end
+end
diff --git a/actionmailer/lib/action_mailer/delivery_method/sendmail.rb b/actionmailer/lib/action_mailer/delivery_method/sendmail.rb
new file mode 100644
index 0000000000..34e03b8060
--- /dev/null
+++ b/actionmailer/lib/action_mailer/delivery_method/sendmail.rb
@@ -0,0 +1,22 @@
+module ActionMailer
+ module DeliveryMethod
+
+ # A delivery method implementation which sends via sendmail.
+ class Sendmail < Method
+
+ self.settings = {
+ :location => '/usr/sbin/sendmail',
+ :arguments => '-i -t'
+ }
+
+ def perform_delivery(mail)
+ sendmail_args = settings[:arguments]
+ sendmail_args += " -f \"#{mail['return-path']}\"" if mail['return-path']
+ IO.popen("#{settings[:location]} #{sendmail_args}","w+") do |sm|
+ sm.print(mail.encoded.gsub(/\r/, ''))
+ sm.flush
+ end
+ end
+ end
+ end
+end
diff --git a/actionmailer/lib/action_mailer/delivery_method/smtp.rb b/actionmailer/lib/action_mailer/delivery_method/smtp.rb
new file mode 100644
index 0000000000..e39f97330c
--- /dev/null
+++ b/actionmailer/lib/action_mailer/delivery_method/smtp.rb
@@ -0,0 +1,31 @@
+module ActionMailer
+ module DeliveryMethod
+
+ # A delivery method implementation which sends via smtp.
+ class Smtp < Method
+
+ self.settings = {
+ :address => "localhost",
+ :port => 25,
+ :domain => 'localhost.localdomain',
+ :user_name => nil,
+ :password => nil,
+ :authentication => nil,
+ :enable_starttls_auto => true,
+ }
+
+ def perform_delivery(mail)
+ destinations = mail.destinations
+ mail.ready_to_send
+ sender = (mail['return-path'] && mail['return-path'].spec) || mail['from']
+
+ smtp = Net::SMTP.new(settings[:address], settings[:port])
+ smtp.enable_starttls_auto if settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
+ smtp.start(settings[:domain], settings[:user_name], settings[:password],
+ settings[:authentication]) do |smtp|
+ smtp.sendmail(mail.encoded, sender, destinations)
+ end
+ end
+ end
+ end
+end
diff --git a/actionmailer/lib/action_mailer/delivery_method/test.rb b/actionmailer/lib/action_mailer/delivery_method/test.rb
new file mode 100644
index 0000000000..e63e0abbb8
--- /dev/null
+++ b/actionmailer/lib/action_mailer/delivery_method/test.rb
@@ -0,0 +1,12 @@
+module ActionMailer
+ module DeliveryMethod
+
+ # A delivery method implementation designed for testing, which just appends each record to the :deliveries array
+ class Test < Method
+
+ def perform_delivery(mail)
+ ActionMailer::Base.deliveries << mail
+ end
+ end
+ end
+end