postageapp 1.2.5 → 1.4.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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +10 -30
  4. data/{LICENSE → LICENSE.md} +1 -1
  5. data/README.md +118 -68
  6. data/Rakefile +15 -4
  7. data/VERSION +1 -0
  8. data/app/ingresses/action_mailbox/ingresses/postage_app.rb +2 -0
  9. data/app/ingresses/action_mailbox/ingresses/postage_app/inbound_emails_controller.rb +50 -0
  10. data/config/routes.rb +6 -0
  11. data/doc/RAILS2.md +54 -0
  12. data/doc/RAILS3.md +15 -0
  13. data/exe/postageapp +37 -0
  14. data/generators/postageapp/templates/postageapp_tasks.rake +25 -8
  15. data/lib/generators/postageapp/postageapp_generator.rb +9 -6
  16. data/lib/postageapp.rb +59 -30
  17. data/lib/postageapp/cli.rb +14 -0
  18. data/lib/postageapp/cli/command.rb +110 -0
  19. data/lib/postageapp/cli/command/config.rb +74 -0
  20. data/lib/postageapp/cli/command/create_mailbox.rb +21 -0
  21. data/lib/postageapp/cli/command/env.rb +58 -0
  22. data/lib/postageapp/cli/command/get_project_info.rb +3 -0
  23. data/lib/postageapp/configuration.rb +267 -63
  24. data/lib/postageapp/diagnostics.rb +30 -0
  25. data/lib/postageapp/engine.rb +9 -0
  26. data/lib/postageapp/env.rb +9 -0
  27. data/lib/postageapp/failed_request.rb +2 -0
  28. data/lib/postageapp/http.rb +32 -0
  29. data/lib/postageapp/logger.rb +2 -0
  30. data/lib/postageapp/mail.rb +1 -1
  31. data/lib/postageapp/mailer.rb +2 -11
  32. data/lib/postageapp/mailer/mailer_4.rb +29 -15
  33. data/lib/postageapp/rails/railtie.rb +1 -3
  34. data/lib/postageapp/request.rb +27 -11
  35. data/lib/postageapp/response.rb +22 -8
  36. data/lib/postageapp/utils.rb +0 -11
  37. data/log/.gitignore +1 -0
  38. data/postageapp.gemspec +16 -17
  39. data/script/with +3 -3
  40. data/test/gemfiles/Gemfile.rails-2.3.x +1 -1
  41. data/test/gemfiles/Gemfile.rails-3.0.x +1 -1
  42. data/test/gemfiles/Gemfile.rails-3.1.x +1 -1
  43. data/test/gemfiles/Gemfile.rails-3.2.x +1 -1
  44. data/test/gemfiles/Gemfile.rails-4.0.x +1 -1
  45. data/test/gemfiles/Gemfile.rails-4.1.x +1 -1
  46. data/test/gemfiles/Gemfile.rails-4.2.x +1 -2
  47. data/test/gemfiles/Gemfile.rails-5.0.x +12 -0
  48. data/test/gemfiles/Gemfile.rails-5.2.x +12 -0
  49. data/test/gemfiles/Gemfile.rails-6.0.x +12 -0
  50. data/test/gemfiles/Gemfile.rails-6.1.x +12 -0
  51. data/test/gemfiles/Gemfile.ruby +2 -3
  52. data/test/helper.rb +6 -17
  53. data/test/log/.gitignore +1 -0
  54. data/test/mailer/action_mailer_3/notifier.rb +10 -10
  55. data/test/tmp/.gitignore +1 -0
  56. data/test/travis_test.rb +58 -40
  57. data/test/{configuration_test.rb → unit/configuration_test.rb} +35 -22
  58. data/test/{failed_request_test.rb → unit/failed_request_test.rb} +6 -6
  59. data/test/{live_test.rb → unit/live_test.rb} +33 -43
  60. data/test/{mail_delivery_method_test.rb → unit/mail_delivery_method_test.rb} +1 -1
  61. data/test/{mailer_4_test.rb → unit/mailer_4_test.rb} +2 -2
  62. data/test/{mailer_helper_methods_test.rb → unit/mailer_helper_methods_test.rb} +4 -4
  63. data/test/{postageapp_test.rb → unit/postageapp_test.rb} +10 -1
  64. data/test/{rails_initialization_test.rb → unit/rails_initialization_test.rb} +2 -2
  65. data/test/{request_test.rb → unit/request_test.rb} +24 -23
  66. data/test/{response_test.rb → unit/response_test.rb} +4 -4
  67. data/test/unit/tmp/.gitignore +1 -0
  68. data/tmp/.gitignore +1 -0
  69. metadata +60 -68
  70. data/lib/postageapp/mailer/mailer_2.rb +0 -140
  71. data/lib/postageapp/mailer/mailer_3.rb +0 -190
  72. data/lib/postageapp/version.rb +0 -3
  73. data/test/mailer/action_mailer_2/notifier.rb +0 -76
  74. data/test/mailer/action_mailer_2/notifier/with_body_and_attachment.erb +0 -1
  75. data/test/mailer/action_mailer_2/notifier/with_custom_postage_variables.text.html.erb +0 -1
  76. data/test/mailer/action_mailer_2/notifier/with_custom_postage_variables.text.plain.erb +0 -1
  77. data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.html.erb +0 -1
  78. data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.plain.erb +0 -1
  79. data/test/mailer/action_mailer_2/notifier/with_simple_view.erb +0 -1
  80. data/test/mailer/action_mailer_2/notifier/with_text_only_view.text.plain.erb +0 -1
  81. data/test/mailer_2_test.rb +0 -95
  82. data/test/mailer_3_test.rb +0 -118
