mail_alternatives_with_attachments 1.0.0

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