mail_alternatives_with_attachments 1.0.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,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mail_alternatives_with_attachments.gemspec
4
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,51 @@
1
+ Why?
2
+ ====
3
+
4
+ Spam filters often require that an HTML email also have a Text alternative that is generally the same as the HTML message. This means you need to send an email with a MIME type of `multipart/alternative` containing `text/html` and `text/plain` parts. ActionMailer 3 supports this scenario, but it falls apart when you need to add (inline) attachments to that mix. The property MIME hierarchy for an email like this is:
5
+
6
+ * `multipart/mixed`
7
+ * `multipart/alternative`
8
+ * `multipart/related`
9
+ * `text/html`
10
+ * `image/png` (e.g. for an inline attachment; pdf would be another good example)
11
+ * `text/plain`
12
+ * `application/zip` (e.g for an attachment--not inline)
13
+
14
+ If this seems more complicated then it should be, that's because it is. Thankfully, this gem allows you to create this entire hierarchy without all the hard work.
15
+
16
+ Usage:
17
+ ======
18
+
19
+ Including the `mail_alternatives_with_attachments` gem in your project will patch ActionMailer with the following two methods:
20
+
21
+ * `ActionMailer::Base#prepare_message(headers={})`: This method does exactly what `ActionMailer::Base#mail(headers={})` does; however it doesn't automatically rendering of templates so that we add our own custom message parts.
22
+ * `Mail::Message#alternative_content_types_with_attachment(options, &block)`: This method allows you to conveniently add all of the different parts of complex email with alternatives and attachments.
23
+
24
+ Typically when using ActionMailer 3, you would create a message with the following code:
25
+
26
+ class MyEmailerClass < ActionMailer::Base
27
+ def my_email_method(address)
28
+ mail :to => address,
29
+ :from => "noreply@myemail.com",
30
+ :subject => "My Subject"
31
+ end
32
+ end
33
+
34
+ Using this gem to create an email with both alternatives and attachments you would use the following code:
35
+
36
+ class MyEmailerClass < ActionMailer::Base
37
+ def my_email_method(address, attachment, logo)
38
+ message = prepare_message to: address, subject: "My Subject", :content_type => "multipart/mixed"
39
+
40
+ message.alternative_content_types_with_attachment(
41
+ :text => render_to_string(:template => "my_template.text"),
42
+ :html => render_to_string("my_template.html")
43
+ ) do |inline_attachments|
44
+ inline_attachments.inline['logo.png'] = logo
45
+ end
46
+
47
+ attachments['attachment.pdf'] = attachment
48
+
49
+ message
50
+ end
51
+ end
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ require "mail_alternatives_with_attachments/version"
2
+
3
+ module MailAlternativesWithAttachments
4
+ require "mail_alternatives_with_attachments/action_mailer_prepare_message"
5
+ require "mail_alternatives_with_attachments/mail_message_alternative_content_types_with_attachment"
6
+ end
@@ -0,0 +1,49 @@
1
+ module MailAlternativesWithAttachments::ActionMailerPrepareMessage
2
+
3
+ # Copied directly from ActionMailer::Base#mail but without
4
+ # the automatic rendering of templates.
5
+ def prepare_message(headers={})
6
+ # Guard flag to prevent both the old and the new API from firing
7
+ # Should be removed when old API is removed
8
+ @mail_was_called = true
9
+ m = @_message
10
+
11
+ # At the beginning, do not consider class default for parts order neither content_type
12
+ content_type = headers[:content_type]
13
+ parts_order = headers[:parts_order]
14
+
15
+ # Call all the procs (if any)
16
+ default_values = self.class.default.merge(self.class.default) do |k,v|
17
+ v.respond_to?(:call) ? v.bind(self).call : v
18
+ end
19
+
20
+ # Handle defaults
21
+ headers = headers.reverse_merge(default_values)
22
+ headers[:subject] ||= default_i18n_subject
23
+
24
+ # Apply charset at the beginning so all fields are properly quoted
25
+ m.charset = charset = headers[:charset]
26
+
27
+ # Set configure delivery behavior
28
+ wrap_delivery_behavior!(headers.delete(:delivery_method))
29
+
30
+ # Assign all headers except parts_order, content_type and body
31
+ assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
32
+ assignable.each { |k, v| m[k] = v }
33
+
34
+ # Setup content type, reapply charset and handle parts order
35
+ m.content_type = set_content_type(m, content_type, headers[:content_type])
36
+ m.charset = charset
37
+
38
+ if m.multipart?
39
+ parts_order ||= headers[:parts_order]
40
+ m.body.set_sort_order(parts_order)
41
+ m.body.sort_parts!
42
+ end
43
+
44
+ m
45
+ end
46
+
47
+ end
48
+
49
+ ActionMailer::Base.send(:include, MailAlternativesWithAttachments::ActionMailerPrepareMessage)
@@ -0,0 +1,32 @@
1
+ module MailAlternativesWithAttachments::MailMessageAlternativeWithAttachment
2
+
3
+ def alternative_content_types_with_attachment(options, &block)
4
+ text_alternative = Mail::Part.new do
5
+ content_type "text/plain; charset=UTF-8"
6
+ body options[:text]
7
+ end
8
+
9
+ html_alternative = Mail::Part.new do
10
+ content_type 'text/html; charset=UTF-8'
11
+ body options[:html]
12
+ end
13
+
14
+ html_container = Mail::Part.new { content_type 'multipart/related' }
15
+ html_container.add_part html_alternative
16
+
17
+ alternative_bodies = Mail::Part.new { content_type 'multipart/alternative' }
18
+ alternative_bodies.add_part text_alternative
19
+ alternative_bodies.add_part html_container
20
+
21
+ add_part alternative_bodies
22
+
23
+ if block_given?
24
+ yield(html_container.attachments)
25
+ end
26
+
27
+ return self
28
+ end
29
+
30
+ end
31
+
32
+ Mail::Message.send(:include, MailAlternativesWithAttachments::MailMessageAlternativeWithAttachment)
@@ -0,0 +1,3 @@
1
+ module MailAlternativesWithAttachments
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mail_alternatives_with_attachments/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mail_alternatives_with_attachments"
7
+ s.version = MailAlternativesWithAttachments::VERSION
8
+ s.authors = ["James Coleman"]
9
+ s.email = ["jtc331@gmail.com"]
10
+ s.homepage = "https://github.com/jcoleman/mail_alternatives_with_attachments"
11
+ s.summary = %q{This gem makes it easy to send multipart alternative emails from ActionMailer 3}
12
+ s.description = %q{ActionMailer 3 makes it much easier to send emails, but there is one case it doesn't handle well.\
13
+ Specifically, it is difficult to send a message that has the proper MIME hiearchy for an email with both HTML and text alternatives\
14
+ that also includes attachments. This gem solves that need.}
15
+
16
+ s.rubyforge_project = "mail_alternatives_with_attachments"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ # specify any dependencies here; for example:
24
+ # s.add_development_dependency "rspec"
25
+ # s.add_runtime_dependency "rest-client"
26
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mail_alternatives_with_attachments
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Coleman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-24 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ! "ActionMailer 3 makes it much easier to send emails, but there is one
15
+ case it doesn't handle well.\\\n Specifically, it is difficult to send a message
16
+ that has the proper MIME hiearchy for an email with both HTML and text alternatives\\\n
17
+ that also includes attachments. This gem solves that need."
18
+ email:
19
+ - jtc331@gmail.com
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - .gitignore
25
+ - Gemfile
26
+ - README.markdown
27
+ - Rakefile
28
+ - lib/mail_alternatives_with_attachments.rb
29
+ - lib/mail_alternatives_with_attachments/action_mailer_prepare_message.rb
30
+ - lib/mail_alternatives_with_attachments/mail_message_alternative_content_types_with_attachment.rb
31
+ - lib/mail_alternatives_with_attachments/version.rb
32
+ - mail_alternatives_with_attachments.gemspec
33
+ homepage: https://github.com/jcoleman/mail_alternatives_with_attachments
34
+ licenses: []
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project: mail_alternatives_with_attachments
53
+ rubygems_version: 1.8.10
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: This gem makes it easy to send multipart alternative emails from ActionMailer
57
+ 3
58
+ test_files: []