@@ -0,0 +1,30 @@
1
+ require 'socket'
2
+
3
+ class PostageApp::Diagnostics
4
+ # == Instance Methods =====================================================
5
+
6
+ def initialize(config)
7
+ @config = config
8
+ end
9
+
10
+ def proxy_host_resolved
11
+ resolve(@config.proxy_host, 'socks5')
12
+ end
13
+
14
+ def host_resolved
15
+ resolve(@config.host, @config.protocol)
16
+ end
17
+
18
+ protected
19
+ def resolve(fqdn, service)
20
+ return unless (fqdn)
21
+
22
+ Socket.getaddrinfo(fqdn, service).map do |e|
23
+ # Result: [ family, port, name, ip, faily, socktype, protocol ]
24
+ e[3]
25
+ end.uniq
26
+
27
+ rescue SocketError
28
+ # Couldn't resolve, so nil
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ module PostageApp
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace PostageApp
4
+
5
+ initializer 'postageapp' do |app|
6
+ app.config.action_mailbox.ingress = :postage_app
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module PostageApp::Env
2
+ def self.rails?
3
+ defined?(Rails)
4
+ end
5
+
6
+ def self.rails_with_encrypted_credentials?
7
+ defined?(Rails) and Rails.respond_to?(:application) and Rails.application.respond_to?(:credentials)
8
+ end
9
+ end
@@ -1,4 +1,6 @@
1
1
  module PostageApp::FailedRequest
2
+ # == Module Methods =======================================================
3
+
2
4
  # Stores request object into a file for future re-send
3
5
  # returns true if stored, false if not (due to undefined project path)
4
6
  def self.store(request)
@@ -0,0 +1,32 @@
1
+ module PostageApp::HTTP
2
+ # == Moduule Methods ======================================================
3
+
4
+ def self.connect(config)
5
+ connector =
6
+ if (config.proxy?)
7
+ Net::HTTP::Proxy(
8
+ config.proxy_host,
9
+ config.proxy_port || SOCKS5_PORT_DEFAULT,
10
+ config.proxy_user,
11
+ config.proxy_pass
12
+ )
13
+ else
14
+ Net::HTTP
15
+ end
16
+
17
+ http = connector.new(config.host, config.port)
18
+
19
+ unless (config.verify_certificate?)
20
+ context = OpenSSL::SSL::SSLContext.new
21
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
22
+
23
+ http.send(:instance_variable_set, :@ssl_context, context)
24
+ end
25
+
26
+ http.read_timeout = config.http_read_timeout
27
+ http.open_timeout = config.http_open_timeout
28
+ http.use_ssl = config.secure?
29
+
30
+ http
31
+ end
32
+ end
@@ -1,4 +1,6 @@
1
1
  class PostageApp::Logger < ::Logger
