TMailの添付ファイルの名前の取り出しとActionMailerの添付ファイルの名前付け
MIME云々を読み,rdocを読み,やっとできたorz
サンプルに使ったメールは,http://www.mew.org/Newsletters/3.htmlの一番下のマルチパートメール.コピペしてmultipart_mail.txtって名前で保存して,色々検証してみました.
TMailの添付ファイルの名前取り出し
はじめは,http://i.loveruby.net/ja/projects/tmail/doc/mail.htmlに書いてあった,
# example mail.disposition_param('filename')
でできるか試してみたものの,まぁ結果できなかった(nilが返ってきた)わけで.
何とかしてこのcontent-dispositionを参照できないものかとウロウロしてて,何気にrdocのActionMailerのTMail::Mail#has_attachment?がどうなっているのか気になったので見てみると,
def has_attachments? multipart? && parts.any? { |part| attachment?(part) } end
ってなってたわけです.次にこのTMail::Mail#attachment?を見る.
def attachment?(part) (part['content-disposition'] && part['content-disposition'].disposition == "attachment") || part.header['content-type'].main_type != "text" end
ってなっていた.partの値って,ハッシュで参照できるみたい.結局,ファイル名を取り出す作業は,こうすれば良い.
require 'tmail' mail = TMail::Mail.load('multipart_mail.txt') mail.parts.each do |part| if part['content-disposition'] # えせActionMailer版TMail::Mail#attachment? puts part['content-disposition']['filename'] end end
こうすればTMailでの添付ファイルの名前の取り出しは,辛うじてできる:p
ところで,この辺の処理は,ActionMailerで言うとこのattachmentの名前の取り出し("の"が多い)には全くと言っていいほど関係がなかったりする.何故なら,partとattachmentが違うから.
ActionMailerにおける添付ファイルの名前の取り出し
partとattachment比較.
require 'rubygems' require 'action_mailer' email = TMail::Mail.load('multipart_mail.txt') # ここからirbと考えてください > email.parts # part => [#<TMail::Mail port=#<TMail::StringPort:id=0x105d92a> bodyport=nil>, #<TMail::Mail port=#<TMail::StringPort:id=0x105d718> bodyport=#<TMail::StringPort:id=0x105bd0a>>] > email.attachments # attachment => [#<TMail::Attachment:0x20b753c>]
と,portがTMail::Mailクラスなのに対し,attachmentはTMail::Attachmentクラスである事がわかります.そこでrdocのaction_mailer,TMail::Attachmentを見てみると,Attributesに
- content_type
- originail_filename
とあります.このoriginal_filenameさえあれば,もう添付ファイルの名前問題は解決.
> email.attachments[0].original_filename => "wash.gif"
と,楽々参照できます.だから,Ride on Railsや色んな"ActionMailerいろは"に載っていた,「受信して添付ファイルを取り出しDBに格納」は,こうすると良いかも(動作確認はしてません).
class Mailman < ActionMailer::Base … def recieve(email) if email.has_attachments? email.attachments.each do |attachment| Attachment.create( :file => attachment.read :filename => attachment.original_filename :content_type => attachment.content_type # 他にも,添付されてたメールに関する情報を格納する ) end end end end
Content-Typeがimageならimgタグでブラウザに表示したり,textならpreタグで表示したりできるかも.docやpdf(そんなContent-Typeがあるのか?)ならダウンロード出来るようにしてみたり….結構色々できそうです.