From 38591db14ff43540cfc039d8fa9aa0001a8de7b8 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 18 Mar 2005 16:03:29 +0000 Subject: [PATCH] Added better quoting and attachments handling in anticipation for ActionMailer::Receiver framework git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@916 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../action_mailer/vendor/tmail/attachments.rb | 25 ++++++ .../lib/action_mailer/vendor/tmail/mail.rb | 2 + .../lib/action_mailer/vendor/tmail/quoting.rb | 81 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 actionmailer/lib/action_mailer/vendor/tmail/attachments.rb create mode 100644 actionmailer/lib/action_mailer/vendor/tmail/quoting.rb diff --git a/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb b/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb new file mode 100644 index 0000000000..fb6629d67e --- /dev/null +++ b/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb @@ -0,0 +1,25 @@ +require 'stringio' + +module TMail + class Attachment < StringIO + attr_accessor :original_filename, :content_type + end + + class Mail + def has_attachments? + multipart? && parts.any? { |part| part.header["content-type"].main_type != "text" } + end + + def attachments + if multipart? + parts.collect { |part| + if part.header["content-type"].main_type != "text" + attachment = Attachment.new(Base64.decode64(part.body)) + attachment.original_filename = part.header["content-type"].params["name"].strip.dup + attachment + end + }.compact + end + end + end +end \ No newline at end of file diff --git a/actionmailer/lib/action_mailer/vendor/tmail/mail.rb b/actionmailer/lib/action_mailer/vendor/tmail/mail.rb index bfea9b6db4..85a80fd29c 100755 --- a/actionmailer/lib/action_mailer/vendor/tmail/mail.rb +++ b/actionmailer/lib/action_mailer/vendor/tmail/mail.rb @@ -14,6 +14,8 @@ require 'tmail/header' require 'tmail/port' require 'tmail/config' require 'tmail/utils' +require 'tmail/attachments' +require 'tmail/quoting' require 'socket' diff --git a/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb b/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb new file mode 100644 index 0000000000..1a882934c9 --- /dev/null +++ b/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb @@ -0,0 +1,81 @@ +require 'iconv' +require 'base64' + +module TMail + class Mail + def unquoted_subject(to_charset = 'utf-8') + Unquoter.unquote_and_convert_to(subject, to_charset) + end + + def unquoted_body(to_charset = 'utf-8') + Unquoter.unquote_and_convert_to(body, to_charset, header["content-type"]["charset"]) + end + + def unquoted_body_with_all_parts(to_charset = 'utf-9', &block) + attachment_presenter = block || Proc.new { |file_name| "Attachment: #{file_name}\n" } + + if multipart? + parts.collect { |part| + part.header["content-type"].main_type == "text" ? + part.unquoted_body : attachment_presenter.call(part.header["content-type"].params["name"]) + }.join + else + unquoted_body + end + end + end + + class Unquoter + class << self + def unquote_and_convert_to(text, to_charset, from_charset = "iso-8859-1") + if text =~ /^=\?(.*?)\?(.)\?(.*)\?=$/ + from_charset = $1 + quoting_method = $2 + text = $3 + case quoting_method + when "Q" then + unquote_quoted_printable_and_convert_to(text, from_charset, to_charset) + when "B" then + unquote_base64_and_convert_to(text, from_charset, to_charset) + else + raise "unknown quoting method #{quoting_method.inspect}" + end + else + unquote_quoted_printable_and_convert_to(text, from_charset, to_charset) + end + end + + def unquote_quoted_printable_and_convert_to(text, from, to) + Iconv.iconv(to, from, text.gsub(/_/," ").unpack("M*").first).first + end + + def unquote_base64_and_convert_to(text, from, to) + Iconv.iconv(to, from, Base64.decode64(text)).first + end + end + end +end + +if __FILE__ == $0 + require 'test/unit' + + class TC_Unquoter < Test::Unit::TestCase + def test_unquote_quoted_printable + a ="=?ISO-8859-1?Q?[166417]_Bekr=E6ftelse_fra_Rejsefeber?=" + b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') + assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + end + + def test_unquote_base64 + a ="=?ISO-8859-1?B?WzE2NjQxN10gQmVrcuZmdGVsc2UgZnJhIFJlanNlZmViZXI=?=" + b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') + assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + end + + def test_unquote_without_charset + a ="[166417]_Bekr=E6ftelse_fra_Rejsefeber" + b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') + assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + end + end +end