snails 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/snails/mailer.rb +100 -27
  3. data/snails.gemspec +1 -1
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9ee5f0ad2cdda5a366dfc31d197b29948e63b7d24be394e8a6b779ea0f11bc2
4
- data.tar.gz: 6f838a808f32036b57ab67ae24e26e2cae9442af0b086aa7d524d78d94ae5df2
3
+ metadata.gz: 483517cd1b55bc5273ebb004bb9ef69a8cd6191de4be897c3d9f2c168ea13f4f
4
+ data.tar.gz: 1730ce09810faafc5802833ab4f38fb103e8dae059b9cfb51b85335893fb7f09
5
5
  SHA512:
6
- metadata.gz: f4b100c320293b3f66944182bde37c32567795838358c09bad18cf94ec34ce91932d5e923245faa29ffb63350d2876b60c97c1e378aa6b75e459353f057c2f5e
7
- data.tar.gz: 4a120754c9dad45639f27e1b23ed44c84054440937ac1bfaccce508263090b84feb1175388867b12ded067b4ac936615e39d3490bdc0fe69b8e9447e7f7bb737
6
+ metadata.gz: e104410a7d4f8eea1370a583d13e4f23cefd043bc78f12027b5fea7063a87285c2cbeb89a1ab8c9a43e7a90d582b3b397528f1c483df2db60cf7dc654f66aba7
7
+ data.tar.gz: dfe0ae0b0116f29c71907e35a38548d3d28af693e7dbf824b29f6e467ddab841d588c6f573b238c3e50d420bae649f81fca9efb73cb3709ac158eb121dae45e3
@@ -12,32 +12,28 @@ module Snails
12
12
 
13
13
  @queue = :emails
14
14
 
15
- def initialize(opts)
16
- mail_config = (opts[:smtp] || opts[:mail]) or raise ":smtp options missing"
17
-
18
- if key = mail_config.dig(:dkim, :private_key) and File.exist?(key)
19
- mail_config[:dkim][:private_key] = IO.read(key)
20
- elsif mail_config[:dkim]
21
- puts "Private key for DKIM not found! Disabling..."
22
- mail_config.delete(:dkim)
23
- end
15
+ # class Bounce < StandardError; end
16
+ # class SoftBounce < Bounce; end
17
+ # class HardBounce < Bounce; end
24
18
 
25
- Tuktuk.options = mail_config
26
- @debug = mail_config[:debug]
19
+ def initialize(opts)
27
20
  @from_email = opts[:from] or raise ":from required"
28
21
  @base_subject = opts[:base_subject] || ''
29
22
  @views = opts[:views] || Snails.root.join('lib', 'views')
30
23
  @logfile = opts[:logfile] # || Snails.root.join('log', 'mailer.log')
24
+
25
+ backend_name = opts[:backend_name] || 'TestBackend'
26
+ @backend = self.class.backends[backend_name].new(opts[:backend_options])
31
27
  end
32
28
 
33
29
  def email(name, &block)
34
30
  define_singleton_method(name) do |*args|
35
- instance_exec(*args, &block)
31
+ instance_exec(*args, &block)
36
32
  end
37
33
  end
38
34
 
39
35
  def helpers(&block)
40
- instance_eval(&block)
36
+ instance_eval(&block)
41
37
  end
42
38
 
43
39
  def perform(method, *args)
@@ -81,50 +77,127 @@ A <%= @exception.class %> occurred in <%= @url %>:
81
77
 
82
78
  private
83
79
 
84
- def render(view)
85
- template = File.read(File.join(@views, "#{view}.erb"))
80
+ def render(view_path, layout_lath = nil)
81
+ view = File.read(File.join(@views, "#{view_path}.erb"))
82
+ if layout_path
83
+ layout = File.read(File.join(@views, "#{layout_path}.erb"))
84
+ render_erb(layout) { render_erb(view) }
85
+ else
86
+ render_erb(view)
87
+ end
88
+ end
89
+
90
+ def render_erb(template)
86
91
  ERB.new(template).result(binding)
87
92
  end
88
93
 
89
94
  def partial(name)
90
95
  partial_name = name.to_s["/"] ? name.to_s.reverse.sub("/", "_/").reverse : "_#{name}"
91
- render partial_name
96
+ render(partial_name)
92
97
  end
93
98
 
94
99
  def logger
95
100
  @logger ||= @logfile ? Logger.new(@logfile) : Snails.logger
96
101
  end
97
102
 
