Using the TMail gem in Rails 2 / Ruby 1.8.7, this was probably how you saved an attachment:
# tmail is a TMail object tmail.attachments.each do |tattch| fn = tattch.original_filename File.open(fn, File::CREAT|File::TRUNC|File::WRONLY,0644) { |f| f.write( tattch.string ) } end
…or perhaps something like this if you’re cautious:
# tmail is a TMail object tmail.attachments.each do |tattch| fn = tattch.original_filename begin File.open(fn, File::CREAT|File::TRUNC|File::WRONLY,0644) { |f| f.write( tattch.string ) } rescue Exception => e logger.error "Unable to save data for #{fn} because #{e.message}" end end
But if you try that in Rails 3 / Ruby 1.9.2 — which uses the new Mail gem — you’ll get a curious little error like this one (where x80 could be many different hex codes, such as xC5 or xC3):
Encoding::UndefinedConversionError Exception: "\x80" from ASCII-8BIT to UTF-8
Your first instinct might be to suspect the Mail gem itself. The problem is, in fact, not Mail’s fault; it is rooted in Ruby 1.9.2’s new string encoding mechanism. Fortunately the fix is dead simple: open the output file in binary mode.
Here is the above code snippet corrected for Rails 3 / Ruby 1.9.2 with the new Mail gem:
# tmail is now a Mail object tmail.attachments.each do |tattch| fn = tattch.filename begin File.open( fn, "w+b", 0644 ) { |f| f.write tattch.body.decoded } rescue Exception => e logger.error "Unable to save data for #{fn} because #{e.message}" end end
For more information about how things changed in Ruby 1.9, consider reading James Gray’s article on Ruby 1.9 string encodings.
Awesome. Thanks for this.
Pingback: ruby gmail undefined method `save_attachments_to’ « Lost Ferry