BLOGTIMES
2012/03/09

mikel/mail を使ってメールから添付ファイルを切り離す

  ruby  programming 
このエントリーをはてなブックマークに追加

久しぶりに Ruby でマルチパートメールの処理をしようと思っていろいろ調べてみたら mikel/mail というライブラリを見つけたのでちょっとおためし。

Mail: An All New Ruby E-mail Library

To date, the main ways to send e-mails from Ruby have been Net::SMTP, TMail, and Rails' ActionMailer (which uses TMail). Now, however, there's a fourth option, the simply named "mail" by Mikel Lindsaar.

インストールは gem install mail で一撃なので楽チン。
基本的な使い方は README.md に書いてあります。
以下、プログラミングメモ。

メールから添付ファイルを切り離す

とりあえず小手調べということで tmail で実装されていた Tmailで受信した添付ファイルをファイル名付きで保存する方法 - Rubyの魔神 - はてな?Rubyグループ を mail を使って書き直してみました。マルチパートでない単純なテキストメールの場合の body を UTF-8 にすることができなくてちょっとハマりましたが、それ以外は素直なライブラリではないでしょうか。

extract-attachments.rb

#!/bin/env ruby # -*- coding: utf-8 -*- # # extract-attachments.rb -- Extracts attachment(s) from the message. # # Usage: ruby extract-attachments.rb mail mail... # # Based on http://ruby.g.hatena.ne.jp/garyo/20071213/1197535597 require 'rubygems' require 'mail' def main idx = 1 ARGV.each do |fname| email = Mail.read(fname) puts "Subject: #{email.subject}" puts "Date: #{email.date}" puts "From: #{email.from}" puts "To: #{email.to}" if !email.text_part && !email.html_part puts email.body.decoded.encode("UTF-8", email.charset) elsif email.text_part puts "text: " + email.text_part.decoded elsif email.html_part puts "html: " + email.html_part.decoded end email.attachments.each do |attachment| filename = attachment.filename filename ||= "#{idx}.#{ext(attachment)}" begin File.open(filename, 'wb', 0644) {|f| f.write attachment.body.decoded } puts "Attachment extracted: #{filename}" rescue Exception => e puts "Unable to extract attachment: #{filename}: #{e.message}" end idx += 1 end end end CTYPE_TO_EXT = { 'image/jpeg' => 'jpeg', 'image/gif' => 'gif', 'image/png' => 'png', 'image/tiff' => 'tiff', 'text/csv' => 'csv', 'application/pdf' => 'pdf', 'application/msword' => 'doc', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx', 'application/vnd.ms-excel' => 'xls', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx', 'application/vnd.ms-powerpoint' => 'ppt', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx', 'application/x-zip-compressed' => 'zip', } def ext( attachment ) CTYPE_TO_EXT[attachment.mime_type] || 'bin' end main

実際に動かしてみる

下記のような eml ファイル*1をプログラムにかけた場合の実行例を載せておきます。

test.eml

Received: (qmail 2116 invoked by uid 89); 9 Mar 2012 14:06:57 +0900 Delivered-To: example.jp-user@example.jp Received: (qmail 2111 invoked by uid 89); 9 Mar 2012 14:06:57 +0900 Received: from softbank000000000000.bbtec.net (HELO ?192.168.123.123?) (user%example.jp@192.168.123.123) by mail.example.jp with (DHE-RSA-AES256-SHA encrypted) SMTP; 9 Mar 2012 14:06:57 +0900 Message-ID: <4F5AE162.4040106@example.jp> Date: Fri, 9 Mar 2012 14:06:42 +0900 From: user <user@example.jp> Organization: cles::blog User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.10) Gecko/20050716 Thunderbird/1.0.6 Mnenhy/0.7.2.0 MIME-Version: 1.0 To: user <user@example.jp> Subject: =?ISO-2022-JP?B?GyRCJUYlOSVIJWEhPCVrGyhC?= Content-Type: multipart/mixed; boundary="------------040409030508060501090009" X-Maildrop-Filter: user This is a multi-part message in MIME format. --------------040409030508060501090009 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit テストメールです -- user@example.jp http://blog.example.jp/ --------------040409030508060501090009 Content-Type: image/png; name="cles.png" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="cles.png" iVBORw0KGgoAAAANSUhEUgAAAFAAAAAPCAIAAAD8q9/YAAAAnUlEQVRIx2NIG2GAAYj/jxiA 5OEzDNRH//939lUOHjTq4ZHsYRcwQOZiyqIpQBPB9DA8I2EKInMx2WgaMc0hqICAh+HuxmQQ w8XjYSIZyCRaKODXTlCcgIdJjWGCHsYVnwQ9TGoMk+lhImMYpziOgCfDw5i6cGUEcjyMNQ8j i+DnEu9hzDyMyz/4I5DSPDxaLY16eDh4eES1pUcUAAB7S69qNlCgQQAAAABJRU5ErkJggg== --------------040409030508060501090009--
$ ./extract-attachments.rb test.eml Subject: テストメール Date: 2012-03-09T14:06:42+09:00 From: ["user@example.jp"] To: ["user@example.jp"] text: テストメールです -- user@example.jp http://blog.example.jp/ Attachment extracted: cles.png
  • *1: 文字コードはJIS(ISO-2022-JP)にしておく必要あり

トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/4820
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form

コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。

OpenID を使ってログインすることができます。

Identity URL: Yahoo! JAPAN IDでログイン