tomi-ruのモバイル日記

profile
記事とカテゴリ一覧はこちら
 | 

2008-07-11

Email::MIME::XPath++

| 00:08 | はてなブックマーク - Email::MIME::XPath++ - tomi-ruのモバイル日記

Email::MIME系でメールパースする話で

  • 添付画像を取るときAttachment::StripperだとDoCoMo携帯から画像一個本文なしで添付してきた時みたいな画像一個だけのシングルパートだと取れない(たぶん携帯のMUAがRFC的におかしいのだと思う)
  • 一番最初にでてくるテキストぽいパートを取得」ってよくやるけど$email->body はマルチパートだと使えないしMIMEは入れ子になってるから再帰的にさがさないと行けなくてめんどう

とかいう話があると思うのですが、

添付ファイルの話は、ぼくは以下みたいに空のパートを付けたりしてました。typesterさんは$email->partsを回して探すことにしたと言ってました。

use Email::MIME::Attachment::Stripper;
use Email::MIME::Modifier;

sub Email::MIME::attachment_files {
    my $self  = shift;
    my $email = Email::MIME->new($self->as_string);

    if ($email->parts == 1) {
        $email->parts_add([ Email::MIME->new("Content-Type: text/plain\n\ndummy") ]);
    }

    my $stripper = Email::MIME::Attachment::Stripper->new($email);
    my @attachments;
    for my $attach ($stripper->attachments) {
        next if $attach->{content_type} =~ m{^(?:text|multipart|message)/};
        push @attachments, $attach;
    }

テキストぽい最初のパートをとる話は、MIMEパートが入れ子の場合$email->bodyでは取れないので、以下のように再帰的にがんばったりしていました。

sub Email::MIME::first_text {
    my $self = shift;
    _first_text_part($self->parts);
}

sub _first_text_part {
    my @parts = @_;
    for my $part (@parts) {
        if ($part->{ct}{discrete} eq 'multipart') {
            return _first_text_part($part->parts);
        }
        if ($part->{ct}{discrete} eq 'text' and
            $part->{ct}{composite} =~ /^plain|html$/) {
            return $part;
        }
    }
}

が、

Email::MIME::XPath を使えば超絶楽だったってことを最近知りました。さっそく今日のCPANモジュールで紹介しようと思ったのですが、Email::MIMEの紹介が先かなとか思ったらめんどうになったのでここで紹介。

最初の、画像パートを抜き出すのは、以下の一行!

my @parts = $email->xpath_findnodes('//*[@content_type=~"^image/"]');

画像一個のシングルパートな場合も問題ないし、変な再帰を書かなくてもよいし、Attachment::Stripperを使うのと比べ、取りたいタイプを指定できて良いです。

テキストぽい最初のパートをとるのも一行

my ($part) = $email->xpath_findnodes('//*[@content_type=~"^text"][1]');

楽だ。なんで言及がすくないんだろう。

Tree::XPathEngine の全機能をサポートしてないですが、xpath_findnodes() と、特別に使える属性の中でcontent_typeというのがあるということだけ覚えておけばよいと思います。

wteiqbtcwteiqbtc2011/03/20 14:39gzTW9S <a href="http://mmdhpeqrvcuc.com/">mmdhpeqrvcuc</a>, [url=http://jfkgbmjhgalo.com/]jfkgbmjhgalo[/url], [link=http://yotgvlprpnlr.com/]yotgvlprpnlr[/link], http://nnycpbqcvebp.com/

HannesHannes2012/09/23 13:44Articles like this make life so much simpelr.

fpwlzscxcfpwlzscxc2012/09/25 16:04uTwDex , [url=http://zqnaoismzlwg.com/]zqnaoismzlwg[/url], [link=http://ihjmypmptmvs.com/]ihjmypmptmvs[/link], http://uvnggiwecjha.com/

EkainEkain2015/08/11 17:52You've got it in one. Cou'dnlt have put it better.

 |