smitty 0.0.2

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDZhYzc4ZjY5ODBhZTYxZGJjYzA4MTI3Njc2ZDlmZWQ4Y2Q1NzY3YQ==
5
+ data.tar.gz: !binary |-
6
+ MzE5NzhlMzE2NzU2ZjNmN2E2ZGM5ZWZhMGNkMDUzZDUwZmNmMjM1Yw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OWQzNjU4YTIyZDc3ODNiZjhkMTJiN2FjNjgzZTE5NzRhZDYyYjAyNmMxMWY3
10
+ ZWQzNWQ5N2U2ODBkNjQ0ZjJmMzUxODhmNDhmMmMzN2Y3YzAwMmQwNGQxOTJj
11
+ OWQ0ZmNkZTVkMWFjZjdhZTAwNTQ5NTM0MGJiNDgwMzEwMjFmZWU=
12
+ data.tar.gz: !binary |-
13
+ MmUxMmE1ZWI0NDQ5ODJhNWQ0Yzk4NzQ5NTVkOWVhNGM4ZTQ0YzAxOThiZmZj
14
+ MzU3MDRhNzg1MzBiODY0ZDU3OTA1OGM2NTAwYTE1MDVkY2NiNzgxZjc5NGJm
15
+ ZjE2NWEzMTYwM2RhODY0MDY5YTQwNWVjYjFjODI2M2JlYTBmODc=
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.css
2
+ *.gem
3
+ .DS_Store
4
+ *.hbs
5
+ *.html
6
+ *.txt
7
+ *.rbc
8
+ .bundle
9
+ .config
10
+ .yardoc
11
+ Gemfile.lock
12
+ InstalledFiles
13
+ _yardoc
14
+ coverage
15
+ doc/
16
+ lib/bundler/man
17
+ pkg
18
+ rdoc
19
+ spec/reports
20
+ test/tmp
21
+ test/version_tmp
22
+ tmp
23
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in smitty.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Tom Steele
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,62 @@
1
+ # Smitty
2
+
3
+ Smitty is a mail client that allows you to use handlebars like HTML templates. It supports all the things you would expect out a mail client. Internally it uses [mail](https://github.com/mikel/mail) for creation and [premailer](https://github.com/alexdunae/premailer/) for inline css. Generation for Multi-Part messages is all done for you.
4
+
5
+ Smitty doesn't use everything that is available in handlebars, it only does replacement for variables. What this allows you to do is create nice looking HTML templates in a proper editor, and then do quick search and replace.
6
+
7
+ For example, say you wanted to loop over a set of emails and names, inserting a different name for the corresponding email. In your template, you would put {{name}} in the place where you wanted replacement to occur, write your names and email addresses in 'names.txt' and 'emails.txt' respectively, and call smitty like so. Assume your template is in template.hbs.
8
+
9
+ ./smitty from@someplace.io emails.txt 'YO {{name}}' template.hbs --vars 'name=names.txt'
10
+
11
+ Smitty would then loop over each email address in emails.txt, replacing {{name}} with the corresponding name from names.txt. As you can see, variable names in the subject is also supported.
12
+
13
+ ## Installation
14
+
15
+ Download the latest gem [here](https://github.com/tomsteele/smitty/releases/download/v0.0.2/smitty-0.0.2.gem) and install with gem:
16
+
17
+ $ gem install smitty
18
+
19
+ Or build and install it yourself as:
20
+
21
+ $ gem build smitty.gemspec
22
+ $ gem install smitty
23
+
24
+ ## Usage
25
+
26
+ Smitty 0.0.2
27
+
28
+ Usage:
29
+ ./smitty [options] <from_address> <to_file> <subject> <template>
30
+ ./smitty -h | --help
31
+ ./smitty -v | --version
32
+
33
+ Required Arguments:
34
+ from_address: Address to send mail from.
35
+ to_file: Newline separated file containing recipient addresses.
36
+ subject: Mail subject, can have handlebar replacements.
37
+ template: Handlebars like HTML template.
38
+
39
+ Options:
40
+ -h --help Show this usage.
41
+ -v --version Show version.
42
+ --vars key=value,key=value Variables for template and subject line, should be a comma separated
43
+ list of key value pairs. Key should be the variable name in your
44
+ template, and value may be a constant or a newline separated file.
45
+ Value file and to_file must have the same amount of lines.
46
+ -a files Attach comma separated list of files.
47
+ --server SERVER SMTP Server, default is localhost.
48
+ --port PORT SMTP Port, default is 25.
49
+ --ssl Use SSL, default is false.
50
+ --username USER SMTP user.
51
+ --password PASSWORD SMTP password.
52
+ --cc address Add a cc address.
53
+ --bcc address Add a bcc address.
54
+ --dry-run Output messages and don't send.
55
+
56
+ ## Contributing
57
+
58
+ 1. Fork it
59
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
60
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
61
+ 4. Push to the branch (`git push origin my-new-feature`)
62
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/smitty ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.join(File.dirname(__FILE__), '/../lib'))
3
+ require 'mail'
4
+ require 'docopt'
5
+ require 'nokogiri'
6
+ require 'premailer'
7
+ require 'smitty'
8
+
9
+ # Parse arguments
10
+ begin
11
+ args = Docopt::docopt(Smitty::USAGE, {version: Smitty::VERSION})
12
+ rescue Docopt::Exit => e
13
+ puts e.message
14
+ exit(0)
15
+ end
16
+
17
+ # Create SMTP connection and set Mail default
18
+ smtp_conn = Smitty.smtp_connect(args['--server'], args['--port'], args['--ssl'], args['--username'], args['--password'])
19
+ Mail.defaults do
20
+ delivery_method :smtp_connection, { :connection => smtp_conn }
21
+ end
22
+
23
+ attachments = args['-a'].split(',') if args['-a']
24
+ from_address = args['<from_address>']
25
+ subject = args['<subject>']
26
+
27
+ # Read to_file into list of addresses
28
+ begin
29
+ to_addresses = File.readlines(args['<to_file>']).map(&:chomp)
30
+ rescue Errno::ENOENT => e
31
+ Smitty.croak("Count not open #{args['<to_file>']}", e.message)
32
+ end
33
+
34
+ # Read in template
35
+ begin
36
+ template = Premailer.new(args['<template>'])
37
+ rescue Errno::ENOENT => e
38
+ Smitty.croak("Could not open #{args['<to_file>']}", e.message)
39
+ end
40
+
41
+ # Parse replacement variables, exiting if length is not equal to to_file
42
+ variables = []
43
+ variables = args['--vars'].split(',').map { |var| Smitty.variable_parser(var, to_addresses.length) } unless args['--vars'].nil?
44
+
45
+ # Loop over each receipient, create a temporary template,
46
+ # replace variables, and send the message
47
+ to_addresses.each do |to_address|
48
+ template_copy = String.new(template.to_inline_css)
49
+ subject_copy = String.new(subject)
50
+ # Replace each variable in the template
51
+ variables.each do |variable|
52
+ if variable[:with].kind_of?(Array)
53
+ sub_text = variable[:with].shift()
54
+ else
55
+ sub_text = variable[:with]
56
+ end
57
+ template_copy.gsub!("{{#{variable[:replace_string]}}}", sub_text)
58
+ subject_copy.gsub!("{{#{variable[:replace_string]}}}", sub_text)
59
+ end
60
+ Smitty.croak('A marker was found in the template that did not have a matching key') if template_copy =~ /\{\{\w+\}\}/
61
+ Smitty.croak('A marker was found in the subject that did not have a matching key') if subject_copy =~ /\{\{\w+\}\}/
62
+ # Create the new mail object
63
+ mail = Mail.new()
64
+ mail.from = from_address
65
+ mail.to = to_address
66
+ mail.bcc = args['--bcc'] unless args['--bcc'].nil?
67
+ mail.cc = args['--cc'] unless args['--cc'].nil?
68
+ mail.subject = subject_copy
69
+ mail.text_part do
70
+ body Nokogiri::HTML(template_copy).text
71
+ end
72
+ mail.html_part do
73
+ content_type 'text/html; charset=UTF-8'
74
+ body template_copy
75
+ end
76
+ # Attach each file to the message
77
+ begin
78
+ attachments.each { |file| mail.add_file(file) } unless attachments.nil?
79
+ rescue Exception => e
80
+ Smitty.croak('Could not attach file', e.message)
81
+ end
82
+ if args['--dry-run']
83
+ puts mail.to_s
84
+ else
85
+ puts "Message delivered to #{to_address}"
86
+ mail.deliver!
87
+ end
88
+ end
@@ -0,0 +1,7 @@
1
+ module Smitty
2
+ # Prints variable amount of messages and exits
3
+ def self.croak(*messages)
4
+ messages.each { |message| puts "Error: #{message}"}
5
+ exit(1)
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require 'net/smtp'
2
+
3
+ module Smitty
4
+ def self.smtp_connect(server, port, ssl, username, password)
5
+ begin
6
+ smtp_server = server.nil? ? 'localhost' : server
7
+ smtp_port = port.nil? ? 25 : port.to_i
8
+ smtp_conn = Net::SMTP.new(smtp_server, smtp_port)
9
+ smtp_conn.enable_tls() if ssl
10
+ if username
11
+ Smitty.croak('No password provided') if password.nil?
12
+ smtp_conn.start(smtp_server, username, password, :plain)
13
+ else
14
+ smtp_conn.start()
15
+ end
16
+ smtp_conn
17
+ rescue Exception => e
18
+ Smitty.croak("Could not connect to SMTP server #{smtp_server}:#{smtp_port}", e.message)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module Smitty
2
+ USAGE = <<DOC
3
+ Smitty #{Smitty::VERSION}
4
+
5
+ Usage:
6
+ #{$0} [options] <from_address> <to_file> <subject> <template>
7
+ #{$0} -h | --help
8
+ #{$0} -v | --version
9
+
10
+ Required Arguments:
11
+ from_address: Address to send mail from.
12
+ to_file: Newline separated file containing recipient addresses.
13
+ subject: Mail subject, can have handlebar replacements.
14
+ template: Handlebars like HTML template.
15
+
16
+ Options:
17
+ -h --help Show this usage.
18
+ -v --version Show version.
19
+ --vars key=value,key=value Variables for template and subject line, should be a comma separated
20
+ list of key value pairs. Key should be the variable name in your
21
+ template, and value may be a constant or a newline separated file.
22
+ Value file and to_file must have the same amount of lines.
23
+ -a files Attach comma separated list of files.
24
+ --server SERVER SMTP Server, default is localhost.
25
+ --port PORT SMTP Port, default is 25.
26
+ --ssl Use SSL, default is false.
27
+ --username USER SMTP user.
28
+ --password PASSWORD SMTP password.
29
+ --cc address Add a cc address.
30
+ --bcc address Add a bcc address.
31
+ --dry-run Output messages and don't send.
32
+
33
+ DOC
34
+ end
@@ -0,0 +1,15 @@
1
+ module Smitty
2
+ def self.variable_parser(variable_string, mail_length)
3
+ pairs = variable_string.split('=')
4
+ # content is a file
5
+ begin
6
+ with_content = File.readlines(pairs[1]).map(&:chomp)
7
+ Smitty.croak("#{pairs[0]} != recipient length") if with_content.length != mail_length
8
+ rescue Errno::ENOENT
9
+ with_content = pairs[1]
10
+ rescue
11
+ croak("Could not parse key value pair #{variable_string}")
12
+ end
13
+ {replace_string: pairs[0], with: with_content }
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Smitty
2
+ VERSION = '0.0.2'
3
+ end
data/lib/smitty.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'smitty/version'
2
+ require 'smitty/usage'
3
+ require 'smitty/croak'
4
+ require 'smitty/variable_parser'
5
+ require 'smitty/smtp_connect'
data/smitty.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'smitty/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "smitty"
8
+ spec.version = Smitty::VERSION
9
+ spec.authors = ["Tom Steele"]
10
+ spec.email = ["thomasjsteele@gmail.com"]
11
+ spec.description = %q{Send mail with handlebars like templates}
12
+ spec.summary = %q{Send mail with handlebars like templates}
13
+ spec.homepage = "https://github.com/tomsteele/smitty"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "docopt", ">= 0.5.0"
22
+ spec.add_dependency "nokogiri", ">= 1.6.0"
23
+ spec.add_dependency "mail", ">= 2.5.4"
24
+ spec.add_dependency "premailer", ">= 1.7.3"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.3"
27
+ spec.add_development_dependency "rake"
28
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smitty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Tom Steele
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: docopt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.5.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.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: mail
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 2.5.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.5.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: premailer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.7.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.7.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Send mail with handlebars like templates
98
+ email:
99
+ - thomasjsteele@gmail.com
100
+ executables:
101
+ - smitty
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - bin/smitty
111
+ - lib/smitty.rb
112
+ - lib/smitty/croak.rb
113
+ - lib/smitty/smtp_connect.rb
114
+ - lib/smitty/usage.rb
115
+ - lib/smitty/variable_parser.rb
116
+ - lib/smitty/version.rb
117
+ - smitty.gemspec
118
+ homepage: https://github.com/tomsteele/smitty
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.0.7
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Send mail with handlebars like templates
142
+ test_files: []