2012-10-11 42 views
0

我正在使用Perl來閱讀郵件,查找並保存附件。附件將始終是二進制pdf文檔,永遠不會有多個附件。我需要閱讀主題,檢查並保存附件(如果存在)複製郵件到臨時存儲的文件夾。MIME :: Parser - 無法保存二進制附件

閱讀,打印,複印功能都可以使用。我用MIME :: Parser(我已經安裝了MIME :: Tools)嘗試了很多不同的場景,但是要麼得到一個空白文件或者帶有1或2個字符的文件。我也想知道如何確定/設置文件擴展名,而不是盲目地重命名爲.pdf。

#!/usr/bin/perl 


use Net::IMAP::Simple::SSL; 
use Email::Simple; 
use MIME::Parser; 

print "Content-type: text/html\n\n"; 

$server = new Net::IMAP::Simple::SSL('xxx'); 
$server->login('xxx','xxx'); 

my $folder='inbox'; 

my ($unseen, $recent, $total) = $server->status($folder); 
my $newm = $server->select('INBOX'); 

my $tmp=($total-9); #limit for testing 

my $outputdir = "./temp"; 
my $parser = new MIME::Parser; 
$parser->output_dir($outputdir); 


for (my $i = $tmp; $i <= $total; $i++) { 

     if ($server->seen($i)) { 
     print "Message #$i has been seen before...<br />"; 
     } else { 

     my $es=Email::Simple->new(join '', @{$server->top($i)}); 
     print $es->header('Subject')." on "; 
     print $es->header('Date')."<br />"; 
     print "You've just seen message #$i<br />" if $server->see($i)."<br />"; 
     $msg = $server->get($i); 
     $parser->parse_data($msg); 
     $server->copy($i,'dump'); 

     } 

    } 

$server->quit(); 

exit; 

錯誤

parse_data:錯誤的參數引用類型:網:: IMAP ::簡單:: _在mailextract.pl行消息X

回答

1

不知道爲什麼你」重新使用兩個不同的解析器...

my $entity = $parser->parse_data($message); 
my $from = $entity->head->get('From'); 
my $subject = $entity->head->get('Subject'); 
my $timestamp = $entity->head->get('Date'); 

for my $part ($entity->parts()) { 
    if ($part->mime_type eq 'application/pdf') { ### Few different types in use, see what your 
               ### messages get sent with 
    my $filename = $part->bodyhandle->path; 
    ... 
    ### Do whatever 
    } 
} 

編輯:而你的錯誤發生,因爲你沒有通過th使用PerlIO的

You may supply the DATA in any of a number of ways... 

    A scalar which holds the message. A reference to this scalar will be used internally. 

    A ref to a scalar which holds the message. This reference will be used internally. 

    DEPRECATED 

    A ref to an array of scalars. The array is internally concatenated into a temporary string, and a reference to the new 

字符串內部使用

parse_data DATA

Instance method. Parse a MIME message that's already in core. This internally creates an "in memory" filehandle on a Perl scalar value 

:電子正確的事情要解析,淨:: IMAP ::簡單:: _消息代替。

It is much more efficient to pass in a scalar reference, so please consider refactoring your code to use that interface instead. 

如果絕對必須傳遞數組,可以在調用代碼使用 IO :: ScalarArray以產生文件句柄會更好,並 傳遞一個文件句柄來解析()

試試$parser->parse($server->getfh($i));

+0

很好,謝謝。更新下面的工作代碼,以防任何人可以使用它。 – chrisrth

0
#!/usr/bin/perl 

use Net::IMAP::Simple::SSL; 
use MIME::Parser; 

print "Content-type: text/html\n\n"; 

$server = new Net::IMAP::Simple::SSL('xxx'); 
$server->login('xxx','xxx'); 


my $newm=0; 
    $newm = $server->select('INBOX'); 

if ($newm==0) { 
    $server->quit(); 
    print "No New Messages."; 
    exit; 
    } 

my $outputdir = "./temp"; 
my $parser = new MIME::Parser; 
$parser->output_dir($outputdir); 


for (my $i = 1; $i <= $newm; $i++) { 

    my $entity = $parser->parse($server->getfh($i)); 
    my $from = $entity->head->get('From'); 
    my $subject = $entity->head->get('Subject'); 
    my $timestamp = $entity->head->get('Date'); 

    print "#$i $from/$subject/$timestamp<br />"; 

    for my $part ($entity->parts()) { 
    print "/".$part->mime_type; 
    if ($part->mime_type eq 'application/octet-stream' || $part->mime_type eq 'application/pdf') { 
     my $filename = $part->bodyhandle->path; 
     print "/$filename"; 
     } 
    print "<br />"; 
    } 
    $server->copy($i,'dump'); 
    $server->delete($i); 
    } 
$server->quit();