mailing 0.9.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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mailing.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Piotr Macuk
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # Mailing
2
+
3
+ Tool for sending fast mailings
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mailing'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mailing
18
+
19
+ ## Step by step usage
20
+
21
+ require 'mailing'
22
+ require 'logger'
23
+
24
+ # create channel
25
+ config = {
26
+ :address => 'localhost',
27
+ :port => 25,
28
+ :domain => 'localhost.localdomain'
29
+ }
30
+ channel = Mailing::SmtpChannel.new(config)
31
+
32
+ # create sender with channel, envelope_from and logger
33
+ logger = Logger.new('/tmp/mailing.log')
34
+ sender = Mailing::Sender.new(channel, 'sender@domain.com', logger)
35
+
36
+ # create mailing with from, subject, body, recipients
37
+ mailing = Mailing::Mailing.new('from@domain.com', 'Subject', 'Body')
38
+ mailing.recipients = %w(john@domain.com paul@domain.com peter@domain.com)
39
+
40
+ # send mailing
41
+ mailing.send(sender)
42
+
43
+ ## Quick usage
44
+
45
+ require 'mailing'
46
+ require 'logger'
47
+
48
+ mailing = Mailing::Mailing.new('from@domain.com', 'Subject', 'Body')
49
+ mailing.recipients = %w(john@domain.com paul@domain.com peter@domain.com)
50
+ config = {
51
+ :address => 'localhost',
52
+ :port => 25,
53
+ :domain => 'localhost.localdomain'
54
+ }
55
+ mailing.send_by_smtp(config, 'sender@domain.com')
56
+
57
+ ## Rails usage
58
+
59
+ mailing = Mailing::Mailing.new('from@domain.com', 'Subject', 'Body')
60
+ mailing.recipients = User.pluck(:email)
61
+ mailing.send_by_smtp(ActionMailer::Base.smtp_settings,
62
+ 'sender@domain.com', Rails.logger)
63
+
64
+ ## Contributing
65
+
66
+ 1. Fork it
67
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
68
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
69
+ 4. Push to the branch (`git push origin my-new-feature`)
70
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,29 @@
1
+ module Mailing
2
+ class Mailing
3
+ require 'mail'
4
+
5
+ attr_accessor :from, :subject, :body, :recipients
6
+
7
+ def initialize(from, subject, body, recipients=[])
8
+ @from, @subject, @body = from, subject, body
9
+ @recipients = recipients
10
+ end
11
+
12
+ def send(sender)
13
+ sender.send(self)
14
+ end
15
+
16
+ def send_by_smtp(config, envelope_from, logger=nil)
17
+ channel = SmtpChannel.new(config)
18
+ sender = Sender.new(channel, envelope_from, logger)
19
+ send(sender)
20
+ end
21
+
22
+ def mail(builder=Mail)
23
+ mail = builder.new(:from => @from, :subject => @subject, :body => @body)
24
+ mail.charset = 'UTF-8'
25
+ mail.content_transfer_encoding = "8bit"
26
+ mail
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ module Mailing
2
+ class Sender
3
+ attr_accessor :channel, :envelope_from, :logger, :delay
4
+
5
+ def initialize(channel, envelope_from, logger=nil, delay=0.5)
6
+ @channel = channel
7
+ @envelope_from = envelope_from
8
+ @logger = logger
9
+ @delay = delay
10
+ end
11
+
12
+ def send(mailing)
13
+ @mailing = mailing
14
+ @mail = @mailing.mail
15
+ info "Start mailing: #{Time.now}"
16
+ info @mail.encoded
17
+ info "Recipients count: #{@mailing.recipients.size}"
18
+ deliver
19
+ end
20
+
21
+ protected
22
+ def deliver
23
+ info "Start sending: #{Time.now}"
24
+ channel.start
25
+ @mailing.recipients.each do |recipient|
26
+ @mail.to = recipient
27
+ info channel.deliver(@mail.encoded, @envelope_from, recipient)
28
+ sleep @delay
29
+ end
30
+ channel.finish
31
+ info "Finish sending: #{Time.now}"
32
+ info "---" * 20
33
+ info "\n"
34
+ end
35
+
36
+ def info(msg)
37
+ return unless @logger
38
+ @logger.info msg
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,45 @@
1
+ module Mailing
2
+ class SmtpChannel
3
+ require 'net/smtp'
4
+
5
+ attr_accessor :config
6
+
7
+ # config: hash with smtp configuration
8
+ # {
9
+ # :address => "host.domain.com",
10
+ # :port => 25,
11
+ # :domain => 'domain.com',
12
+ # :user_name => 'user@domain.com',
13
+ # :password => 'password',
14
+ # :authentication => :login,
15
+ # :enable_starttls_auto => true,
16
+ # :openssl_verify_mode => 'none'
17
+ # }
18
+ def initialize(config)
19
+ @config = config
20
+ @smtp = nil
21
+ end
22
+
23
+ def start
24
+ @smtp = Net::SMTP.new(@config[:address], @config[:port])
25
+ @smtp.enable_starttls_auto if @config[:enable_starttls_auto]
26
+ @smtp.start(@config[:domain], @config[:user_name],
27
+ @config[:password], @config[:authentication])
28
+ end
29
+
30
+ def deliver(mail, envelope_from, recipient)
31
+ begin
32
+ @smtp.sendmail(mail, envelope_from, recipient)
33
+ "Sent to #{recipient}"
34
+ rescue Exception => e
35
+ finish
36
+ start
37
+ "Error for #{recipient}: #{e}".strip
38
+ end
39
+ end
40
+
41
+ def finish
42
+ @smtp.finish
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module Mailing
2
+ VERSION = "0.9.0"
3
+ end
data/lib/mailing.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'mailing/version'
2
+ require 'mailing/mailing'
3
+ require 'mailing/sender'
4
+ require 'mailing/smtp_channel'
data/mailing.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mailing/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Piotr Macuk"]
6
+ gem.email = ["piotr@macuk.pl"]
7
+ gem.description = %q{Tool for sending fast mailings}
8
+ gem.summary = %q{Fast mailings}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mailing"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mailing::VERSION
17
+ gem.add_dependency 'mail', ["~> 2.4.4"]
18
+ end
@@ -0,0 +1,50 @@
1
+ require 'minitest/autorun'
2
+ require 'mailing/mailing'
3
+
4
+ class MailingTest < MiniTest::Unit::TestCase
5
+ def setup
6
+ @mailing = Mailing::Mailing.new('from', 'subject', 'body')
7
+ end
8
+
9
+ def test_init
10
+ assert_equal 'from', @mailing.from
11
+ assert_equal 'subject', @mailing.subject
12
+ assert_equal 'body', @mailing.body
13
+ assert_empty @mailing.recipients
14
+ end
15
+
16
+ def test_init_with_recipients
17
+ @mailing = Mailing::Mailing.new('from', 'subject', 'body', [1, 2, 3])
18
+ assert_equal [1, 2, 3], @mailing.recipients
19
+ end
20
+
21
+ def test_accessors
22
+ @mailing.from = 'test'
23
+ assert_equal 'test', @mailing.from
24
+ @mailing.subject = 'test'
25
+ assert_equal 'test', @mailing.subject
26
+ @mailing.body = 'test'
27
+ assert_equal 'test', @mailing.body
28
+ end
29
+
30
+ def test_recipient_accessor
31
+ @mailing.recipients = [1, 2, 3]
32
+ assert_equal 3, @mailing.recipients.size
33
+ @mailing.recipients << 4
34
+ assert_equal 4, @mailing.recipients.size
35
+ end
36
+
37
+ def test_mail
38
+ mail = @mailing.mail.encoded
39
+ assert_match /From: from/, mail
40
+ assert_match /Subject: subject/, mail
41
+ assert_match /body/, mail
42
+ end
43
+
44
+ def test_send
45
+ sender = MiniTest::Mock.new
46
+ sender.expect(:send, nil, [@mailing])
47
+ @mailing.send(sender)
48
+ sender.verify
49
+ end
50
+ end
@@ -0,0 +1,53 @@
1
+ require 'minitest/autorun'
2
+ require 'mailing/sender'
3
+
4
+ class SenderTest < MiniTest::Unit::TestCase
5
+ def setup
6
+ @channel = MiniTest::Mock.new
7
+ @channel.expect(:start, nil)
8
+ @channel.expect(:deliver, 'delivered', [String, String, String])
9
+ @channel.expect(:finish, nil)
10
+
11
+ @sender = Mailing::Sender.new(@channel, 'me@host.com')
12
+
13
+ @mail = MiniTest::Mock.new
14
+ @mail.expect(:encoded, 'mail')
15
+ @mailing = MiniTest::Mock.new
16
+ @mailing.expect(:mail, @mail)
17
+ end
18
+
19
+ def test_init
20
+ assert_equal 'me@host.com', @sender.envelope_from
21
+ assert_nil @sender.logger
22
+ assert_equal 0.5, @sender.delay
23
+ end
24
+
25
+ def test_accessors
26
+ @sender.envelope_from = 'test@test.com'
27
+ assert_equal 'test@test.com', @sender.envelope_from
28
+ @sender.logger = []
29
+ assert_equal [], @sender.logger
30
+ @sender.delay = 1
31
+ assert_equal 1, @sender.delay
32
+ end
33
+
34
+ def test_send_with_no_recipients
35
+ @mailing.expect(:recipients, [])
36
+ @sender.send(@mailing)
37
+ @mail.verify
38
+ @mailing.verify
39
+ end
40
+
41
+ def test_send_with_recipients
42
+ @sender.delay = 0
43
+ @mailing.expect(:recipients, [1, 2])
44
+ @mail.expect(:'to=', nil, [1])
45
+ @mail.expect(:'to=', nil, [2])
46
+ @channel.expect(:deliver, 'delivered', [String, 'me@host.com', 1])
47
+ @channel.expect(:deliver, 'delivered', [String, 'me@host.com', 2])
48
+ @sender.send(@mailing)
49
+ @mail.verify
50
+ @mailing.verify
51
+ @channel.verify
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mailing
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Piotr Macuk
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mail
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.4.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.4.4
30
+ description: Tool for sending fast mailings
31
+ email:
32
+ - piotr@macuk.pl
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - lib/mailing.rb
43
+ - lib/mailing/mailing.rb
44
+ - lib/mailing/sender.rb
45
+ - lib/mailing/smtp_channel.rb
46
+ - lib/mailing/version.rb
47
+ - mailing.gemspec
48
+ - test/mailing_test.rb
49
+ - test/sender_test.rb
50
+ homepage: ''
51
+ licenses: []
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.21
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Fast mailings
74
+ test_files:
75
+ - test/mailing_test.rb
76
+ - test/sender_test.rb