A simple program that does what you want is below.
The minimum version for Email::MIME is when walk_parts was introduced.
use Email::MIME 1.901; use IO::Socket::SSL; use Mail::IMAPClient; use POSIX qw/ strftime /; use Term::ReadKey;
You don’t want to hardcode your password in your program, right?
sub read_password { local $| = 1; print "Enter password: "; ReadMode "noecho"; my $password = <STDIN>; ReadMode "restore"; die "$0: unexpected end of input" unless defined $password; print "\n"; chomp $password; $password; }
Connect using SSL. We should be able to do this with a simple Ssl parameter for the constructor, but some manufacturers decided to break it down in their packages.
my $pw = read_password; my $imap = Mail::IMAPClient->new(
If you need a folder other than the inbox, change it.
$imap->select("INBOX") or die "$0: select INBOX: ", $imap->LastError, "\n";
Using the IMAP search, we look for all messages whose topics contain today's date in the format YYYYMMDD. The date can be anywhere in the object, so, for example, the theme "foo bar baz 20100316" will correspond today.
my $today = strftime "%Y%m%d", localtime $^T; my @messages = $imap->search(SUBJECT => $today); die "$0: search: $@" if defined $@;
For each such message, write file attachments in the current directory. We write an external attachment layer and do not dig nested attachments. The part with the name parameter in its content type (as in image/jpeg; name="foo.jpg" ) is considered an attachment, and we ignore all the other parts. The name of the saved attachment is the following components, separated by the - symbol: today's date, IMAP message identifier, one index of its position in the message and its name.
foreach my $id (@messages) { die "$0: funky ID ($id)" unless $id =~ /\A\d+\z/; my $str = $imap->message_string($id) or die "$0: message_string: $@"; my $n = 1; Email::MIME->new($str)->walk_parts(sub { my($part) = @_; return unless ($part->content_type =~ /\bname=([^"]+)/ or $part->content_type =~ /\bname="([^"]+)"/);