Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Trying to extract an attachment

by rhesa (Vicar)
on Oct 29, 2007 at 15:08 UTC ( [id://647858]=note: print w/replies, xml ) Need Help??


in reply to Trying to extract an attachment

The result of $stripper->attachments; is an array of hashrefs. Each element has 3 key-value pairs:
{ filename => "suggested filename", payload => "file contents". content_type => "mime type", }
Provided the rest of your code correctly fetches the attachments, this loop for saving them is broken:
# Save the attachments on the local disk foreach $i (@attachments) { my $file = 'test'.$i; #DUMP . @attachments->filename(1); print "cou"; open FILE, '>', $file or die $!; print FILE @attachments; close FILE; chmod 0644, $file; print "cou"; }
If you're iterating over the array, you should be operating on the *current* element in the loop block, not on the array again. And you should be using each attachment's datastructure properly:
foreach my $att ( @attachments ) { my $file = $att->{filename}; open my $fh, '>', $file or die $!; print $fh $att->{payload}; close $fh; chmod 0644, $file; }

Replies are listed 'Best First'.
Re^2: Trying to extract an attachment
by Shinama (Acolyte) on Oct 30, 2007 at 10:12 UTC
    Hi rhesa,

    thanks for helping me :) But I still have the problem with attachment... I still get errors like
    Use of uninitialized value in concatenation (.) or string at C:\Dokume +nte und Einstellungen\holzner.s\Eigene Dateien\perlmail\perlguard_gu_ +version.pl line 55. at C:\Dokumente und Einstellungen\holzner.s\Eigene Dateien\perlmail\p +erlguard_gu_version.pl line 55 The size of the message is kB Continue ? Use of uninitialized value in concatenation (.) or string at C:\Dokume +nte und Einstellungen\holzner.s\Eigene Dateien\perlmail\perlguard_gu_ +version.pl line 65. at C:\Dokumente und Einstellungen\holzner.s\Eigene Dateien\perlmail\p +erlguard_gu_version.pl line 65 Number of email parts : 2 hash: $VAR1 = undef; hash: $VAR1 = undef;
    how is it possible that the size is "nothing"? Doesn't it mean that the script was not able to read the mail? The email I use for testing is just a normal email with a small attachment :( In addition to the "old" mistakes above your foreach results in the following error messages:
    Use of uninitialized value in open at C:\Dokumente und Einstellungen\h +olzner.s\Eigene Dateien\perlmail\perlguard_gu_version.pl line 132. at C:\Dokumente und Einstellungen\holzner.s\Eigene Dateien\perlmail\p +erlguard_gu_version.pl line 132 No such file or directory at C:\Dokumente und Einstellungen\holzner.s\ +Eigene Dateien\perlmail\perlguard_gu_version.pl line 132. at C:\Dokumente und Einstellungen\holzner.s\Eigene Dateien\perlmail\p +erlguard_gu_version.pl line 132 </code it seems like the script doesn't recognize the key pair ? but how is t +hat (empty attachment array) possible?


    I'm sorry to bother you with such stupid beginner problems but I don't understand it :(

    Do you have any idea how I could fix that whole problem :(? Here is the current version of the script (I have blocked most of the prints to get rid of the print spamming :( )

    Could it be that the problem already starts at the MsgBS-part? This is the beginning of the errors?

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Email::Simple; use Email::MIME; use Mail::IMAPTalk; use Email::MIME::Attachment::Stripper ; use constant DUMP => 'C:\\Dokumente und Einstellungen\\holzner\.s\\Eig +ene Dateien\\perlmail\\'; my $server = 'mymailserver'; my $imap_port = '143'; my $login = 'mylogin'; my $password = 'mypwd'; print "******************\n"; print "* MAIL EXTRACT *\n"; print "******************\n\n"; my $FolderName = 'THO'; print "Connecting to IMAP server at ".$server.":".$imap_port."...\n"; # open the imap connection using IMAP::Talk my $imap = Mail::IMAPTalk->new( Server => $server, Port => $imap_port, Username => $login, Password => $password, Separator => '\\', RootFolder => '',#'Inbox', CaseInsensitive => 1) || die "Connection failed. Reason: $@"; # Select folder and get first unseen message $imap->select($FolderName) || die $@; my $MsgId = $imap->search('not', 'seen')->[0]; if ($MsgId) { # Get the enveloppe print "The message with ID ".$MsgId." has the following enveloppe: +\n"; my $MsgEV = $imap->fetch($MsgId, 'envelope')->{$MsgId}->{envelope} +; print "From: " . $MsgEV->{From}."\n"; print "To: " . $MsgEV->{To}."\n"; print "Subject: " . $MsgEV->{Subject}."\n"; print "Sender: " . $MsgEV->{Sender}."\n"; print "Continue ?\n"; getc(STDIN); # Get the message body structure my $MsgBS = $imap->fetch($MsgId, 'bodystructure')->{$MsgId}->{body +structure}; print "MsgBS -->". $MsgBS. "\<--\n"; print "The size of the message is ". $MsgBS->{Size} ."kB\n"; print "Continue ?\n"; getc(STDIN); # Find imap part number of text part of message my $MsgTxtHash = Mail::IMAPTalk::find_message($MsgBS); my $MsgPart = $MsgTxtHash->{text}->{'IMAP-Partnum'}; # Retrieve message text body my $MsgTxt = $imap->fetch($MsgId, "body[$MsgPart]")->{$MsgId}->{bo +dy}; #print Dumper( $MsgTxt ); #print "Full message : \n"; #print "\n<-------------------------------------->\n"; #print $MsgTxt."\n"; #print "\n<-------------------------------------->\n"; #print "Continue ?\n"; getc(STDIN); # Transform the content from IMAP:Talk into a MIME object using Em +ail:MIME my $parsed = Email::MIME->new($MsgTxt); #print "Parsed content :\n". Dumper( $parsed) . "\n"; # display the MIME structure #print "MIME structure :" . $parsed->debug_structure . "\n"; my $parts = $parsed->parts; print "Number of email parts : $parts\n"; my @parts = $parsed->parts; my $i=0; #foreach (@parts) { # print "Dumped email part $i:\n", # Dumper( $parts[$i] ), # "\n"; # $i++; #} my $decoded = $parsed->body; #print "body: " . Dumper( $decoded ) . "\n"; # Give the Email MIME content to Attachment::Stripper for extracti +on my $stripper; if ($parts > 1) { $stripper = Email::MIME::Attachment::Stripper->new($parts[1]) } else { die "This message consists of a single part.\n"; } die "Not an regular MIME part given to stripper:\n" if not ref $stripper; # The extraction method itself my @attachments = $stripper->attachments; # Display the resulting attachments hash $i=0; foreach (@parts) { my $j=0; foreach ($parts[$i]) { print "hash:\n" . Dumper( $attachments[$i]->{payload}) . " +\n"; $j++; } $i++; } # Close the IMAP connection $imap->logout(); # Save the attachments on the local disk foreach my $att ( @attachments ) { my $file = $att->{filename}; open my $fh, '>', $file or die $!; print $fh $att->{payload}; close $fh; chmod 0644, $file; } } else { print "No new message in the mailbox\n" }


    Thanks a lot for helping me :) I just read in an german forum that a much better perl programmer than me needed 6 months for doing something similiar to this :( So this means that I need 1-2 years ._."?

    bye for now,
    Shinama
    "You read too much and understand too little." Moiraine Damodred (The Wheel of Time)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://647858]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (1)
As of 2024-04-24 14:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found