昨日の続き。
Propmailでメールの添付ファイルを自動処理させたいんだけど、添付されたファイルをデコードするのにPHPでやった方がいいか、uudeviewという外部システムを使ったやった方が良いかっていう。
とりあえず、PHPのみで完結させる場合
PHPでやる場合は、id:ya--madaのこのライブラリを使った。
<?php $stdin = fopen("php://stdin", "r"); $header = ""; $_header_write = true; $raw_mail = ""; do { $line = fread($stdin, 4096); if (strlen($line) == 0) break; if ( $n = strpos($line, "\n\n")){ // 空行を見つけた $header .= substr($line, 0, $n); $_header_write = false; } if ($_header_write) $header .= $line; $raw_mail .= $line ;//. PHP_EOL; } while(true); fclose($stdin); require_once 'Projects/279be/itoh/showtie/showtie/lib/ReceiptMailDecoder.class.php'; $decoder = new ReceiptMailDecoder($raw_mail); // To:アドレスのみを取得する $toAddr = $decoder->getToAddr(); // To:ヘッダの値を取得する $toString = $decoder->getDecodedHeader( 'to' ); // Subject:ヘッダの値を取得する $subject = $decoder->getDecodedHeader( 'subject' ); // text/planなメール本文を取得する $body = mb_convert_encoding($decoder->body['text'],"eucjp-win","jis"); // text/htmlなメール本文を取得する $body = mb_convert_encoding($decoder->body['html'],"eucjp-win","jis"); // マルチパートのデータを取得する if ( $decoder->isMultipart() ) { $tempFiles = array(); $num_of_attaches = $decoder->getNumOfAttach(); for ( $i=0 ; $i < $num_of_attaches ; ++$i ) { /* * ファイルを一時ディレクトリ _TEMP_ATTACH_FILE_DIR_ に保存する * 一時ファイルには tempnam()を使用する * この部分は使用に合わせて変更して下せい */ $fpath = tempnam('./hoge', "todoattach_" ); if ( $decoder->saveAttachFile( $i, $fpath ) ) { $tempFiles["$fpath"] = $decoder->attachments[$i]['mime_type']; } } }
んで、コマンドラインから
$ time cat Maildir/new/1251350204.25353_0.test.example.com |php -d memory_limit=10M proc_test_php.php
って感じで添付ファイル付きのメール(1251350204.25353_0.test.example.com)をパイプして渡してやる。ちなみに、メールの添付ファイルは1M程度。
結果は
real 0m0.081s
user 0m0.062s
sys 0m0.021s
結構速い。
uudeviewを使った場合
じゃあ、uudeview一発でっていうわけにもいかなくて、uudeviewはメールのヘッダ情報なんかを結果としてSTDOUTに出さない(Subjectのみかろうじて)ので、PHPの中を一回通してHeaderを拾ってやる。
こんな感じ。
proc_test.php
<?php $stdin = fopen("php://stdin", "r"); $uudeview = popen('uudeview - -p ~/hoge 2>&1', 'w'); $header = ""; $_header_write = true; do { $line = fread($stdin, 4096); if (strlen($line) == 0) break; if ( $n = strpos($line, "\n\n")){ // 空行を見つけた $header .= substr($line, 0, $n); $_header_write = false; } if ($_header_write) $header .= $line; fputs($uudeview, $line); } while(true); fclose($stdin); fclose($uudeview);
で、コマンドラインからは
$ time cat Maildir/new/1251350204.25353_0.test.example.com |php proc_test.php
って感じ。
結果は、
real 0m0.162s
user 0m0.129s
sys 0m0.024s
・・・遅っ!ってほどでもないけど、PHPより遅いんだ。
PHP内でパイプしないで、やってみる
PHP内を通したから遅いのかなーとか一瞬思って
proc_test2.php
<?php $stdin = fopen("php://stdin", "r"); $header = ""; $_header_write = true; do { $line = fread($stdin, 4096); if (strlen($line) == 0) break; if ( $n = strpos($line, "\n\n")){ // 空行を見つけた $header .= substr($line, 0, $n); $_header_write = false; } if ($_header_write) $header .= $line; echo $line; } while(true); fclose($stdin);
ってしてみて、コマンドラインから
$ time cat Maildir/new/1251350204.25353_0.sc440.local.junoe.jp |php proc_test2.php|uudeview - -p ~/hoge 2>&1
ってしてみる。
結果、
real 0m0.147s
user 0m0.126s
sys 0m0.022s
・・・変って無い。
まぁ、そもそもuudeviewだけでやっても
$ time uudeview -i Maildir/new/1251350204.25353_0.sc440.local.junoe.jp
real 0m0.117s
user 0m0.107s
sys 0m0.009s
なんだけどね。