end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

perlでメールを受信(Net::POP3)し、パース(MIME::Parser)

今まで使用したことがありませんでしたが、perlでメールを受信し、マルチパートをパースするには、Net::POP3MIME::Parserを使用するようです。

#!/usr/local/bin/perl

use strict;
use warnings;
use MIME::Parser;
use Net::POP3;
use Data::Dumper;

my $host =	'mail.hogehoge.co.jp';
my $uid =	'hoge';
my $passwd =	'hoge';
my $parse_out_dir = './out';

sub main {

    #login
    my $pop3  = Net::POP3->new($host) or die "can't connect $host";
    die "can't login $host by $uid" unless $pop3->login($uid,$passwd);

    #MIME::Parserの準備
    my $parser = MIME::Parser->new();
    unless (-d $parse_out_dir){
	mkdir $parse_out_dir or die "can't mkdir $parse_out_dir";
    }
    $parser->output_dir($parse_out_dir);

    #messeMIME::Parserの準備
    my $msg_ids = $pop3->list();
    for my $mid (keys %$msg_ids ) {

	my $msg = $pop3->get($mid);

	#parse_dataすると,output_dirにfileが書込まれます
	#同じfile名が複数ある場合
	#hoge-1.txt,hoge-2.txtのように連番で保存されます
	my $entity = $parser->parse_data($msg);

	#multipart以外は、$entity->partsが失敗します
	unless ($entity->is_multipart){
	    clear_dir($parse_out_dir);
	    next;
	}

	my $i = 0;
	my $part_count = $entity->parts;
	while ( $i < $part_count ){
	    #file名(path?)の取得
	    my $path = $entity->parts($i)->bodyhandle->path;
	    print "$path\n";
	    $i++;
	}

	clear_dir($parse_out_dir);
    }
    $pop3->quit;
}


sub clear_dir { #$dir内のfileを全て削除
    my ($dir) = @_;

    opendir my $dh, $dir or die "can't opendir $dir";
    for my $file ( readdir($dh) ){
	next if ($file eq "." or $file eq "..");
	unlink("$dir/$file") or die "can't unlink $dir/$file";
    }
    closedir($dh) or die "can't closedir $dir";
}

main();