mailtest 0.0.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 609959bc9a33b070c2b676661ce2d336ac775766
4
+ data.tar.gz: 6624c276d23cb5c2186b165d7bdfec6df2104e0b
5
+ SHA512:
6
+ metadata.gz: 905521f21c4e5c8cf24b5fde50f7d6d767b7fccf706aaf96530be25abab7336d23ccc9463a0f57beff81487c801718b34596ca347ee636ad2e346f8af70ee74c
7
+ data.tar.gz: 266f7e0a153ced5fa3cc27f0e30b0cfda1a5b159ac25a3e5dcc803ace73ac568156a82c3f92a01f4e4180d5fbca254a8f31212afb8605d32182a8a4c19137d74
data/.envrc ADDED
@@ -0,0 +1,7 @@
1
+ if has nix-env ; then
2
+ use nix -p bundler ruby
3
+ fi
4
+
5
+ layout ruby
6
+
7
+ PATH_add ./bin
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.yml
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Peter Hoeg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,45 @@
1
+ * Mailtest
2
+
3
+ This tool sends test messages to a number of receivers specified in a YAML file.
4
+
5
+ All the messages get a sequence number and a generated "transaction word" in
6
+ order to make the emails easy to search for.
7
+
8
+ Please keep in mind that as the "transaction word" is randomly generated it may
9
+ end up being something offensive. If it offends you or any of the receivers or
10
+ anybody else who happens to see the generated mails, that is simply too bad - it
11
+ is not our problem.
12
+
13
+ ** Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ #+BEGIN_SRC ruby
18
+ gem 'mailtest'
19
+ #+END_SRC
20
+
21
+ And then execute:
22
+
23
+ #+BEGIN_SRC shell
24
+ bundle
25
+ #+END_SRC
26
+
27
+ Or install it yourself as:
28
+
29
+ #+BEGIN_SRC shell
30
+ gem install mailtest
31
+ #+END_SRC
32
+
33
+ ** Usage
34
+
35
+ bin/mailtest --help will give you the details on how to use it
36
+
37
+ ** Contributing
38
+
39
+ Bug reports and pull requests are welcome on GitHub at
40
+ https://github.com/peterhoeg/mailtest.
41
+
42
+
43
+ ** License
44
+
45
+ The gem is available as open source under the terms of the [[http://opensource.org/licenses/MIT][MIT License]].
@@ -0,0 +1,16 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ DIRS = %w[lib test].freeze
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs = DIRS
8
+ t.test_files = FileList['test/**/*_test.rb']
9
+ end
10
+
11
+ Rake::TestTask.new(:bench) do |t|
12
+ t.libs = DIRS
13
+ t.test_files = FileList['test/**/*_benchmark.rb']
14
+ end
15
+
16
+ task default: :test
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bundler/setup'
3
+
4
+ $LOAD_PATH.unshift 'lib'
5
+ require 'mailtest/cli'
@@ -0,0 +1,7 @@
1
+ $VERBOSE = nil
2
+
3
+ require 'mailtest/runner'
4
+ require 'mailtest/version'
5
+
6
+ module Mailtest
7
+ end
@@ -0,0 +1,86 @@
1
+ $stdout.sync = true
2
+ $stderr.sync = true
3
+
4
+ require 'main'
5
+ require 'mailtest'
6
+
7
+ Main do
8
+ argument('receiver') do
9
+ required
10
+ description 'An email address or the file with the list of receivers'
11
+ end
12
+
13
+ argument('from') do
14
+ required
15
+ description 'The sender of the email'
16
+ end
17
+
18
+ option('body') do
19
+ argument :required
20
+ default <<-EOF
21
+ This is an email test. You can safely ignore this message.
22
+
23
+ This word does not mean anything: @word@
24
+ EOF
25
+ description 'The body of the message'
26
+ end
27
+
28
+ option('subject') do
29
+ argument :required
30
+ default '[@index@/@count@]: @word@ test for @receiver@, @timestamp@'
31
+ description 'The subject of the message'
32
+ end
33
+
34
+ option('cc') do
35
+ argument :required
36
+ cast :list_of_string
37
+ description 'A comma separated list of addresses to keep in CC'
38
+ end
39
+
40
+ option('bcc') do
41
+ argument :required
42
+ cast :list_of_string
43
+ description 'A comma separated list of addresses to keep in BCC'
44
+ end
45
+
46
+ option('domain') do
47
+ argument :required
48
+ description 'The domain to add to or replace in the receiver list'
49
+ end
50
+
51
+ option('host') do
52
+ argument :required
53
+ default 'localhost'
54
+ description 'The mail hosts through which we send'
55
+ end
56
+
57
+ option('port') do
58
+ argument :required
59
+ cast :int
60
+ default 25
61
+ description 'The mail host port through which we send'
62
+ end
63
+
64
+ option('word_length') do
65
+ argument :required
66
+ cast :int
67
+ default 20
68
+ description 'Minimum length of the random word used'
69
+ end
70
+
71
+ option('debug') do
72
+ cast :bool
73
+ description 'Enter debugging mode'
74
+ end
75
+
76
+ option('dry-run') do
77
+ cast :bool
78
+ description 'Do we actually send the messages'
79
+ end
80
+
81
+ def run
82
+ runner = Runner.new(params)
83
+ runner.run
84
+ exit_success!
85
+ end
86
+ end
@@ -0,0 +1,170 @@
1
+ require 'ap'
2
+ require 'mail'
3
+ require 'progress_bar'
4
+ require 'rainbow'
5
+ require 'random-word'
6
+ require 'yaml'
7
+
8
+ class Runner
9
+ def initialize(params)
10
+ setup_logger!(params['debug'].value)
11
+ setup_mail!(params)
12
+ setup_receivers!(params)
13
+ setup_tokens!(params)
14
+ @bar = ProgressBar.new(@receivers.count)
15
+ @dry_run = params['dry-run'].value
16
+ @messages = []
17
+
18
+ create_emails!(params)
19
+ end
20
+
21
+ def run
22
+ errors = []
23
+ success = 0
24
+
25
+ @logger.info "Sending '#{@tokens[:word]}' to #{@tokens[:count]} recipient(s)"
26
+
27
+ @messages.each_with_index do |m, i|
28
+ receivers = m.to.join(', ')
29
+ @logger.debug "Sending to: #{receivers} #{x_of_y(i)}"
30
+ begin
31
+ m.deliver unless @dry_run
32
+ success += 1
33
+ rescue StandardError => e
34
+ errors << receivers
35
+ @logger.error Rainbow(e.message).red
36
+ ensure
37
+ @bar.increment!
38
+ end
39
+ end
40
+
41
+ show_result!(success, errors)
42
+ end
43
+
44
+ def debug
45
+ @messages.each do |m|
46
+ ap m
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def setup_logger!(debug)
53
+ @logger = Logger.new(STDOUT)
54
+ @logger.level = debug ? Logger::DEBUG : Logger::INFO
55
+ end
56
+
57
+ def setup_mail!(params)
58
+ Mail.defaults do
59
+ delivery_method :smtp,
60
+ address: params['host'].value,
61
+ port: params['port'].value
62
+ end
63
+ end
64
+
65
+ def setup_receivers!(params)
66
+ @logger.debug 'Creating receiver list'
67
+ receivers = []
68
+ receiver = params['receiver'].value
69
+ if File.exist?(receiver)
70
+ begin
71
+ receivers = YAML.load_file(receiver)
72
+ rescue StandardError => e
73
+ @logger.error e.message
74
+ end
75
+ @logger.debug "#{receiver} is a file with email addresses"
76
+ elsif receiver =~ /,/
77
+ receivers = receiver.split(',')
78
+ @logger.debug "#{receiver} is a list of email addresses"
79
+ elsif valid_email?(receiver)
80
+ # we expect an array
81
+ receivers << receiver
82
+ @logger.debug "#{receiver} is a valid email address"
83
+ else
84
+ raise "#{receiver} is neither an email address nor a file with addresses"
85
+ end
86
+
87
+ @receivers = receivers.map do |r|
88
+ add_or_replace_domain(r, params['domain'].value)
89
+ end
90
+
91
+ @logger.debug "Receivers: #{@receivers}"
92
+ @count = @receivers.length
93
+ end
94
+
95
+ def setup_tokens!(params)
96
+ @logger.debug 'Creating tokens'
97
+ length = params['word_length'].value
98
+ @tokens = {
99
+ count: @receivers.count,
100
+ index: 0,
101
+ receiver: nil,
102
+ timestamp: Time.now,
103
+ word: RandomWord.nouns(not_shorter_than: length).next
104
+ }
105
+ end
106
+
107
+ def create_emails!(params)
108
+ @logger.debug 'Creating mails'
109
+ @receivers.each_with_index do |receiver, i|
110
+ @tokens[:index] = i + 1
111
+ @tokens[:receiver] = receiver
112
+ subjectp = replace_tokens(params['subject'].value)
113
+ bodyp = replace_tokens(params['body'].value)
114
+ @messages << Mail.new do
115
+ from params['from'].value
116
+ to receiver
117
+ subject subjectp
118
+ body bodyp
119
+ cc params['cc'].value
120
+ end
121
+ end
122
+ end
123
+
124
+ def color_number(number, color, color_zero = false)
125
+ return number.to_s if number.zero? && !color_zero
126
+ Rainbow(number.to_s).color(color)
127
+ end
128
+
129
+ def show_result!(success, errors)
130
+ success_str = color_number(success, :green, true)
131
+ errors_str = color_number(errors.length, :red)
132
+
133
+ @logger.info "Finished: [#{success_str}/#{errors_str}/#{@count}]"
134
+ if errors.empty?
135
+ @logger.info Rainbow('Success!').green
136
+ else
137
+ @logger.error Rainbow("Errors: #{errors.join(', ')}").red
138
+ end
139
+ end
140
+
141
+ def valid_email?(str)
142
+ !str !~ /@/
143
+ end
144
+
145
+ def add_or_replace_domain(receiver, domain)
146
+ if valid_email?(receiver) && domain
147
+ user = receiver.split('@')[0]
148
+ return [user, domain].join('@')
149
+ elsif valid_email?(receiver)
150
+ return receiver
151
+ elsif domain
152
+ return [receiver, domain].join('@')
153
+ end
154
+ @logger.error "Receiver: #{receiver}, domain: #{domain}"
155
+ raise ArgumentError, 'Unable to read/generate email address'
156
+ end
157
+
158
+ def replace_tokens(str)
159
+ s = str
160
+
161
+ %w[count index receiver timestamp word].each do |t|
162
+ s = s.gsub("@#{t}@", @tokens[t.to_sym].to_s)
163
+ end
164
+ s
165
+ end
166
+
167
+ def x_of_y(x)
168
+ "[#{x + 1}/#{@tokens[:count]}]"
169
+ end
170
+ end
@@ -0,0 +1,3 @@
1
+ module Mailtest
2
+ VERSION = '0.0.4'.freeze
3
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'mailtest/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'mailtest'
9
+ spec.version = Mailtest::VERSION
10
+ spec.authors = ['Peter Hoeg']
11
+ spec.email = ['peter@hoeg.com']
12
+
13
+ spec.summary = 'Generate a test email to a list of receivers.'
14
+ spec.description = 'Helps when doing mass email changes or migrations\
15
+ where you need to verify that everything is set up correctly.'
16
+ spec.homepage = 'https://github.com/peterhoeg/mailtest'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_development_dependency 'bundler'
27
+ spec.add_development_dependency 'minitest'
28
+ spec.add_development_dependency 'minitest-reporters'
29
+ spec.add_development_dependency 'rake'
30
+ spec.add_development_dependency 'rubocop'
31
+
32
+ spec.add_dependency 'mail'
33
+ spec.add_dependency 'main'
34
+ spec.add_dependency 'awesome_print'
35
+ spec.add_dependency 'progress_bar'
36
+ spec.add_dependency 'rainbow'
37
+ spec.add_dependency 'random-word'
38
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mailtest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Peter Hoeg
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-06-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
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: minitest
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
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-reporters
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mail
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: main
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: awesome_print
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: progress_bar
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rainbow
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: random-word
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: |-
168
+ Helps when doing mass email changes or migrations\
169
+ where you need to verify that everything is set up correctly.
170
+ email:
171
+ - peter@hoeg.com
172
+ executables: []
173
+ extensions: []
174
+ extra_rdoc_files: []
175
+ files:
176
+ - ".envrc"
177
+ - ".gitignore"
178
+ - Gemfile
179
+ - LICENSE.txt
180
+ - README.org
181
+ - Rakefile
182
+ - bin/mailtest
183
+ - lib/mailtest.rb
184
+ - lib/mailtest/cli.rb
185
+ - lib/mailtest/runner.rb
186
+ - lib/mailtest/version.rb
187
+ - mailtest.gemspec
188
+ homepage: https://github.com/peterhoeg/mailtest
189
+ licenses:
190
+ - MIT
191
+ metadata: {}
192
+ post_install_message:
193
+ rdoc_options: []
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ requirements: []
207
+ rubyforge_project:
208
+ rubygems_version: 2.6.10
209
+ signing_key:
210
+ specification_version: 4
211
+ summary: Generate a test email to a list of receivers.
212
+ test_files: []