postageapp 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/LICENSE +1 -1
- data/README.md +176 -0
- data/Rakefile +14 -12
- data/VERSION +1 -1
- data/generators/postageapp/postageapp_generator.rb +34 -0
- data/generators/postageapp/templates/initializer.rb +3 -0
- data/generators/postageapp/templates/postageapp_tasks.rake +78 -0
- data/lib/generators/postageapp/postageapp_generator.rb +27 -0
- data/lib/postageapp.rb +56 -0
- data/lib/postageapp/configuration.rb +91 -0
- data/lib/postageapp/failed_request.rb +64 -0
- data/lib/postageapp/logger.rb +16 -0
- data/lib/postageapp/mailer.rb +48 -0
- data/lib/postageapp/mailer/mailer_2.rb +92 -0
- data/lib/postageapp/mailer/mailer_3.rb +192 -0
- data/lib/postageapp/rails.rb +14 -0
- data/lib/postageapp/request.rb +87 -0
- data/lib/postageapp/response.rb +39 -0
- data/lib/postageapp/utils.rb +30 -0
- data/lib/postageapp/version.rb +7 -0
- data/postageapp.gemspec +61 -7
- data/test/configuration_test.rb +66 -0
- data/test/failed_request_test.rb +79 -0
- data/test/helper.rb +66 -0
- data/test/mailer/action_mailer_2/notifier.rb +64 -0
- data/test/mailer/action_mailer_2/notifier/with_body_and_attachment.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.html.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.plain.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_simple_view.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_text_only_view.text.plain.erb +1 -0
- data/test/mailer/action_mailer_3/notifier.rb +98 -0
- data/test/mailer/action_mailer_3/notifier/with_html_and_text_views.html.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_html_and_text_views.text.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_old_api.html.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_old_api.text.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_simple_view.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_text_only_view.text.erb +1 -0
- data/test/mailer_2_test.rb +87 -0
- data/test/mailer_3_test.rb +104 -0
- data/test/mailer_helper_methods_test.rb +24 -0
- data/test/postageapp_test.rb +18 -0
- data/test/rails_initialization_test.rb +29 -0
- data/test/request_integration_test.rb +78 -0
- data/test/request_test.rb +81 -0
- data/test/response_test.rb +40 -0
- metadata +84 -9
- data/README.rdoc +0 -17
- data/test/test_postageapp.rb +0 -7
@@ -0,0 +1,91 @@
|
|
1
|
+
class PostageApp::Configuration
|
2
|
+
|
3
|
+
# The API key for your postageapp.com project
|
4
|
+
attr_accessor :api_key
|
5
|
+
|
6
|
+
# +true+ for https, +false+ for http connections (default: is +true+)
|
7
|
+
attr_accessor :secure
|
8
|
+
|
9
|
+
# The protocol used to connect to the service (default: 'https' for secure
|
10
|
+
# and 'http' for insecure connections)
|
11
|
+
attr_accessor :protocol
|
12
|
+
|
13
|
+
# The host to connect to (default: 'api.postageapp.com')
|
14
|
+
attr_accessor :host
|
15
|
+
|
16
|
+
# The port on which PostageApp service runs (default: 443 for secure, 80 for
|
17
|
+
# insecure connections)
|
18
|
+
attr_accessor :port
|
19
|
+
|
20
|
+
# The hostname of the proxy server (if using a proxy)
|
21
|
+
attr_accessor :proxy_host
|
22
|
+
|
23
|
+
# The port of the proxy server (if using proxy)
|
24
|
+
attr_accessor :proxy_port
|
25
|
+
|
26
|
+
# The username for the proxy server (if using proxy)
|
27
|
+
attr_accessor :proxy_user
|
28
|
+
|
29
|
+
# The password for the proxy server (if using proxy)
|
30
|
+
attr_accessor :proxy_pass
|
31
|
+
|
32
|
+
# The HTTP open timeout in seconds (defaults to 2).
|
33
|
+
attr_accessor :http_open_timeout
|
34
|
+
|
35
|
+
# The HTTP read timeout in seconds (defaults to 5).
|
36
|
+
attr_accessor :http_read_timeout
|
37
|
+
|
38
|
+
# The email address that all send_message method should address
|
39
|
+
# all messages while overriding original addresses
|
40
|
+
attr_accessor :recipient_override
|
41
|
+
|
42
|
+
# A list of API method names payloads of which are captured and resent
|
43
|
+
# in case of service unavailability
|
44
|
+
attr_accessor :requests_to_resend
|
45
|
+
|
46
|
+
# The file path of the project. This is where logs and failed requests
|
47
|
+
# can be stored
|
48
|
+
attr_accessor :project_root
|
49
|
+
|
50
|
+
# The framework PostageApp gem runs in
|
51
|
+
attr_accessor :framework
|
52
|
+
|
53
|
+
# Environment gem is running in
|
54
|
+
attr_accessor :environment
|
55
|
+
|
56
|
+
# The logger used by this gem
|
57
|
+
attr_accessor :logger
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@secure = true
|
61
|
+
@host = 'api.postageapp.com'
|
62
|
+
@http_open_timeout = 5
|
63
|
+
@http_read_timeout = 10
|
64
|
+
@requests_to_resend = %w( send_message )
|
65
|
+
@framework = 'undefined framework'
|
66
|
+
@environment = 'production'
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :secure?, :secure
|
70
|
+
|
71
|
+
def protocol
|
72
|
+
@protocol || if secure?
|
73
|
+
'https'
|
74
|
+
else
|
75
|
+
'http'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def port
|
80
|
+
@port || if secure?
|
81
|
+
443
|
82
|
+
else
|
83
|
+
80
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def url
|
88
|
+
"#{self.protocol}://#{self.host}:#{self.port}"
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module PostageApp::FailedRequest
|
2
|
+
|
3
|
+
# Stores request object into a file for future re-send
|
4
|
+
# returns true if stored, false if not (due to undefined project path)
|
5
|
+
def self.store(request)
|
6
|
+
return false if !store_path || !PostageApp.configuration.requests_to_resend.member?(request.method.to_s)
|
7
|
+
|
8
|
+
open(file_path(request.uid), 'w') do |f|
|
9
|
+
f.write(Marshal.dump(request))
|
10
|
+
end unless File.exists?(file_path(request.uid))
|
11
|
+
|
12
|
+
PostageApp.logger.info "STORING FAILED REQUEST [#{request.uid}]"
|
13
|
+
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
# Attempting to resend failed requests
|
18
|
+
def self.resend_all
|
19
|
+
return false if !store_path
|
20
|
+
|
21
|
+
Dir.foreach(store_path) do |filename|
|
22
|
+
next if !filename.match /^\w{40}$/
|
23
|
+
|
24
|
+
request = initialize_request(filename)
|
25
|
+
|
26
|
+
receipt_response = PostageApp::Request.new(:get_message_receipt, :uid => filename).send(true)
|
27
|
+
if receipt_response.ok?
|
28
|
+
PostageApp.logger.info "NOT RESENDING FAILED REQUEST [#{filename}]"
|
29
|
+
File.delete(file_path(filename))
|
30
|
+
|
31
|
+
elsif receipt_response.not_found?
|
32
|
+
PostageApp.logger.info "RESENDING FAILED REQUEST [#{filename}]"
|
33
|
+
response = request.send(true)
|
34
|
+
|
35
|
+
# Not a fail, so we can remove this file, if it was then
|
36
|
+
# there will be another attempt to resend
|
37
|
+
File.delete(file_path(filename)) if !response.fail?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
# Initializing PostageApp::Request object from the file
|
45
|
+
def self.initialize_request(uid)
|
46
|
+
return false if !store_path
|
47
|
+
|
48
|
+
Marshal.load(File.read(file_path(uid))) if File.exists?(file_path(uid))
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def self.store_path
|
54
|
+
return if !PostageApp.configuration.project_root
|
55
|
+
dir = File.join(File.expand_path(PostageApp.configuration.project_root), 'tmp/postageapp_failed_requests')
|
56
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
57
|
+
return dir
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.file_path(uid)
|
61
|
+
File.join(store_path, uid)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class PostageApp::Logger < ::Logger
|
2
|
+
|
3
|
+
def format_message(severity, datetime, progname, msg)
|
4
|
+
timestamp = datetime.strftime('%m/%d/%Y %H:%M:%S %Z')
|
5
|
+
message = case msg
|
6
|
+
when PostageApp::Request
|
7
|
+
"REQUEST [#{msg.url}]\n #{msg.arguments_to_send.to_json}"
|
8
|
+
when PostageApp::Response
|
9
|
+
"RESPONSE [#{msg.status} #{msg.uid} #{msg.message}]\n #{msg.data.to_json}"
|
10
|
+
else
|
11
|
+
msg
|
12
|
+
end
|
13
|
+
"[#{timestamp}] #{message}\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'action_mailer'
|
2
|
+
require 'action_mailer/version'
|
3
|
+
|
4
|
+
# Loading PostageApp::Mailer class depending on what action_mailer is
|
5
|
+
# currently installed on the system. Assuming we're dealing only with
|
6
|
+
# ones that come with Rails 2 and 3
|
7
|
+
if ActionMailer::VERSION::MAJOR >= 3
|
8
|
+
require File.expand_path('../mailer/mailer_3', __FILE__)
|
9
|
+
else
|
10
|
+
require File.expand_path('../mailer/mailer_2', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
# General helper methods for Request object to act more like TMail::Mail
|
14
|
+
# of Mail for testing
|
15
|
+
class PostageApp::Request
|
16
|
+
|
17
|
+
# Getter and setter for headers. You can specify headers in the following
|
18
|
+
# formats:
|
19
|
+
# headers['Custom-Header'] = 'Custom Value'
|
20
|
+
# headers 'Custom-Header-1' => 'Custom Value 1',
|
21
|
+
# 'Custom-Header-2' => 'Custom Value 2'
|
22
|
+
def headers(value = nil)
|
23
|
+
self.arguments['headers'] ||= { }
|
24
|
+
if value && value.is_a?(Hash)
|
25
|
+
value.each do |k, v|
|
26
|
+
self.arguments['headers'][k.to_s] = v.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
self.arguments['headers']
|
30
|
+
end
|
31
|
+
|
32
|
+
def to
|
33
|
+
self.arguments_to_send.dig('arguments', 'recipients')
|
34
|
+
end
|
35
|
+
|
36
|
+
def from
|
37
|
+
self.arguments_to_send.dig('arguments', 'headers', 'from')
|
38
|
+
end
|
39
|
+
|
40
|
+
def subject
|
41
|
+
self.arguments_to_send.dig('arguments', 'headers', 'subject')
|
42
|
+
end
|
43
|
+
|
44
|
+
def body
|
45
|
+
self.arguments_to_send.dig('arguments', 'content')
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Postage::Mailer allows you to use/re-use existing mailers set up using
|
2
|
+
# ActionMailer. The only catch is to change inheritance from ActionMailer::Base
|
3
|
+
# to PostageApp::Mailer. Also don't forget to require 'postageapp/mailer'
|
4
|
+
#
|
5
|
+
# Here's an example of a valid PostageApp::Mailer class
|
6
|
+
#
|
7
|
+
# require 'postageapp/mailer'
|
8
|
+
#
|
9
|
+
# class Notifier < PostageApp::Mailer
|
10
|
+
# def signup_notification(recipient)
|
11
|
+
# recipients recipient.email_address
|
12
|
+
# from 'system@example.com'
|
13
|
+
# subject 'New Account Information'
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# Postage::Mailer introduces a few mailer methods specific to Postage:
|
18
|
+
#
|
19
|
+
# * postage_template - template name that is defined in your PostageApp project
|
20
|
+
# * postage_variables - extra variables you want to send along with the message
|
21
|
+
#
|
22
|
+
# Sending email
|
23
|
+
#
|
24
|
+
# Notifier.deliver_signup_notification(user) # attempts to deliver to PostageApp (depending on env)
|
25
|
+
# request = Notifier.create_signup_notification(user) # creates PostageApp::Request object
|
26
|
+
#
|
27
|
+
class PostageApp::Mailer < ActionMailer::Base
|
28
|
+
|
29
|
+
# Using :test as a delivery method if set somewhere else
|
30
|
+
self.delivery_method = :postage unless (self.delivery_method == :test)
|
31
|
+
|
32
|
+
adv_attr_accessor :postage_template
|
33
|
+
adv_attr_accessor :postage_variables
|
34
|
+
|
35
|
+
def perform_delivery_postage(mail)
|
36
|
+
mail.send
|
37
|
+
end
|
38
|
+
|
39
|
+
def deliver!(mail = @mail)
|
40
|
+
raise 'PostageApp::Request object not present, cannot deliver' unless mail
|
41
|
+
__send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creating a Postage::Request object unlike TMail one in ActionMailer::Base
|
45
|
+
def create_mail
|
46
|
+
params = { }
|
47
|
+
params['recipients'] = self.recipients unless self.recipients.blank?
|
48
|
+
|
49
|
+
params['headers'] = { }
|
50
|
+
params['headers']['subject'] = self.subject unless self.subject.blank?
|
51
|
+
params['headers']['from'] = self.from unless self.from.blank?
|
52
|
+
params['headers'].merge!(self.headers) unless self.headers.blank?
|
53
|
+
|
54
|
+
params['content'] = { }
|
55
|
+
params['attachments'] = { }
|
56
|
+
|
57
|
+
if @parts.empty?
|
58
|
+
params['content'][self.content_type] = self.body unless self.body.blank?
|
59
|
+
else
|
60
|
+
self.parts.each do |part|
|
61
|
+
case part.content_disposition
|
62
|
+
when 'inline'
|
63
|
+
part.content_type = 'text/plain' if part.content_type.blank? && String === part.body
|
64
|
+
params['content'][part.content_type] = part.body
|
65
|
+
when 'attachment'
|
66
|
+
params['attachments'][part.filename] = {
|
67
|
+
'content_type' => part.content_type,
|
68
|
+
'content' => Base64.encode64(part.body)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
params['template'] = self.postage_template unless self.postage_template.blank?
|
75
|
+
params['variables'] = self.postage_variables unless self.postage_variables.blank?
|
76
|
+
|
77
|
+
params.delete('headers') if params['headers'].blank?
|
78
|
+
params.delete('content') if params['content'].blank?
|
79
|
+
params.delete('attachments') if params['attachments'].blank?
|
80
|
+
|
81
|
+
@mail = PostageApp::Request.new(:send_message, params)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Not insisting rendering a view if it's not there. PostageApp gem can send blank content
|
85
|
+
# provided that the template is defined.
|
86
|
+
def render(opts)
|
87
|
+
super(opts)
|
88
|
+
rescue ActionView::MissingTemplate
|
89
|
+
# do nothing
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# Postage::Mailer allows you to use/re-use existing mailers set up using
|
2
|
+
# ActionMailer. The only catch is to change inheritance from ActionMailer::Base
|
3
|
+
# to PostageApp::Mailer. Also don't forget to require 'postageapp/mailer'
|
4
|
+
#
|
5
|
+
# Here's an example of a valid PostageApp::Mailer class
|
6
|
+
#
|
7
|
+
# require 'postageapp/mailer'
|
8
|
+
#
|
9
|
+
# class Notifier < PostageApp::Mailer
|
10
|
+
# def signup_notification(recipient)
|
11
|
+
# mail(
|
12
|
+
# :to => recipient.email,
|
13
|
+
# :from => 'sender@test.test',
|
14
|
+
# :subject => 'Test Message'
|
15
|
+
# )
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Postage::Mailer introduces a few mailer methods specific to Postage:
|
20
|
+
#
|
21
|
+
# * postage_template - template name that is defined in your PostageApp project
|
22
|
+
# * postage_variables - extra variables you want to send along with the message
|
23
|
+
#
|
24
|
+
# Sending email
|
25
|
+
#
|
26
|
+
# request = Notifier.signup_notification(user) # creates PostageApp::Request object
|
27
|
+
# response = request.deliver # attempts to deliver the message and creates a PostageApp::Response
|
28
|
+
#
|
29
|
+
class PostageApp::Mailer < ActionMailer::Base
|
30
|
+
|
31
|
+
# Wrapper for creating attachments
|
32
|
+
# Attachments sent to PostageApp are in the following format:
|
33
|
+
# 'filename.ext' => {
|
34
|
+
# 'content_type' => 'content/type',
|
35
|
+
# 'content' => 'base64_encoded_content'
|
36
|
+
# }
|
37
|
+
class Attachments < Hash
|
38
|
+
|
39
|
+
def initialize(message)
|
40
|
+
@_message = message
|
41
|
+
message.arguments['attachments'] ||= { }
|
42
|
+
end
|
43
|
+
|
44
|
+
def []=(filename, attachment)
|
45
|
+
default_content_type = MIME::Types.type_for(filename).first.content_type rescue ''
|
46
|
+
if attachment.is_a?(Hash)
|
47
|
+
content_type = attachment[:content_type] || default_content_type
|
48
|
+
content = Base64.encode64(attachment[:body])
|
49
|
+
else
|
50
|
+
content_type = default_content_type
|
51
|
+
content = Base64.encode64(attachment)
|
52
|
+
end
|
53
|
+
@_message.arguments['attachments'][filename] = {
|
54
|
+
'content_type' => content_type,
|
55
|
+
'content' => content
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# In API call we can specify PostageApp template that will be used
|
61
|
+
# to generate content of the message
|
62
|
+
attr_accessor :postage_template
|
63
|
+
|
64
|
+
# Hash of variables that will be used to inject into the content
|
65
|
+
attr_accessor :postage_variables
|
66
|
+
|
67
|
+
# Instead of initializing Mail object, we prepare PostageApp::Request
|
68
|
+
def initialize(method_name = nil, *args)
|
69
|
+
@_message = PostageApp::Request.new(:send_message)
|
70
|
+
process(method_name, *args) if method_name
|
71
|
+
end
|
72
|
+
|
73
|
+
def postage_template(value)
|
74
|
+
@_message.arguments['template'] = value
|
75
|
+
end
|
76
|
+
|
77
|
+
def postage_variables(variables = {})
|
78
|
+
@_message.arguments['variables'] = variables
|
79
|
+
end
|
80
|
+
|
81
|
+
def attachments
|
82
|
+
@_attachments ||= Attachments.new(@_message)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Overriding method that prepares Mail object. This time we'll be
|
86
|
+
# contructing PostageApp::Request payload.
|
87
|
+
def mail(headers = {}, &block)
|
88
|
+
# Guard flag to prevent both the old and the new API from firing
|
89
|
+
# Should be removed when old API is removed
|
90
|
+
@mail_was_called = true
|
91
|
+
m = @_message
|
92
|
+
|
93
|
+
# At the beginning, do not consider class default for parts order neither content_type
|
94
|
+
content_type = headers[:content_type]
|
95
|
+
parts_order = headers[:parts_order]
|
96
|
+
|
97
|
+
# Call all the procs (if any)
|
98
|
+
default_values = self.class.default.merge(self.class.default) do |k,v|
|
99
|
+
v.respond_to?(:call) ? v.bind(self).call : v
|
100
|
+
end
|
101
|
+
|
102
|
+
# Handle defaults
|
103
|
+
headers = headers.reverse_merge(default_values)
|
104
|
+
headers[:subject] ||= default_i18n_subject
|
105
|
+
|
106
|
+
# Set configure delivery behavior
|
107
|
+
wrap_delivery_behavior!(headers.delete(:delivery_method))
|
108
|
+
|
109
|
+
# Assigning recipients
|
110
|
+
m.arguments['recipients'] = headers.delete(:to)
|
111
|
+
|
112
|
+
# Assign all headers except parts_order, content_type and body
|
113
|
+
assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
|
114
|
+
m.arguments['headers'] = assignable
|
115
|
+
|
116
|
+
# Render the templates and blocks
|
117
|
+
responses, explicit_order = collect_responses_and_parts_order(headers, &block)
|
118
|
+
create_parts_from_responses(m, responses)
|
119
|
+
|
120
|
+
m
|
121
|
+
end
|
122
|
+
|
123
|
+
# Overriding method to create mesage from the old_api
|
124
|
+
def create_mail
|
125
|
+
m = @_message
|
126
|
+
|
127
|
+
m.arguments['headers'] ||= { }
|
128
|
+
m.arguments['headers']['from'] = from
|
129
|
+
m.arguments['headers']['subject'] = subject
|
130
|
+
m.arguments['recipients'] = recipients
|
131
|
+
|
132
|
+
m
|
133
|
+
end
|
134
|
+
|
135
|
+
# Overriding part assignment from old_api
|
136
|
+
# For now only accepting a hash
|
137
|
+
def part(params)
|
138
|
+
@_message.arguments['content'] ||= { }
|
139
|
+
@_message.arguments['content'][params[:content_type]] = params[:body]
|
140
|
+
end
|
141
|
+
|
142
|
+
# Overriding attachment assignment from old_api
|
143
|
+
# For now only accepting a hash
|
144
|
+
def attachment(params)
|
145
|
+
@_message.arguments['attachments'] ||= { }
|
146
|
+
@_message.arguments['attachments'][params[:filename]] = {
|
147
|
+
'content_type' => params[:content_type],
|
148
|
+
'content' => Base64.encode64(params[:body].to_s)
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
# Overriding method in old_api
|
153
|
+
def create_inline_part(body, mime_type = nil)
|
154
|
+
@_message.arguments['content'] ||= { }
|
155
|
+
@_message.arguments['content'][mime_type && mime_type.to_s || 'text/plain'] = body
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
def create_parts_from_responses(m, responses) #:nodoc:
|
161
|
+
content = m.arguments['content'] ||= {}
|
162
|
+
responses.each do |part|
|
163
|
+
content[part[:content_type]] = part[:body]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
# A set of methods that are useful when request needs to behave as Mail
|
170
|
+
class PostageApp::Request
|
171
|
+
|
172
|
+
attr_accessor :delivery_handler,
|
173
|
+
:perform_deliveries,
|
174
|
+
:raise_delivery_errors
|
175
|
+
|
176
|
+
# Either doing an actual send, or passing it along to Mail::TestMailer
|
177
|
+
# Probably not the best way as we're skipping way too many intermediate methods
|
178
|
+
def deliver
|
179
|
+
if @delivery_method == Mail::TestMailer
|
180
|
+
mailer = @delivery_method.new(nil)
|
181
|
+
mailer.deliver!(self)
|
182
|
+
else
|
183
|
+
self.send
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Not 100% on this, but I need to assign this so I can properly handle deliver method
|
188
|
+
def delivery_method(method = nil, settings = {})
|
189
|
+
@delivery_method = method
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|