Monkey patch mail to handle character encodings on ruby 1.8
authorTom Hughes <tom@compton.nu>
Mon, 30 Jan 2012 21:36:46 +0000 (21:36 +0000)
committerTom Hughes <tom@compton.nu>
Mon, 30 Jan 2012 21:42:41 +0000 (21:42 +0000)
Gemfile
Gemfile.lock
config/initializers/mail.rb [new file with mode: 0644]

diff --git a/Gemfile b/Gemfile
index 3050d9fa3a91fe54af1cb8089ee5cc7784b963dc..a75a9279a715d1b33b65531ce4d18f582e3ea4dc 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -19,6 +19,9 @@ gem 'open_id_authentication', '>= 1.1.0'
 gem 'validates_email_format_of', '>= 1.5.1'
 gem 'composite_primary_keys', '>= 4.1.2'
 
+# Character conversion support for ruby 1.8
+gem 'iconv', :platforms => :ruby_18
+
 # Load libxml support for XML parsing and generation
 gem 'libxml-ruby', '>= 2.0.5', :require => 'libxml'
 
index 35082453254a9d990182d0c2816876d95c8d5590..23c4297ab52d89f422e101a810f64c6525fcf3c5 100644 (file)
@@ -46,13 +46,14 @@ GEM
     erubis (2.7.0)
     execjs (1.3.0)
       multi_json (~> 1.0)
-    faraday (0.7.5)
-      addressable (~> 2.2.6)
-      multipart-post (~> 1.1.3)
-      rack (>= 1.1.0, < 2)
+    faraday (0.7.6)
+      addressable (~> 2.2)
+      multipart-post (~> 1.1)
+      rack (~> 1.1)
     hike (1.2.1)
     httpclient (2.2.4)
     i18n (0.6.0)
+    iconv (0.1)
     jquery-rails (1.0.19)
       railties (~> 3.0)
       thor (~> 0.14)
@@ -140,7 +141,7 @@ GEM
       polyglot
       polyglot (>= 0.3.1)
     tzinfo (0.3.31)
-    uglifier (1.2.2)
+    uglifier (1.2.3)
       execjs (>= 0.3.0)
       multi_json (>= 1.0.2)
     validates_email_format_of (1.5.3)
@@ -154,6 +155,7 @@ DEPENDENCIES
   composite_primary_keys (>= 4.1.2)
   dynamic_form
   httpclient
+  iconv
   jquery-rails
   libxml-ruby (>= 2.0.5)
   memcache-client
diff --git a/config/initializers/mail.rb b/config/initializers/mail.rb
new file mode 100644 (file)
index 0000000..d448544
--- /dev/null
@@ -0,0 +1,59 @@
+module Mail
+  class Ruby18
+    def Ruby18.b_value_decode(str)
+      match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
+      if match
+        encoding = match[1]
+        str = Ruby18.decode_base64(match[2])
+        require 'iconv'
+        str = Iconv.conv("UTF-8//TRANSLIT//IGNORE", encoding, str)
+      end
+      str
+    end
+
+    def Ruby18.q_value_decode(str)
+      match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
+      if match
+        encoding = match[1]
+        str = Encodings::QuotedPrintable.decode(match[2].gsub(/_/, '=20'))
+        require 'iconv'
+        str = Iconv.conv("UTF-8//TRANSLIT//IGNORE", encoding, str)
+      end
+      str
+    end
+  end
+
+  class Message
+    def decoded_with_text
+      if self.text?
+        decode_body_as_text
+      else
+        decoded_without_text
+      end
+    end
+
+    alias_method_chain :decoded, :text
+
+    def text?
+      has_content_type? ? !!(main_type =~ /^text$/i) : false
+    end
+
+  private
+
+    def decode_body_as_text
+      body_text = body.decoded
+      if charset
+        if RUBY_VERSION < '1.9'
+          require 'iconv'
+          return Iconv.conv("UTF-8//TRANSLIT//IGNORE", charset, body_text)
+        else
+          if encoding = Encoding.find(charset) rescue nil
+            body_text.force_encoding(encoding)
+            return body_text.encode(Encoding::UTF_8)
+          end
+        end
+      end
+      body_text
+    end    
+  end
+end