2
+ # == Instance Methods =====================================================
3
+
2
4
  def format_message(severity, datetime, progname, msg)
3
5
  "[%s] %s\n" % [
4
6
  datetime.strftime('%m/%d/%Y %H:%M:%S %Z'),
@@ -1,3 +1,3 @@
1
- class PostageApp::Mail
1
+ module PostageApp::Mail
2
2
  require 'postageapp/mail/arguments'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  begin
2
+ require 'active_support'
2
3
  require 'action_mailer'
3
4
  require 'action_mailer/version'
4
5
 
@@ -7,15 +8,5 @@ rescue LoadError
7
8
  end
8
9
 
9
10
  if (defined?(ActionMailer))
10
- # Loading PostageApp::Mailer class depending on what action_mailer is
11
- # currently installed on the system. Assuming we're dealing only with
12
- # ones that come with Rails 2 and 3
13
- case (ActionMailer::VERSION::MAJOR)
14
- when 3
15
- require File.expand_path('mailer/mailer_3', File.dirname(__FILE__))
16
- when 2
17
- require File.expand_path('mailer/mailer_2', File.dirname(__FILE__))
18
- else
19
- require File.expand_path('mailer/mailer_4', File.dirname(__FILE__))
20
- end
11
+ require_relative './mailer/mailer_4'
21
12
  end
@@ -24,7 +24,7 @@
24
24
  # Sending email
25
25
  #
26
26
  # # Create a PostageApp::Request object
27
- # request = Notifier.signup_notification(user)
27
+ # request = Notifier.signup_notification(user)
28
28
  # # Deliver the message and return a PostageApp::Response
29
29
  # response = request.deliver_now
30
30
 
@@ -156,7 +156,7 @@ class PostageApp::Mailer < ActionMailer::Base
156
156
  :template_name,
157
157
  :template_path
158
158
  )
159
-
159
+
160
160
  m.headers.merge!(assignable)
161
161
 
162
162
  # Render the templates and blocks
@@ -166,15 +166,29 @@ class PostageApp::Mailer < ActionMailer::Base
166
166
  m
167
167
  end
168
168
 
169
- protected
170
- def each_template(paths, name, &block) #:nodoc:
171
- templates = lookup_context.find_all(name, paths)
169
+ def find_first_mime_type(mt)
170
+ part = arguments['content'].detect{ |mime_type, body| mime_type == mt }
172
171
 
173
- if (templates.present?)
174
- templates.uniq { |t| t.formats }.each(&block)
175
- end
172
+ OpenStruct.new(mime_type: part[0], decoded: part[1]) if part
173
+ end
174
+
175
+ def header
176
+ @_message.arguments['headers']
177
+ end
178
+
179
+ def reply_to
180
+ @_message.arguments.dig('headers', 'reply_to')
181
+ end
182
+
183
+ def cc
184
+ @_message.arguments.dig('headers', 'cc')
185
+ end
186
+
187
+ def multipart?
188
+ %w[ text/plain text/html ].all? { |mt| arguments['content'].key?(mt) }
176
189
  end
177
190
 
191
+ protected
178
192
  def create_parts_from_responses(m, responses) #:nodoc:
179
193
  content = m.arguments['content'] ||= { }
180
194
 
@@ -200,17 +214,17 @@ class PostageApp::Request
200
214
  def deliver_now
201
215
  inform_interceptors
202
216
 
203
- if (perform_deliveries)
204
- if (@delivery_method == Mail::TestMailer)
205
- @delivery_method.deliveries << self
206
- else
207
- self.send
208
- end
217
+ return unless (perform_deliveries)
218
+
219
+ if (@delivery_method == Mail::TestMailer)
220
+ @delivery_method.deliveries << self
221
+ else
222
+ self.send
209
223
  end
210
224
  end
211
225
  alias_method :deliver, :deliver_now
212
226
 
213
- # Not 100% on this, but I need to assign this so I can properly handle deliver method
227
+ # Allows overriding the delivery method setting
214
228
  def delivery_method(method = nil, settings = nil)
