malone-acd 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d8304a6c962c3ce511c5c6013fc12e79f089fecf
4
+ data.tar.gz: dc8d668a2610da9dc24617f906431e6b83191e75
5
+ SHA512:
6
+ metadata.gz: 2c10db3e69a24e740e71ff7025c573d0f2d17f24e82eca81420fec1ddf0af2d9d2ffe781c4b0c5cbc8193ed796a2810f3e8135fc8efb4abe02c4616be78d061b
7
+ data.tar.gz: cbfe96fe372643cc263d0e11af4e64febdf936077ac889760edd5195ab01d0620acbc9d31ffee11ddcc6a214b904120a8548e266d8832199cd36aae1a834ae7a
data/CHANGELOG ADDED
@@ -0,0 +1,21 @@
1
+ 1.0.0
2
+
3
+ - Malone.configure has been replaced with Malone.connect
4
+ Use Malone.current to retrieve the last configured Malone
5
+ instance (using Malone.connect)
6
+
7
+ - Malone.deliver has been replaced with an instance method.
8
+ Call deliver (with the same arguments as before) on the
9
+ return value of Malone.connect or Malone.current.
10
+
11
+ - Malone#deliver now receives :text and :html instead of :body.
12
+
13
+ - No need to pass in TLS. it's tries to do TLS automatically.
14
+
15
+ - Errors during SMTP authentication (and any other error) aren't
16
+ trapped silently now. (via @tizoc, @elpollila)
17
+
18
+ - Configuration parameters are more strict (i.e. passing :password
19
+ would throw a NoMethodError via @tizoc, @elpollila)
20
+
21
+ - malone/sandbox has been renamed to malone/test.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Cyril David
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ malone(1) -- send mail using smtp without any fuss
2
+ ==================================================
3
+
4
+ ## USAGE
5
+
6
+ require "malone"
7
+
8
+ # Typically you would do this somewhere in the bootstrapping
9
+ # part of your application
10
+
11
+ m = Malone.connect(url: "smtp://foo%40bar.com:pass@smtp.gmail.com:587",
12
+ domain: "mysite.com")
13
+
14
+ m.deliver(from: "me@me.com", to: "you@me.com",
15
+ subject: "Test subject", text: "Great!")
16
+
17
+ # Malone.current will now remember the last configuration you setup.
18
+ Malone.current.config == m.config
19
+
20
+ # Now you can also do Malone.deliver, which is syntactic sugar
21
+ # for Malone.current.deliver
22
+ Malone.deliver(from: "me@me.com", to: "you@me.com",
23
+ subject: "Test subject", text: "Great!")
24
+
25
+ # Also starting with Malone 1.0, you can pass in :html
26
+ # for multipart emails.
27
+
28
+ Malone.deliver(from: "me@me.com", to: "you@me.com",
29
+ subject: "Test subject",
30
+ text: "Great!", html: "<b>Great!</b>")
31
+
32
+
33
+ ## TESTING
34
+
35
+ require "malone/test"
36
+
37
+ m = Malone.connect(url: "smtp://foo%40bar.com:pass@smtp.gmail.com:587",
38
+ domain: "mysite.com")
39
+
40
+ m.deliver(from: "me@me.com", to: "you@me.com",
41
+ subject: "Test subject", text: "Great!")
42
+
43
+ Malone.deliveries.size == 1
44
+ # => true
45
+
46
+ mail = Malone.deliveries.first
47
+
48
+ "me@me.com" == mail.from
49
+ # => true
50
+
51
+ "you@me.com" == mail.to
52
+ # => true
53
+
54
+ "FooBar" == mail.text
55
+ # => true
56
+
57
+ "Hello World" == envelope.subject
58
+ # => true
59
+
60
+ ## INSTALLATION
61
+
62
+ gem install malone
63
+
64
+ ## CONFIGURATION TIPS
65
+
66
+ If you're used to doing configuration via environment
67
+ variables, similar to how Heroku does configuration, then
68
+ you can simply set an environment variable in your
69
+ production machine like so:
70
+
71
+ export MALONE_URL=smtp://foo%40bar.com:pass@smtp.gmail.com:587
72
+
73
+ Then you can connect using the environment variable in your
74
+ code like so:
75
+
76
+ Malone.connect(url: ENV["MALONE_URL"])
77
+
78
+ # or quite simply
79
+ Malone.connect
80
+
81
+ By default Malone tries for the environment variable `MALONE_URL` when
82
+ you call `Malone.connect` without any arguments.
@@ -0,0 +1,13 @@
1
+ require "ostruct"
2
+
3
+ class Malone
4
+ def self.deliveries
5
+ @deliveries ||= []
6
+ end
7
+
8
+ def deliver(*args)
9
+ self.class.deliveries << OpenStruct.new(*args)
10
+ end
11
+ end
12
+
13
+
data/lib/malone.rb ADDED
@@ -0,0 +1,127 @@
1
+ require "cgi"
2
+ require "mailfactory"
3
+ require "net/smtp"
4
+ require "uri"
5
+
6
+ class Malone
7
+ attr :config
8
+
9
+ def self.connect(options = {})
10
+ @config = Configuration.new(options)
11
+
12
+ current
13
+ end
14
+
15
+ def self.current
16
+ unless defined?(@config)
17
+ raise RuntimeError, "Missing configuration: Try doing `Malone.connect`."
18
+ end
19
+
20
+ return new(@config)
21
+ end
22
+
23
+ def self.deliver(dict)
24
+ current.deliver(dict)
25
+ end
26
+
27
+ def initialize(config)
28
+ @config = config
29
+ end
30
+
31
+ def deliver(dict)
32
+ mail = envelope(dict)
33
+
34
+ smtp = Net::SMTP.new(config.host, config.port)
35
+ smtp.enable_starttls_auto if config.tls
36
+
37
+ begin
38
+ smtp.start(config.domain, config.user, config.password, config.auth)
39
+ smtp.send_message(mail.to_s, mail.from.first, *recipients(mail))
40
+ ensure
41
+ smtp.finish if smtp.started?
42
+ end
43
+ end
44
+
45
+ def recipients(mail)
46
+ [].tap do |ret|
47
+ ret.push(*mail.to)
48
+ ret.push(*mail.cc)
49
+ ret.push(*mail.bcc)
50
+ end
51
+ end
52
+
53
+ def envelope(dict)
54
+ envelope = Envelope.new
55
+ envelope.from = dict[:from]
56
+ envelope.to = dict[:to]
57
+ envelope.replyto = dict[:replyto]
58
+ envelope.cc = dict[:cc] if dict[:cc]
59
+ envelope.bcc = dict[:bcc] if dict[:bcc]
60
+ envelope.text = dict[:text]
61
+ envelope.rawhtml = dict[:html] if dict[:html]
62
+ envelope.subject = dict[:subject]
63
+
64
+ envelope.attach(dict[:attach]) if dict[:attach]
65
+
66
+ envelope.add_attachment_as(*dict[:attach_as]) if dict[:attach_as]
67
+
68
+ return envelope
69
+ end
70
+
71
+ class Configuration
72
+ attr_accessor :host
73
+ attr_accessor :port
74
+ attr_accessor :user
75
+ attr_accessor :password
76
+ attr_accessor :domain
77
+ attr_accessor :auth
78
+ attr_accessor :tls
79
+
80
+ def initialize(options)
81
+ opts = options.dup
82
+
83
+ @tls = true
84
+
85
+ url = opts.delete(:url) || ENV["MALONE_URL"]
86
+
87
+ if url
88
+ uri = URI(url)
89
+
90
+ opts[:host] ||= uri.host
91
+ opts[:port] ||= uri.port.to_i
92
+ opts[:user] ||= unescaped(uri.user)
93
+ opts[:password] ||= unescaped(uri.password)
94
+ end
95
+
96
+ opts.each do |key, val|
97
+ send(:"#{key}=", val)
98
+ end
99
+ end
100
+
101
+ def auth=(val)
102
+ @auth = val
103
+ @auth = @auth.to_sym if @auth
104
+ end
105
+
106
+ private
107
+ def unescaped(val)
108
+ return if val.to_s.empty?
109
+
110
+ CGI.unescape(val)
111
+ end
112
+ end
113
+
114
+ class Envelope < MailFactory
115
+ attr :bcc
116
+
117
+ def initialize
118
+ super
119
+
120
+ @bcc = []
121
+ end
122
+
123
+ def bcc=(bcc)
124
+ @bcc.push(bcc)
125
+ end
126
+ end
127
+ end
data/malone.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'malone-acd'
3
+ s.version = "1.0.7"
4
+ s.summary = %{Dead-simple Ruby mailing solution which always delivers.}
5
+ s.date = "2011-01-10"
6
+ s.author = "Cyril David"
7
+ s.email = "me@cyrildavid.com"
8
+ s.homepage = "http://github.com/cyx/malone"
9
+
10
+ s.files = Dir[
11
+ "CHANGELOG",
12
+ "LICENSE",
13
+ "README.md",
14
+ "lib/**/*.rb",
15
+ "test/*.*",
16
+ "*.gemspec"
17
+ ]
18
+
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "mailfactory-acd"
22
+ s.add_development_dependency "cutest-cj"
23
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
2
+
3
+ require "cutest"
4
+ require "malone"
data/test/malone.rb ADDED
@@ -0,0 +1,223 @@
1
+ require_relative "helper"
2
+
3
+ test "basic configuration" do
4
+ m = Malone.connect(host: "smtp.gmail.com", port: 587,
5
+ user: "foo@bar.com", password: "pass1234",
6
+ domain: "foo.com", auth: "login")
7
+
8
+ c = m.config
9
+
10
+ assert_equal "smtp.gmail.com", c.host
11
+ assert_equal 587, c.port
12
+ assert_equal "foo@bar.com", c.user
13
+ assert_equal "pass1234", c.password
14
+ assert_equal "foo.com", c.domain
15
+ assert_equal :login, c.auth
16
+ end
17
+
18
+ test "configuration via url" do
19
+ m = Malone.connect(url: "smtp://foo%40bar.com:pass1234@smtp.gmail.com:587")
20
+
21
+ c = m.config
22
+
23
+ assert_equal "smtp.gmail.com", c.host
24
+ assert_equal 587, c.port
25
+ assert_equal "foo@bar.com", c.user
26
+ assert_equal "pass1234", c.password
27
+ end
28
+
29
+ test "configuration via url and params" do
30
+ m = Malone.connect(url: "smtp://foo%40bar.com:pass1234@smtp.gmail.com:587",
31
+ domain: "foo.com", auth: "login", password: "barbaz123")
32
+
33
+ c = m.config
34
+
35
+ assert_equal "smtp.gmail.com", c.host
36
+ assert_equal 587, c.port
37
+ assert_equal "foo@bar.com", c.user
38
+ assert_equal "foo.com", c.domain
39
+ assert_equal :login, c.auth
40
+ assert_equal true, c.tls
41
+
42
+ # We verify that parameters passed takes precedence over the URL.
43
+ assert_equal "barbaz123", c.password
44
+ end
45
+
46
+ test "configuration via MALONE_URL" do
47
+ ENV["MALONE_URL"] = "smtp://foo%40bar.com:pass1234@smtp.gmail.com:587"
48
+
49
+ m = Malone.connect(domain: "foo.com", auth: "login", tls: false)
50
+ c = m.config
51
+
52
+ assert_equal "smtp.gmail.com", c.host
53
+ assert_equal 587, c.port
54
+ assert_equal "foo@bar.com", c.user
55
+ assert_equal "foo.com", c.domain
56
+ assert_equal :login, c.auth
57
+ assert_equal false, c.tls
58
+ end
59
+
60
+ test "typos in configuration" do
61
+ assert_raise NoMethodError do
62
+ Malone.connect(pass: "pass")
63
+ end
64
+ end
65
+
66
+ test "Malone.connect doesn't mutate the options" do
67
+ ex = nil
68
+ begin
69
+ Malone.connect({}.freeze)
70
+ rescue RuntimeError => ex
71
+ end
72
+
73
+ assert_equal nil, ex
74
+ end
75
+
76
+ test "Malone.current" do
77
+ Malone.connect(url: "smtp://foo%40bar.com:pass1234@smtp.gmail.com:587")
78
+
79
+ c = Malone.current.config
80
+
81
+ assert_equal "smtp.gmail.com", c.host
82
+ assert_equal 587, c.port
83
+ assert_equal "foo@bar.com", c.user
84
+ assert_equal "pass1234", c.password
85
+ end
86
+
87
+ test "#envelope" do
88
+ m = Malone.connect
89
+
90
+ mail = m.envelope(to: "recipient@me.com", from: "no-reply@mydomain.com",
91
+ subject: "SUB", text: "TEXT", html: "<h1>TEXT</h1>",
92
+ cc: "cc@me.com", bcc: "bcc@me.com",
93
+ replyto: "other@me.com")
94
+
95
+ assert_equal ["recipient@me.com"], mail.to
96
+ assert_equal ["cc@me.com"], mail.cc
97
+ assert_equal ["bcc@me.com"], mail.bcc
98
+ assert_equal ["no-reply@mydomain.com"], mail.from
99
+ assert_equal ["=?utf-8?Q?SUB?="], mail.subject
100
+ assert_equal "other@me.com", mail.replyto
101
+
102
+ assert_equal "TEXT", mail.instance_variable_get(:@text)
103
+ assert_equal "<h1>TEXT</h1>", mail.instance_variable_get(:@html)
104
+ end
105
+
106
+ scope do
107
+ class FakeSMTP < Struct.new(:host, :port)
108
+ def enable_starttls_auto
109
+ @enable_starttls_auto = true
110
+ end
111
+
112
+ def start(domain, user, password, auth)
113
+ @domain, @user, @password, @auth = domain, user, password, auth
114
+
115
+ @started = true
116
+ end
117
+
118
+ def started?
119
+ defined?(@started)
120
+ end
121
+
122
+ def finish
123
+ @finish = true
124
+ end
125
+
126
+ def send_message(blob, from, *recipients)
127
+ @blob, @from, @recipients = blob, from, recipients
128
+ end
129
+
130
+ def [](key)
131
+ instance_variable_get(:"@#{key}")
132
+ end
133
+ end
134
+
135
+ module Net
136
+ def SMTP.new(host, port)
137
+ $smtp = FakeSMTP.new(host, port)
138
+ end
139
+ end
140
+
141
+ setup do
142
+ Malone.connect(url: "smtp://foo%40bar.com:pass1234@smtp.gmail.com:587",
143
+ domain: "mydomain.com", auth: :login)
144
+ end
145
+
146
+ test "delivering successfully" do |m|
147
+ m.deliver(to: "recipient@me.com", from: "no-reply@mydomain.com",
148
+ subject: "SUB", text: "TEXT", cc: "cc@me.com", bcc: "bcc@me.com")
149
+
150
+ assert_equal "smtp.gmail.com", $smtp.host
151
+ assert_equal 587, $smtp.port
152
+
153
+ assert $smtp[:enable_starttls_auto]
154
+ assert_equal "mydomain.com", $smtp[:domain]
155
+ assert_equal "foo@bar.com", $smtp[:user]
156
+ assert_equal "pass1234", $smtp[:password]
157
+ assert_equal :login, $smtp[:auth]
158
+
159
+
160
+ assert_equal ["recipient@me.com", "cc@me.com", "bcc@me.com"], $smtp[:recipients]
161
+ assert_equal "no-reply@mydomain.com", $smtp[:from]
162
+
163
+ assert ! $smtp[:blob].include?("bcc@me.com")
164
+
165
+ assert $smtp[:started]
166
+ assert $smtp[:finish]
167
+ end
168
+
169
+ test "Malone.deliver forwards to Malone.current" do |m|
170
+ Malone.deliver(to: "recipient@me.com", from: "no-reply@mydomain.com",
171
+ subject: "SUB", text: "TEXT")
172
+
173
+ assert_equal "smtp.gmail.com", $smtp.host
174
+ assert_equal 587, $smtp.port
175
+
176
+ assert $smtp[:enable_starttls_auto]
177
+ assert_equal "mydomain.com", $smtp[:domain]
178
+ assert_equal "foo@bar.com", $smtp[:user]
179
+ assert_equal "pass1234", $smtp[:password]
180
+ assert_equal :login, $smtp[:auth]
181
+
182
+ assert_equal ["recipient@me.com"], $smtp[:recipients]
183
+ assert_equal "no-reply@mydomain.com", $smtp[:from]
184
+
185
+ assert $smtp[:started]
186
+ assert $smtp[:finish]
187
+ end
188
+
189
+ test "calls #finish even when it fails during send_message" do |m|
190
+ class FakeSMTP
191
+ def send_message(*args)
192
+ raise
193
+ end
194
+ end
195
+
196
+ begin
197
+ m.deliver(to: "recipient@me.com", from: "no-reply@mydomain.com",
198
+ subject: "SUB", text: "TEXT")
199
+ rescue
200
+ end
201
+
202
+ assert $smtp[:started]
203
+ assert $smtp[:finish]
204
+ end
205
+ end
206
+
207
+ test "sandbox" do
208
+ require "malone/test"
209
+
210
+ m = Malone.connect
211
+ m.deliver(to: "recipient@me.com", from: "no-reply@mydomain.com",
212
+ subject: "SUB", text: "TEXT", html: "<h1>TEXT</h1>")
213
+
214
+ assert_equal 1, Malone.deliveries.size
215
+
216
+ mail = Malone.deliveries.first
217
+
218
+ assert_equal "no-reply@mydomain.com", mail.from
219
+ assert_equal "recipient@me.com", mail.to
220
+ assert_equal "SUB", mail.subject
221
+ assert_equal "TEXT", mail.text
222
+ assert_equal "<h1>TEXT</h1>", mail.html
223
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: malone-acd
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.7
5
+ platform: ruby
6
+ authors:
7
+ - Cyril David
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2011-01-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mailfactory-acd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cutest-cj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: me@cyrildavid.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - CHANGELOG
48
+ - LICENSE
49
+ - README.md
50
+ - lib/malone.rb
51
+ - lib/malone/test.rb
52
+ - malone.gemspec
53
+ - test/helper.rb
54
+ - test/malone.rb
55
+ homepage: http://github.com/cyx/malone
56
+ licenses: []
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.2.2
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Dead-simple Ruby mailing solution which always delivers.
78
+ test_files: []