七転び八起きブログ

MIME::Toolsドキュメント私家版日本語訳

2005年01月14日   :: CGI

MIME::Toolsの理解がどうにもいい加減な気がするので、cpanのドキュメントを訳してみました。私家版なので、翻訳ミスなどあるかと思います。もしありましたら、コメントお待ちし取ります('A`)

しかし英語が出来ないことが年を経るごとに弱点に…。こないだ見たシュワンツのライディングスクールのDVDも字幕無かったら完全にアウトでした。何か強烈なモチベーションを得られそうなものを探さなければ。

原文はMIME-tools 5.503(cpanが最近重いのでこっち) また、So you want to make a Mime Parser ...も役に立つかと思いますのでクリップ。

しかし基本的に好きな分野ではないせいか、コードを書いているとすぐに飽きます。Blog Hacksの作者の人たちとか、あれですかね、絵描きが、絵さえ描いていれば他に何もいらないと思うような、そういう感じなんでしょうか。うぅむ。

名前

MIME-tools

構文

MIME形式のメッセージを分析して、指定したディレクトリにMIMEコンポーネントを出力するという基本的なコードをいくつか書きます。

use MIME::Parser;
###パーサを作り、オプションをいくつか設定する。
my $parser = new MIME::Parser; $parser->output_under("$ENV{HOME}/mimemail");

### パースして入力
$entity = $parser->parse(\*STDIN) or die "parse failed\n";

### トップレベルのエンティティをチラッと見る。
$entity->dump_skeleton;

続いて、3つのパートを含んだMIME形式のメッセージを組み上げて、さらにそれを送信するコードを書きます。

use MIME::Entity;

###トップレベルの要素を作り、メールのヘッダーをセットする。
$top = MIME::Entity->build(Type =>"multipart/mixed",
From => "me\@myhost.com",
To => "you\@yourhost.com",
Subject => "Hello, nurse!");

### パート1 単純なテキスト
$top->attach(Path=>"./testin/short.txt");

### パート2: GIF画像
$top->attach(Path => "./docs/mime-sm.gif",
Type => "image/gif",
Encoding => "base64");

### パート3 いくつかの一般的な文書
$top->attach(Data=>$message);

### 送るぞ
open MAIL, "| /usr/lib/sendmail -t -oi -oem" or die "open: $!";
$top->print(\*MAIL);
close MAIL;

MIME::Toolsの各ページを見れば、もっと色々スクリプトの例が載っています。

記述

MIME::ToolsはPerl5のコレクションです。

これは、シングルパートないしマルチパート(ネストしている場合もある)のMIMEメッセージを分析したり、デコードしたり、生成する為のモジュールです。
(そうだよ少年、これは気味でもGIF画像を添付したメールを遅れるってことだよ。)

必要条件

MIME::Toolsを使うには、システムに以下の物が必要です。

File::Path
File::Spec
IPC::Open2 (オプション)
IO::Scalar, ... from the IO-stringy distribution
MIME::Base64
MIME::QuotedPrint
Net::SMTP
Mail::Internet, ... from the MailTools distribution.

これらの必須モジュールが入っているかどうか、また、そのバージョンがいくつなのかは、お手持ちのシステムのMalefile.PL等をご覧下さい。

クイックツアー

クラスの概観

一般的に直接扱うであろうクラスの概観はこんな感じです。


    (START HERE)            results() .-----------------.
          \                 .-------->| MIME::          |
           .-----------.   /          | Parser::Results |
           | MIME::    |--'           `-----------------'
           | Parser    |--.           .-----------------.
           `-----------'   \ filer()  | MIME::          |
              | parse()     `-------->| Parser::Filer   |
              | gives you             `-----------------'
              | a...                                  | output_path() 
              |                                       | determines
              |                                       | path() of...
              |    head()       .--------.            |
              |    returns...   | MIME:: | get()      |
              V       .-------->| Head   | etc...     |
           .--------./          `--------'            |
     .---> | MIME:: |                                 |
     `-----| Entity |           .--------.            |
   parts() `--------'\          | MIME:: |           /
   returns            `-------->| Body   |<---------'
   sub-entities    bodyhandle() `--------'
   (if any)        returns...       | open()
                                    | returns...
                                    |
                                    V
                                .--------. read()
                                | IO::   | getline()
                                | Handle | print()
                                `--------' etc...

図解すると、こういう感じで構文を解析しているのです。

"Parser"はMIMEストリームを解析します。
ParserはMIME::のインスタンスです。
これをファイルハンドルの様に、入力ストリームに持っていくことで、そのメッセージを解析できます。
解析が成功裏に終われば、MIMEエンティティが返されます。
解析されたメッセージは、エンティティとして表現されます。
エンティティとは、Mail::Internetのサブクラスである、MIME:Entity:のインスタンスです。
エンティティは、Content-typeやsenderやsubjectline等のメッセージヘッダーの情報を持っています。
エンティティの"body"部分は、メッセージデータの場所を知っています。
そのメッセージデータを読み書きするために、"open"することが出来ます。そうすることで入出力のハンドル( I/O handle )を持ってくることができるのです。
"body"を開いて、入出力ハンドル( I/O handle )を得て、メッセージデータを読み書きできます。
このハンドルは、IO::と基本的には同じです。ハンドルとファイルハンドル……これはどんなクラスでもありうるものです。それが、小さくて、基礎となっているデータソースへの標準的な読み書きの手順をサポートしている限りは。

2つのパートを含んでいる典型的なマルチパートのメッセージ(グリーティングメッセージとGIF画像)は、MIME::Entityのツリーになっています。それぞれのパーツもそれぞれMIME::Headを持っています。こんな感じに。


    .--------.
    | MIME:: | Content-type: multipart/mixed
    | Entity | Subject: Happy Samhaine!
    `--------'
         |
         `----.
        parts |
              |   .--------.
              |---| MIME:: | Content-type: text/plain; charset=us-ascii
              |   | Entity | Content-transfer-encoding: 7bit
              |   `--------'
              |   .--------.
              |---| MIME:: | Content-type: image/gif
                  | Entity | Content-transfer-encoding: base64
                  `--------' Content-disposition: inline;
                               filename="hs.gif"

メッセージの構文解析

まずはMIME::Parserインスタンスを作り、どこに抽出したファイルを置くかや、ファイルの命名ルールなどのパラメータを決めるところから解析は始まります。

そのインスタンスを、MIMEメッセージが待っている、読み取り可能なファイルハンドルに持って行きます。それが上手くいくと、Mail:Internetのサブクラスである、MIME::Entityを得ることが出来ます。これは以下のものを内に持っています。

  • MIMEのヘッダーのデータを持っているMIME::Head。これはMIME::Headerのサブクラスです。
  • メッセージの本文の場所を知っているMIME::Body。あなたは、これを"open"して読み取りることができます。データへのファイルハンドルをくれるのです。これはファイルハンドルと同様のオブジェクトです。そして、IO::Handleインターフェイスのサブクラスである限りどんなクラスでもあり売ります。

もし元のメッセージデータがマルチパートだったら、MIME::Entityオブジェクトは、空ではない"parts"のリストを持っています。それはそれぞれMIME::Entityを持っています(それはさらにネスとしてるかもしれません)。

内部では、パーサ(MIME::Parser)は、必要なときはMIME::Decorderインスタンスに、エンコードされたデータをデコードさせます。MIME::Decorderはbase64等のサポートしているエンコーディングから、デコード可能なインスタンスへのマッピングをします。このマッピングはnewやexperimentメソッドで変更を加えることが出来ます。また、それ自体でデコーダとして使うことが出来ます。

メッセージを組み上げる

メッセージの組み上げは、全てMIME::Entityを通じて行います。シングルパートのメッセージなら、MIME::Entity/buildコンストラクタで簡単に作ることが出来ます。

マルチパートのメッセージなら、まず MIME::Entity::build()メソッドトップレベルのマルチパートを作ります。そして MIME::Entity::attach() でパーツをくっつけていきます。
  ※注意:私たちが「メールと添付したGIF画像」と思っているものは、実際は2つのパートを含むマルチパートメッセージです。一つ目はテキスト、2つ目はGIF画像です。

MIMEエンティティを作っているとき、二つの重要な情報を与えてあげないといけません。 content type と content transfer encodingです。これは直接にファイルのタイプを決めます。例えば、 HTML file なら text/htmlです。もう一つの、 encodingは、しかしながらトリッキーです。例えば、7bit-compliantなHTMLもあれば、非常に長くて、信頼性を得るために quoted-printableで送られないとまずいものもあります。

メールを送る

MIME::EntityはMail::Internetを継承していますので、それを使ってメールを送ることが出来ます。例えば

$entity->smtpsend;

エンコードとデコードのサポート

MIME::Decorderクラスは同様にエンコードすることもできます。これは、MIME::Entityを出力するときに行われます。全てのスタンダードなエンコードがサポートされています(詳細に関してはをMIME入門書をご覧下さい)


    Encoding:        | Normally used when message contents are:
    -------------------------------------------------------------------
    7bit             | 7-bit data with under 1000 chars/line, or multipart.
    8bit             | 8-bit data with under 1000 chars/line.
    binary           | 8-bit data with some long lines (or no line breaks).
    quoted-printable | Text files with some 8-bit chars (e.g., Latin-1 text).
    base64           | Binary files.

あなたが与えられた文書に対して、どのエンコーディングを選ぶかは、主に(1)あなたが文書の内容(テキストなのかバイナリなのかとか)について何を知っているか、(2)7ビット通信を行うインターネットでの電子メール送受信において、信頼できるメッセージを必要とするか、次第です。

一般的には、 quoted-printable で base64 なものだけが、保障できる信頼性のある送受信データです。他の三つ、まず no-encodingはただ単にデータを送ります。そのデータが1000行未満の7ビットASCIIであり、マルチパート境界でコンフリクトを起こしていない限りにおいて、信頼できます。

私は、 content-type と encodingを。ファイルパスから自動的に推定できるように作ったつもりですが、問題もあるようです…少なくともMail::capは…。

メッセージのロギング

MIME::Toolsは様々な外部からの入力を扱う、複雑なツールキットです。ロギングは、裏で本当なにがおこなわれているかを知る助けになります。MIME::Tools自身で記録しているメッセージがいくつかあります。

Debug Messages
STDERRに直接、 "MIME-tools :debug "という接頭辞をつけて出力します。あなたがDebuggingするように設定しない限り、ログは出力されません。
 
Warning messages
異例の事態になったときに、標準のPerlがwarn()で出すものと同じメカニズムで記録されます。 $^Wが真で、MIME::Toolsがquietに設定されていなければ記録されます。
Error Messages
何かが失敗したときに、標準のPerlがwarn()で出すものと同じメカニズムで記録されます。 $^Wが真で、MIME::Toolsがquietに設定されていなければ記録されます。
Usage messages
上の”典型的な”ものとは違って、データ処理や使い方の警告です。あまり良くない使い方や怪しげな呼び出しを開発者に警告します。$^Wが真で、MIME::Toolsがquietに設定されていなければ記録されます。

MIME::Parser(ないし内部のヘルパークラス)が上記のようなメッセージを伝えたいとき、上の様な関数が呼び出される前に、即座にMIME::Parser::Resultオブジェクトが呼び出されます。つまり、各Parserはそれぞれ独自にトレースログを持っているということです。

 

ツールキットを設定する

debugging
デバッグのオンオフを設定します。デフォルトはオフです。 (例 : MIME::Tools->debugging(1); )
quiet
warningとerrorメッセージの報告をオンオフします。デフォルトはオンです。 (例 :  MIME::Tools->quiet(1); )
version
MIME::Toolsのバージョンを返します。(例 :  print MIME::Tools->version, "\n";  )

THINGS YOU SHOULD DO

(省略)

THINGS I DO THAT YOU SHOULD KNOW ABOUT

(省略)

 

MIME入門書

MIMEを解析しなければいけないけれど、詳しいことが良く分からない…大丈夫です。

用語集

ここにあるのは、RFC-1521に適合した専門用語についての定義です。それぞれは同等のMIMEモジュールを携えています…。

atattchment
"atattchment"マルチパートに関して、一般に広まっている俗語です。「これが前に約束してた画像だよ」みたいなメッセージは、これには含まれません。システム上は、単なるトップレベルのエンティティの下にあるMIME:Entityです。恐らく、partsの中の一つになっています。
body
エンティティの"body"とは、ヘッダーと、実際のいわゆる”メッセージ”を含む部分です。例えば、GIF画像の添付書類があるなら、そのGIFファイルのbodyは、 base64によってコード化されたGIFファイルそれ自体です。bodyはMIME::Bodyインスタンスによってあらわされます。bodyhandle()メソッドを使って実際のメール本文を得ることが出来ます。
body parts
マルチパートのエンティティのパートの一つなので、"body parts"はまた、bodyとheaderを持ちます。なのでこれで"bodyのbody"というということの意味が分かりますね。bodyはエンティティとほぼ同義です。もちろん、MIME::Entityインスタンスです。
entity
エンティティは、メッセージ部分か、body partsのどちらかを意味しています。すべてのエンティティにはheaderとbodyがあります。エンティティはMIME::Entityで表されます。
エンティティからheader(MIME::Header)とbody(MIME::Body)を得るメソッドがあります。
header
MIMEメッセージの一番上にあるものです。これは "Content-type", "Content-transfer-encoding",などを含んでいます。全てのMIMEエンティティはMIME::Headerで表されるヘッダーを持っています。headメソッドで、エンティティからMIME::Headerを得ることが出来ます。
message
一般的に、messageはネットワークで伝達されている、完全に(ないしトップレベルが)テキストであるものを意味します。
現在、"messages"をきちんと明白に定義するパッケージは、MIME::にはありません。messageとは、ファイルやファイルハンドルから読まれうるデータのストリームです。あなたは、MIME::Parserで返されたMME::Entityを、messageの全てであるとして扱えます。

Content-types

これは、通常どんな形式のデータがMIMEメッセージとして示されるかを、 majortype/minortype と言う感じで記述したものです。主要なものは以下の様になっています。より包括的なリストは、RFC-2046で見つけることが出来るかもしれません。

application
他のカテゴリーにはまらないデータで、特にアプリケーションで処理されるもの。
audio
オーディオ。
image
グラフィックスデータ。
message
通常のメッセージ、メールまたはMIMEメッセージ 。
multipart
他のメッセージを含むメッセージ 。
text
人が読むことになっている、文のデータ。
video
ビデオかビデオ+オーディオデータ。

Content transfer encodings

これは、メッセージのbodyが安全な転送のためにどのようにパッケージされるかということです。主要な5つのMIMEエンコーディングが以下に挙げられています。より包括的なリストは、RFC-2046で見つけることが出来るかもしれません。

7bit
コード化が全く行われません。 このラベルは8ビットの文字は一切無いことを主張し、改行コードを含んだ文字数が1000を超えないことを主張しています。
8bit
コード化は全く行われません。このラベルは8ビットの文字があるかもしれないことを主張し、改行コードを含んだ文字数が1000を超えないことを主張しています。
binary
コード化は全く行われません。このラベルは8ビットの文字があるかもしれないことを主張し、改行コードを含んだ文字数が1000を超えるやもしれないことを主張しています。まずメールゲートウェイを通り抜けられることは無いでしょう。
base64
スタンダードなエンコーディング。(それは任意の2進のデータを7ビットのドメインにマッピングします)。 非ASCII文字を含むメッセージ(例えば、ラテン語-1、ラテン語-2、またはいかなる他の8ビットのアルファベットも)をコード化することの役に立ちます。
quoted-printable
スタンダードなエンコーディング。(それは任意のline-orientedのデータを7ビットのドメインにマッピングします)。非ASCII文字を含むメッセージ(例えば、ラテン語-1、ラテン語-2、またはいかなる他の8ビットのアルファベットも)をコード化することの役に立ちます。

 

 

■トラックバック

このエントリーのトラックバックURL:
http://www.7korobi8oki.com/mt/mt-tb.cgi/14

» 今日いじってみたPerlのmodule達 from shibata(hi) shokudou
CPANを巡っています。 ・MIME::Parser ・MIME::HEad ・HTTP::Date そして、参考にしたページ。 ・Blog Developer... [続きを読む]

トラックバック時刻: 2006年01月05日 02:25

» バイクメカニズム&メンテナンス from 車とバイクの情報館
大切にしている愛車だからこそ、正しい作業内容に基づいたメンテナンスをしてやりたい…。ライダーのそんな声に答えるべく、バイクに乗る前の基礎知識からメカニズム、メン... [続きを読む]

トラックバック時刻: 2007年03月26日 23:42

» this is very good from this is very good
this is related article [続きを読む]

トラックバック時刻: 2007年12月28日 21:10

■コメントはこちらから

サイン・インを確認しました、 . さん。コメントしてください。 (サイン・アウト)

(いままで、ここでコメントしたとがないときは、コメントを表示する前にこのウェブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)


情報を登録する?


mail TOP