215
229
  @delivery_method = method
216
230
  end
@@ -1,7 +1,5 @@
1
- require 'postageapp'
2
-
3
1
  if (defined?(ActionMailer))
4
- require 'postageapp/mailer'
2
+ require_relative '../mailer'
5
3
 
6
4
  # Register as a delivery method with ActionMailer
7
5
  ActionMailer::Base.add_delivery_method(
@@ -1,10 +1,16 @@
1
1
  class PostageApp::Request
2
- API_VERSION = '1.0'
2
+ # == Constants ============================================================
3
+
4
+ API_VERSION = '1.1'
3
5
 
4
6
  HEADERS_DEFAULT = {
5
7
  'Content-type' => 'application/json',
6
8
  'Accept' => 'text/json, application/json'
7
9
  }
10
+
11
+ TimeoutError = defined?(::Timeout) ? ::Timeout::Error : ::TimeoutError
12
+
13
+ # == Properties ===========================================================
8
14
 
9
15
  # Unique ID (UID) for the request
10
16
  attr_writer :uid
@@ -19,6 +25,8 @@ class PostageApp::Request
19
25
  # Assigns the API key to be used for the request
20
26
  attr_accessor :api_key
21
27
 
28
+ # == Class Methods ========================================================
29
+
22
30
  # Returns a user-agent string used for identification when making API calls.
23
31
  def self.user_agent
24
32
  @user_agent ||=
@@ -28,6 +36,8 @@ class PostageApp::Request
28
36
  PostageApp.configuration.framework
29
37
  ]
30
38
  end
39
+
40
+ # == Instance Methods =====================================================
31
41
 
32
42
  # Creates a new Request with the given API call method and arguments.
33
43
  def initialize(method, arguments = nil)
@@ -44,19 +54,25 @@ class PostageApp::Request
44
54
  http = PostageApp.configuration.http
45
55
 
46
56
  PostageApp.logger.info(self)
57
+
58
+ if (ENV['DEBUG'])
59
+ puts "// #{url}"
60
+ puts JSON.pretty_generate(self.arguments_to_send)
61
+ end
47
62
 