98
- def send_email(from: nil, to:, subject:, body: nil, template: nil, html_body: nil, html_template: nil, message_id: nil, return_path: nil, list_unsubscribe: nil)
103
+ def send_email(from: @from_email, to:, subject:, body: nil, template: nil, layout: nil, html_body: nil, html_template: nil, html_layout: nil, message_id: nil, return_path: nil, list_unsubscribe: nil)
99
104
  raise "No recipient given for mail: #{subject}!" if to.blank?
100
105
 
101
106
  message = {
102
107
  to: to,
103
- from: from || @from_email,
104
- subject: @base_subject + subject
108
+ from: from,
109
+ subject: @base_subject + subject
105
110
  }
106
111
 
112
+ raise "Blank from" if message[:from].blank?
113
+ raise "Blank to" if message[:to].blank?
114
+
107
115
  if body or template
108
- message[:body] = template ? render(template) : body
116
+ message[:body] = template ? render(template, layout) : body
109
117
  end
110
118
 
111
119
  if html_body or html_template
112
- message[:html_body] = html_template ? render(html_template) : html_body
120
+ message[:html_body] = html_template ? render(html_template, html_layout) : html_body
113
121
  end
114
122
 
115
123
  message[:message_id] = message_id if message_id
116
124
  message[:return_path] = return_path if return_path
117
125
  message[:list_unsubscribe] = list_unsubscribe if list_unsubscribe
118
126
 
119
- logger.info "[#{to}] Delivering: #{subject}"
120
- debug = @debug.nil? ? !Snails.env.production? : @debug # if debug isn't set, determine based on env
121
- resp, email = Tuktuk.deliver(message, debug: debug)
127
+ logger.info "[#{to}] Delivering: #{subject}"
128
+ @backend.deliver(message)
129
+ end
130
+
131
+ alias_method :deliver, :send_email
132
+
133
+ class Backend
134
+ def deliver(email, options = {})
135
+ raise "Please redefine in subclass"
136
+ end
137
+
138
+ def deliver_many(emails, options = {})
139
+ emails.map { |e| deliver(e, options) }
140
+ end
141
+ end
142
+
143
+ class Tuktuk < Backend
144
+ def initialize(config = {})
145
+ @debug = config[:debug]
146
+
147
+ if key = config.dig(:dkim, :private_key) and File.exist?(key)
148
+ config[:dkim][:private_key] = IO.read(key)
149
+ elsif config[:dkim]
150
+ puts "Private key for DKIM not found! Disabling..."
151
+ config.delete(:dkim)
152
+ end
153
+
154
+ Tuktuk.options = config
155
+ end
156
+
157
+ def deliver(email, options = {})
158
+ debug = @debug.nil? ? !Snails.env.production? : @debug # if debug isn't set, determine based on env
159
+ resp, email = Tuktuk.deliver(email, debug: debug)
160
+
161
+ if resp.is_a?(Tuktuk::Bounce)
162
+ logger.info "[#{to}] Email bounced! [#{resp.code}] #{resp.message}"
163
+ end
164
+
165
+ return resp, email
166
+ end
167
+
168
+ def deliver_many(emails, options = {})
169
+ Tuktuk.deliver_many(emails, options)
170
+ end
171
+ end
172
+
173
+ class Mailgun < Backend
174
+
175
+ def initialize(api_key:, domain_name:)
176
+ @key = api_key
177
+ @url = "https://api.mailgun.net/v3/#{domain_name}/messages"
178
+ end
179
+
180
+ def deliver(email, options = {})
181
+ raise "No body!" if email[:body].nil?
182
+
183
+ data = {
184
+ from: email[:from],
185
+ to: email[:to],
186
+ subject: email[:subject],
187
+ }
188
+
189
+ data[:text] = email[:body] if email[:body]
190
+ data[:html] = email[:html_body] if email[:html_body]
191
+
192
+ if data[:text].blank? && data[:html].blank?
193
+ raise ArgumentError, "Either text or html required"
194
+ end
122
195
 
123
- if resp.is_a?(Tuktuk::Bounce)
124
- logger.info "[#{to}] Email bounced! [#{resp.code}] #{resp.message}"
196
+ opts = { username: 'api', password: @key }
197
+ resp = Dagger.post(@url, data, opts)
198
+ resp.ok? ? [resp.data, data[:to]] : nil
125
199
  end
126
200
 
127
- return resp, email
128
201
  end
129
202
 
130
203
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "snails"
6
- s.version = '0.4.2'
6
+ s.version = '0.4.3'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ['Tomás Pollak']
9
9
  s.email = ['tomas@forkhq.com']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Pollak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-05 00:00:00.000000000 Z
11
+ date: 2020-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler