simple_mail_builder 0.1.0

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: 491fbcb4035815dd0a9d1b427d99c63ba3977d51
4
+ data.tar.gz: b02098db9e11f486d13988ed4809681f7493d187
5
+ SHA512:
6
+ metadata.gz: aa5307bb25bfe318efaf1c27d7e0bbf6cdbc898f013e78f299092417d6733c5af06631b9d8c3b4666f0fffd2a0b66e62234f3f33913aaad706af0a139c01aeb2
7
+ data.tar.gz: 808ce9eb28006662c925251c79402604df5024b58c27688dea659efaa2b1dfa52b9c49485ad4be631b64ef2e2ac4eb3a6ca5a47bbb586e1de4b1778d9570638b
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.0
5
+ before_install: gem install bundler -v 1.13.7
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in simple_mail_builder.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Rodrigo Rosenfeld Rosas
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.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # SimpleMailBuilder
2
+
3
+ SimpleMailBuilder makes it easier to create simple multi-part plain text + HTML mail messages,
4
+ following the most important rules from RFC2047 and RFC2045. Simple messages have the following
5
+ headers: To, From and Subject. They have a text part, an HTML part and no attachments.
6
+
7
+ For a more complete full-specs implementation use the well known "mail" gem.
8
+ I created this gem because the "mail" gem will patch core classes (String mostly) and I wanted
9
+ to avoid monkey patches in my application. Also, it adds quite some overhead and I find its code
10
+ base is a bit complicated to understand and wanted to rely on something simpler to reason about.
11
+
12
+ My application doesn't need to do anything complex with e-mails. It just has to deliver a
13
+ simple multi-part text + HTML message with no attachments to an SMTP server and it doesn't have
14
+ to handle edge cases, like handling chars limits in headers and so on. If you don't have
15
+ much control over your messages, it's better to use another library for creating mail messages.
16
+
17
+ All messages are creating using the UTF-8 charset to make the code simpler. All inputs are
18
+ expected to be in UTF-8 encoding already, so if you are reading the content from some file in
19
+ another encoding you should make sure you convert to UTF-8 before using this library.
20
+
21
+ It uses a static '--MESSAGE BOUNDARY--' as the boundary by default, so if your messages could
22
+ contain such text embedded you should take care of providing a valid boundary yourself as
23
+ this library won't handle such edge cases.
24
+
25
+ From and To addresses should be either a plain single e-mail or a Hash mapping e-mails to the
26
+ names ({'User Name' => 'user@name.com'}). You may use the e-mail as the key too
27
+ when you don't have a corresponding name and in that case the name would be ignored when
28
+ generating the headers and just the e-mail would be used.
29
+
30
+ ## Installation
31
+
32
+ Add this line to your application's Gemfile:
33
+
34
+ ```ruby
35
+ gem 'simple_mail_builder'
36
+ ```
37
+
38
+ And then execute:
39
+
40
+ $ bundle
41
+
42
+ Or install it yourself as:
43
+
44
+ $ gem install simple_mail_builder
45
+
46
+ ## Usage
47
+
48
+ ```ruby
49
+ require 'net/smtp'
50
+ require 'simple_mail_builder'
51
+ message = SimpleMailBuilder::Message.new(
52
+ to: {'Recipient' => 'to@domain.com'},
53
+ from: 'from@domain.com', subject: 'Message subject',
54
+ text: "Header\n\nFirst line\nLast line",
55
+ html: '<h1>Header</h1><p>First line</p><p>Last line</p>'
56
+ ).to_s
57
+ Net::SMTP.start('localhost', 1025) do |smtp|
58
+ smtp.send_message message, 'from@domain.com', 'to@domain.com'
59
+ end
60
+ ```
61
+
62
+ ## Development
63
+
64
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to
65
+ run the tests. You can also run `bin/console` for an interactive prompt that will allow you to
66
+ experiment.
67
+
68
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new
69
+ version, update the version number in `version.rb`, and then run `bundle exec rake release`,
70
+ which will create a git tag for the version, push git commits and tags, and push the `.gem`
71
+ file to [rubygems.org](https://rubygems.org).
72
+
73
+ ## Contributing
74
+
75
+ Bug reports and pull requests are welcome on the
76
+ [GitHub repo](https://github.com/rosenfeld/simple_mail_builder).
77
+
78
+
79
+ ## License
80
+
81
+ The gem is available as open source under the terms of the
82
+ [MIT License](http://opensource.org/licenses/MIT).
83
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'simple_mail_builder'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require_relative '../encoder'
5
+
6
+ module SimpleMailBuilder
7
+ module Encoder
8
+ module Base64
9
+ def self.encode_or_quote(text)
10
+ return %Q{"#{text.gsub '"', ''}"} unless ENCODED_REGEX =~ text
11
+ "=?UTF-8?B?#{::Base64.strict_encode64 text}?="
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../encoder'
4
+
5
+ # See RFC2047 to fully understand how "B" and "Q" encondings work.
6
+ # Basically only ASCII chars are allowed to go unencoded, although they may be encoded.
7
+ # Exceptions are espaces (' '), which can be encoded as underscore ('_') alternatively to
8
+ # the default encoding system described below, and the following chars that must be encoded:
9
+ # '=', '?', '_' and tabs. Encoded chars are represented as '=XX' where XX is the hexadecimal
10
+ # representation in the message charset with 2 digits.
11
+ module SimpleMailBuilder
12
+ module Encoder
13
+ module Quote
14
+ def self.encode_if_required(text)
15
+ return text unless ENCODED_REGEX =~ text
16
+ text = text.gsub(ENCODED_REGEX){ |c| c.bytes.map{|b| '=%02X' % b }.join }.gsub /\s+/, '_'
17
+ "=?UTF-8?Q?#{text}?="
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleMailBuilder
4
+ module Encoder
5
+ # a white list seems safer to me. We are allowed to encode all chars, but the purpose of
6
+ # Q encoding is to allow us to quickly inspect its content without decoding, so we allow
7
+ # the more common chars to skip the encoding.
8
+ # Alternatively we could replace only =, ?, _ and tabs (and newlines/control chars?),
9
+ # but I think a white list is simpler to implement without introducing bugs.
10
+ ENCODED_REGEX = %r{[^a-zA-Z0-9\.\-\+/\"\'\&\(\)\<\>!:%$#@;\[\]\*\s]}
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleMailBuilder
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'digest/md5'
5
+ require_relative 'simple_mail_builder/version'
6
+ require_relative 'simple_mail_builder/encoder/quote'
7
+ require_relative 'simple_mail_builder/encoder/base64'
8
+
9
+ module SimpleMailBuilder
10
+ class Message
11
+ def initialize(from: , to: , subject: , text: , html: , boundary: '--MESSAGE BOUNDARY--',
12
+ date: Time.now, domain: 'local.mail')
13
+ from, to = [from, to].map do |address|
14
+ next address if String === address # otherwise we assume it's a Hash
15
+ address.map do |name, email|
16
+ name == email ? email : "#{Encoder::Base64.encode_or_quote(name)} <#{email}>"
17
+ end.join ", \r\n "
18
+ end
19
+ text, html = [text, html].map{|s| [s].pack('M').chomp("=\n").gsub "\n", "\r\n"}
20
+ message = []
21
+ fdate = date.strftime '%a, %d %b %Y %H:%M:%S %z'
22
+ message << "Date: #{fdate}"
23
+ message << "From: #{from}"
24
+ message << "To: #{to}"
25
+ message_id = Digest::MD5.hexdigest [fdate, to, text, html].join
26
+ message << "Message-ID: <#{message_id}@#{domain}>"
27
+ message << "Subject: #{Encoder::Quote.encode_if_required subject}"
28
+ message << 'Mime-Version: 1.0'
29
+ message << 'Content-Type: multipart/alternative;'
30
+ message << %Q{ boundary="#{boundary}";}
31
+ message << ' charset=UTF-8'
32
+ message << 'Content-Transfer-Encoding: 7bit'
33
+ message << '' << ''
34
+ message << "--#{boundary}"
35
+ message << 'Content-Type: text/plain; charset=UTF-8; format=flowed'
36
+ message << 'Content-Transfer-Encoding: quoted-printable'
37
+ message << ''
38
+ message << text
39
+ message << ''
40
+ message << "--#{boundary}"
41
+ message << 'Content-Type: text/html; charset=UTF-8'
42
+ message << 'Content-Transfer-Encoding: quoted-printable'
43
+ message << ''
44
+ message << html
45
+ message << ''
46
+ message << "--#{boundary}--"
47
+ @message = message.join "\r\n"
48
+ end
49
+
50
+ def to_s
51
+ @message
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ # coding: utf-8
3
+
4
+ require_relative 'lib/simple_mail_builder/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'simple_mail_builder'
8
+ spec.version = SimpleMailBuilder::VERSION
9
+ spec.authors = ['Rodrigo Rosenfeld Rosas']
10
+ spec.email = ['rr.rosas@gmail.com']
11
+
12
+ spec.summary = %q{Build mail messages for simple plain text + HTML multipart messages.}
13
+ spec.description = %q{No monkey patches or advanced usage, low footprint.}
14
+ spec.homepage = 'https://github.com/rosenfeld/simple_mail_builder'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(spec)/})
19
+ end
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.13'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_mail_builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rodrigo Rosenfeld Rosas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-06 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: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: No monkey patches or advanced usage, low footprint.
56
+ email:
57
+ - rr.rosas@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/simple_mail_builder.rb
72
+ - lib/simple_mail_builder/encoder.rb
73
+ - lib/simple_mail_builder/encoder/base64.rb
74
+ - lib/simple_mail_builder/encoder/quote.rb
75
+ - lib/simple_mail_builder/version.rb
76
+ - simple_mail_builder.gemspec
77
+ homepage: https://github.com/rosenfeld/simple_mail_builder
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.6.8
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Build mail messages for simple plain text + HTML multipart messages.
101
+ test_files: []