48
- http_response = begin
49
- http.post(
50
- url.path,
51
- self.arguments_to_send.to_json,
52
- HEADERS_DEFAULT.merge(
53
- 'User-Agent' => self.class.user_agent
63
+ http_response =
64
+ begin
65
+ http.post(
66
+ url.path,
67
+ self.arguments_to_send.to_json,
68
+ HEADERS_DEFAULT.merge(
69
+ 'User-Agent' => self.class.user_agent
70
+ )
54
71
  )
55
- )
56
72
 
57
- rescue TimeoutError, Errno::ECONNREFUSED
58
- nil
59
- end
73
+ rescue TimeoutError, Errno::ECONNREFUSED => e
74
+ e
75
+ end
60
76
 
61
77
  response = PostageApp::Response.new(http_response)
62
78
 
@@ -1,4 +1,11 @@
1
1
  class PostageApp::Response
2
+ # == Constants ============================================================
3
+
4
+ STATUS_TIMEOUT = 'timeout'.freeze
5
+ STATUS_FAIL = 'fail'.freeze
6
+
7
+ # == Properties ===========================================================
8
+
2
9
  # The UID should match the Request's UID. If Request didn't provide with one
3
10
  # PostageApp service should generate it for the Response
4
11
  attr_reader :uid
@@ -15,22 +22,29 @@ class PostageApp::Response
15
22
  attr_reader :data
16
23
 
17
24
  attr_reader :exception
25
+
26
+ # == Instance Methods =====================================================
18
27
 
19
28
  # Takes in Net::HTTPResponse object as the attribute.
20
29
  # If something goes wrong Response will be thought of as failed
21
30
  def initialize(http_response)
22
- hash = JSON::parse(http_response.body)
23
-
24
- _response = hash['response']
31
+ case (http_response)
32
+ when Exception
33
+ @status = STATUS_TIMEOUT
34
+ @message = '[%s] %s' % [ http_response.class, http_response.to_s ]
35
+ else
36
+ hash = JSON::parse(http_response.body)
37
+ _response = hash['response']
25
38
 
26
- @status = _response['status']
27
- @uid = _response['uid']
28
- @message = _response['message']
39
+ @status = _response['status']
40
+ @uid = _response['uid']
41
+ @message = _response['message']
29
42
 
30
- @data = hash['data']
43
+ @data = hash['data']
44
+ end
31
45
 
32
46
  rescue => e
33
- @status = 'fail'
47
+ @status = STATUS_FAIL
34
48
  @exception = '[%s] %s' % [ e.class, e ]
35
49
  end
36
50
 
@@ -31,14 +31,3 @@ class Hash
31
31
  end
32
32
  end
33
33
  end
34
-
35
- class Net::HTTP
36
- # Getting rid of the 'warning: peer certificate won't be verified in this SSL session'
37
- alias_method :__initialize, :initialize
38
- def initialize(*args)
39
- __initialize(*args)
40
-
41
- @ssl_context = OpenSSL::SSL::SSLContext.new
42
- @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
43
- end
44
- end
data/log/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *
data/postageapp.gemspec CHANGED
@@ -1,33 +1,32 @@
1
1
  # encoding: utf-8
2
2
 
3
- $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
4
- require 'postageapp/version'
3
+ $LOAD_PATH.unshift(File.expand_path('./lib', __dir__))
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = "postageapp"
8
- s.version = PostageApp::VERSION
6
+ s.name = 'postageapp'
7
+ s.version = File.read(File.expand_path('VERSION', __dir__)).gsub(/\s/, '')
9
8
  s.authors = [
10
- "Oleg Khabarov",
11
- "Scott Tadman",
12
- "The Working Group Inc."
9
+ 'Scott Tadman',
10
+ 'Oleg Khabarov',
11
+ 'PostageApp Ltd.'
13
12
  ]
14
13
  s.email = [
15
- "oleg@khabarov.ca",
16
- "tadman@postageapp.com"
14
+ 'tadman@postageapp.com',
15
+ 'oleg@khabarov.ca',
16
+ 'info@postageapp.com'
17
17
  ]
18
18
 
19
- s.homepage = "http://github.com/postageapp/postageapp-ruby"
19
+ s.homepage = 'http://github.com/postageapp/postageapp-ruby'
20
20
 
21
- s.summary = "Gem for communicating with the PostageApp email API"
22
- s.description = "Gem that interfaces with PostageApp service to send emails from Ruby applications"
21
+ s.summary = 'Client library for PostageApp Email API'
22
+ s.description = 'PostageApp Library for Ruby and Ruby on Rails applications'
23
23
  s.license = 'MIT'
24
-
24
+
25
25
  s.files = `git ls-files`.split("\n")
26
26
  s.platform = Gem::Platform::RUBY
27
27
  s.require_paths = [ 'lib' ]
28
28
 
29
- s.required_ruby_version = '>= 1.9.3'
30
-
31
- s.add_dependency 'json'
32
- s.add_dependency 'mail'
29
+ s.required_ruby_version = '>= 2.5.0'
30
+
31
+ s.add_dependency 'mail', '~> 2.4'
33
32
  end
data/script/with CHANGED
@@ -20,8 +20,8 @@
20
20
 
21
21
  # == Constants ==============================================================
22
22
 
23
- GEMFILE_DIR = File.expand_path('../test/gemfiles', File.dirname(__FILE__))
24
- GEMFILE_ROOT = File.expand_path('../Gemfile', File.dirname(__FILE__))
23
+ GEMFILE_DIR = File.expand_path('../test/gemfiles', __dir__)
24
+ GEMFILE_ROOT = File.expand_path('../Gemfile', __dir__)
25
25
 
26
26
  # == Support Methods ========================================================
27
27
 
@@ -74,7 +74,7 @@ def shell(*args)
74
74
  end
75
75
 
76
76
  unless (system(*args))
77
- exit($?)
77
+ exit($?.to_i)
78
78
  end
79
79
  end
80
80
 
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # rubygems 1.8.30
4
4
 
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # rubygems 1.8.30
4
4