Skip to content
Browse files

Added sorting of parts, default is text/plain, then text/enriched and…

… text/html. Access through Body#set_sort_order and Body#sort_parts! (called from Body#encode automatically)
  • Loading branch information...
1 parent fc65df3 commit fbafc494a59734b0704760b6a8e4164df40aedca @mikel committed Dec 28, 2009
Showing with 104 additions and 8 deletions.
  1. +5 −0 CHANGELOG.rdoc
  2. +1 −1 Rakefile
  3. +22 −1 lib/mail/body.rb
  4. +4 −2 lib/mail/message.rb
  5. +1 −1 lib/mail/version.rb
  6. +68 −0 spec/mail/body_spec.rb
  7. +3 −3 spec/mail/message_spec.rb
View
5 CHANGELOG.rdoc
@@ -1,3 +1,8 @@
+== Mon 28 Dec 2009 01:21:52 UTC Mikel Lindsaar <raasdnil@gmail.com>
+
+* Added sorting of parts, default is text/plain, then text/enriched and text/html. Access through Body#set_sort_order and Body#sort_parts! (called from Body#encode automatically)
+* Version bump to 1.4.2
+
== Sun Dec 27 10:38:24 UTC 2009 Mikel Lindsaar <raasdnil@gmail.com>
* Updating treetop and mail to initialize uninitialized instance variables to
View
2 Rakefile
@@ -12,7 +12,7 @@ require 'bundler'
spec = Gem::Specification.new do |s|
s.name = "mail"
- s.version = "1.4.1"
+ s.version = "1.4.2"
s.author = "Mike Lindsaar"
s.email = "raasdnil@gmail.com"
s.homepage = "http://github.com/mikel/mail"
View
23 lib/mail/body.rb
@@ -30,6 +30,7 @@ def initialize(string = '')
@boundary = nil
@preamble = nil
@epilogue = nil
+ @part_sort_order = [ "text/plain", "text/enriched", "text/html" ]
@parts = []
if string.blank?
@raw_source = ''
@@ -89,7 +90,26 @@ def =~(regexp)
def match(regexp)
self.decoded.match(regexp)
end
-
+
+ # Allows you to set the sort order of the parts, overriding the default sort order.
+ # Defaults to 'text/plain', then 'text/enriched', then 'text/html' with any other content
+ # type coming after.
+ def set_sort_order(order)
+ @part_sort_order = order
+ end
+
+ # Allows you to sort the parts according to the default sort order, or the sort order you
+ # set with :set_sort_order.
+ #
+ # sort_parts! is also called from :encode, so there is no need for you to call this explicitly
+ def sort_parts!
+ order = @part_sort_order
+ @parts = @parts.sort do |a, b|
+ a_order = order.index(a.content_type.string.downcase) || 1000
+ b_order = order.index(b.content_type.string.downcase) || 1000
+ a_order <=> b_order
+ end
+ end
# Returns the raw source that the body was initialized with, without
# any tampering
@@ -101,6 +121,7 @@ def raw_source
# raw source. Need to implement
def encoded
if multipart?
+ self.sort_parts!
encoded_parts = parts.map { |p| p.encoded }
([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
else
View
6 lib/mail/message.rb
@@ -486,7 +486,8 @@ def add_charset
if body.only_us_ascii?
content_type.parameters['charset'] = 'US-ASCII'
else
- STDERR.puts("Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.")
+ warning = "Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.\nCalled from:\n#{caller.join("\n")}"
+ STDERR.puts(warning)
content_type.parameters['charset'] = 'UTF-8'
end
end
@@ -498,7 +499,8 @@ def add_transfer_encoding
if body.only_us_ascii?
header['Content-Transfer-Encoding'] = '7bit'
else
- STDERR.puts("Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect.")
+ warning = "Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect.\nCalled from:\n#{caller.join("\n")}"
+ STDERR.puts(warning)
header['Content-Transfer-Encoding'] = '8bit'
end
end
View
2 lib/mail/version.rb
@@ -3,7 +3,7 @@ module Mail
module VERSION
MAJOR = 1
MINOR = 4
- TINY = 1
+ TINY = 2
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
68 spec/mail/body_spec.rb
@@ -212,6 +212,74 @@
body.parts.length.should == 1
body.should be_multipart
end
+
+ it "should allow you to sort the parts" do
+ body = Mail::Body.new('')
+ body << Mail::Part.new("content-type: text/html\r\nsubject: HTML")
+ body << Mail::Part.new("content-type: text/plain\r\nsubject: Plain Text")
+ body << Mail::Part.new("content-type: text/enriched\r\nsubject: Enriched")
+ body.parts.length.should == 3
+ body.should be_multipart
+ body.sort_parts!
+ body.parts[0].content_type.value.should == "text/plain"
+ body.parts[1].content_type.value.should == "text/enriched"
+ body.parts[2].content_type.value.should == "text/html"
+ end
+
+ it "should allow you to sort the parts with an arbitrary sort order" do
+ body = Mail::Body.new('')
+ body.set_sort_order([ "text/plain", "text/html", "text/enriched" ])
+ body << Mail::Part.new("content-type: text/html\r\nsubject: HTML")
+ body << Mail::Part.new("content-type: text/plain\r\nsubject: Plain Text")
+ body << Mail::Part.new("content-type: text/enriched\r\nsubject: Enriched")
+ body.parts.length.should == 3
+ body.should be_multipart
+ body.sort_parts!
+ body.parts[0].content_type.value.should == "text/plain"
+ body.parts[1].content_type.value.should == "text/html"
+ body.parts[2].content_type.value.should == "text/enriched"
+ end
+
+ it "should allow you to sort the parts with an arbitrary sort order" do
+ body = Mail::Body.new('')
+ body.set_sort_order(["application/x-yaml", "text/plain"])
+ body << Mail::Part.new("content-type: text/plain\r\nsubject: HTML")
+ body << Mail::Part.new("content-type: text/html\r\nsubject: Plain Text")
+ body << Mail::Part.new("content-type: application/x-yaml\r\nsubject: Enriched")
+ body.parts.length.should == 3
+ body.should be_multipart
+ body.sort_parts!
+ body.parts[0].content_type.value.should == "application/x-yaml"
+ body.parts[1].content_type.value.should == "text/plain"
+ body.parts[2].content_type.value.should == "text/html"
+ end
+
+ it "should sort the parts on encode" do
+ body = Mail::Body.new('')
+ body << Mail::Part.new("content-type: text/html\r\nsubject: HTML")
+ body << Mail::Part.new("content-type: text/plain\r\nsubject: Plain Text")
+ body << Mail::Part.new("content-type: text/enriched\r\nsubject: Enriched")
+ body.parts.length.should == 3
+ body.should be_multipart
+ body.encoded
+ body.parts[0].content_type.value.should == "text/plain"
+ body.parts[1].content_type.value.should == "text/enriched"
+ body.parts[2].content_type.value.should == "text/html"
+ end
+
+ it "should put the part types it doesn't know about at the end" do
+ body = Mail::Body.new('')
+ body << Mail::Part.new("content-type: text/html\r\nsubject: HTML")
+ body << Mail::Part.new("content-type: text/plain\r\nsubject: Plain Text")
+ body << Mail::Part.new("content-type: image/jpeg\r\n")
+ body.parts.length.should == 3
+ body.should be_multipart
+ body.encoded
+ body.parts[0].content_type.value.should == "text/plain"
+ body.parts[1].content_type.value.should == "text/html"
+ body.parts[2].content_type.value.should == "image/jpeg"
+ end
+
end
describe "matching" do
View
6 spec/mail/message_spec.rb
@@ -1410,7 +1410,7 @@ def basic_email
mail = Mail.new
mail.body = body
mail.content_transfer_encoding = "8bit"
- STDERR.should_receive(:puts).with("Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.")
+ STDERR.should_receive(:puts).with(/Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect./m)
mail.to_s =~ %r{Content-Type: text/plain; charset=UTF-8}
end
@@ -1420,7 +1420,7 @@ def basic_email
mail.body = body
mail.content_type = "text/plain"
mail.content_transfer_encoding = "8bit"
- STDERR.should_receive(:puts).with("Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.")
+ STDERR.should_receive(:puts).with(/Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect./m)
mail.to_s =~ %r{Content-Type: text/plain; charset=UTF-8}
end
@@ -1479,7 +1479,7 @@ def basic_email
mail.content_type = "text/plain; charset=utf-8"
mail.should be_has_content_type
mail.should be_has_charset
- STDERR.should_receive(:puts).with("Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect.")
+ STDERR.should_receive(:puts).with(/Non US-ASCII detected and no content-transfer-encoding defined.\nDefaulting to 8bit, set your own if this is incorrect./m)
mail.to_s =~ %r{Content-Transfer-Encoding: 8bit}
end

0 comments on commit fbafc49

Please sign in to comment.
Something went wrong with that request. Please try again.