postageapp 1.2.5 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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