TMailはメールを簡単に扱うためのクラスライブラリです。
ヘッダはひとつひとつがオブジェクトとして表現され、
ヘッダを「文字列」としてでなく(めんどくさい文法に一切関ることなく)
「オブジェクト」とそのプロパティとして読み書きをすることができます。
また、MIMEマルチパートにも対応しています。
読みこみ時はヘッダに従って本文を分割し、
書きこみ時には適当にバウンダリを設定して再構成します。
一方で、TMailはメール本文の内容には一切関与しません。 文字コードも勝手には変換しませんし、行末コードも変えません。 Base64のデコードもしません。それはライブラリの利用者側で content-* ヘッダあたりを見て判断する必要があります。
簡単に、TMailライブラリを構成するクラス間の関係について書きます。
中心は TMail::Mail クラス(以下、Mail と略)です。 ひとつのメールがひとつのオブジェクトとして表現され、 (たぶんたくさんの)ヘッダフィールドと本文を含んでいます。
「ヘッダフィールド」とはようするに To: や From: のことです。
ひとつのヘッダフィールドがひとつの HeaderField オブジェクトになります。
ヘッダフィールドオブジェクトは Mail の中に 'to' => To ヘッダフィールド
のようなハッシュとして格納されていて、Mail#[] や Mail#fetch でとりだせます。
ちなみに、mail['From'] も mail['FrOm'] も mail['FROM'] も同じヘッダです。
ヘッダはいろいろな種類があるので、それに対応するクラスも いろいろ用意されています。たとえば To: ヘッダは MaddrH クラスで 表現され、Subject: は StringH クラスで表現されます。to_s body inspect などの共通のメソッドのほか、そのクラスに独自のメソッドも たくさんあります。例えば To ヘッダなら addrs というメソッドがあります。 これはそのヘッダで記載されているアドレスの配列を返すメソッドで、 mail['to'].addrs.each {|adr| ... } のようにすれば To のアドレス 全てに対するくりかえしが行なえるわけです。
また、外界とのアクセスの抽象化のために Loader と Port があります。 Loader はメールボックスの抽象表現で、Port はファイルの抽象表現です。
本文は Mail#body で文字列として、Mail#body_port で Port として参照できます。 MIME マルチパートメールでは、ひとつのパートがひとつの Mail として表現され、 その配列が Mail#parts メソッドで得られます。
実際に(少しは)使える例としてサンプルの fromcheck.rb を見てみます。 このスクリプトは、Mh のメールボックスの中にあるメールを調べて、 メールをくれた人を数の多い順に表示するスクリプトです。
require 'tmail/tmail' unless ARGV[0] then puts "usage: fromcheck.rbMhLoader.new からが TMail に独自なコードです。 MhLoader は Mh メールボックスを扱うクラスで、 他に Mbox と Maildir のローダがあります。" exit 1 end names = {} m = TMail::MhLoader.new( ARGV[0] ) m.each_mail do |port| tmail = TMail::Mail.new( port ) n = tmail.from_phrase(nil) || tmail.from if names.key? n then names[n] += 1 else names[n] = 1 end end names.to_a.sort {|a,b| b[1] <=> a[1] }.each do |name,i| puts "#{i} #{name}" end
そのローダのイテレータ each_mail からは、ポートを引数に渡されます。 TMail::Mail オブジェクトはこれを引数に生成します。
そうしたら、あとは好きにいじるだけです。from_phrase は From: ヘッダの"phrase"部分(friendly from などと呼ばれることもあります)を 取得するメソッドです。この値は格納されていないこともあるので、 それがないときはメールアドレスを表示することにします。
Ruby や Perl の達人ならこのくらいは正規表現を使ったりして やっつけられるでしょうが、これほど簡単には書けないでしょう。 この単純さが TMail のいいところです。
前の例はメールから情報をとりだすものでしたが、TMail では 逆にファイルに書き出すことも可能です。Mail のヘッダなど あらゆる属性は上書き可能であり、ファイルに書き戻すとそれが 実際に反映されます。
書き戻しは、最も簡単にはMail#decoded, encoded を使って文字列に 変換し、書きこむことで実現できます。しかしそれでは巨大なメールで困る、 という几帳面(or 堅実)な人は Mail#write_back を使えばテンポラリ バッファの消費を最小限におさえられます(実は decoded なども write_back を使って実装されています)。当然ながら、文字コードや 行端コード、ヘッダの折り返し桁数など細かいパラメータも指定可能です。
TMail では書き戻しの際には必ず全てのヘッダをパースするので 微妙にヘッダが変わることがありますが、意味的な変化はありません。 それどころか、「標準的でない」フォーマットのヘッダも可能な限り 解釈し「標準的な」フォーマットに構成しなおしてくれます。
Copyright (c) 1998-2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>