smitty 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []