#!/usr/bin/perl -w ### # Perl modules that need to be installed ### use MIME::Parser; use MIME::Entity; use MIME::Base64; use Net::POP3; use XMLRPC::Lite; ### # User Configurable Variables ### my $username = ""; ## CHANGE THIS LINE my $password = ""; ## CHANGE THIS LINE my $mailserver = ""; ## CHANGE THIS LINE my $temp_folder = ""; ## CHANGE THIS LINE my $attachment_output_folder = ""; ## CHANGE THIS LINE my $attachment_output_folder_relative = ""; ## CHANGE THIS LINE my $blog_xmlrpc_url = ""; ## CHANGE THIS LINE my $blog_id = ; ## CHANGE THIS LINE my $blog_username = ""; ## CHANGE THIS LINE my $blog_password = ""; ## CHANGE THIS LINE ### # Other Variables that *may be* changed ### my $pop = Net::POP3->new($mailserver, Timeout => 15); my $max_chars = 70; # Number of chars to allow in a line of text from an incoming message my $delete_messages = 1; # Delete messages from your inbox as they are processed my $delete_temp_files = 1; # Delete temporary files that are created my $print_output = 0; # Print output my $post_to_blog = 1; # Post to your blog? my $use_gif = 0; # 1 to allow GIF's as attachments, 0 to not allow them (T-Mobile issues) my @bad_attachments = ("masthead.jpg"); # A list of attachment filename regular expressions that you don't want included my $umask = '0002'; # File creation to 775, 0022 would be 755 my %mime_types = ("image\/jpeg", "jpg", "image\/jpg", "jpg", "image\/gif", "gif", "video\/3gpp", "3gp", "audio\/x-wav", "wav", "video\/mp4", "mp4", "video\/3gpp2", "3g2", "video\/mpeg", "mpg", "video\/quicktime", "mov", "video\/x-quicktime", "mov", "video/x-msvideo", "avi" ); # A list of the attachment mime types to extract ### # Parsing Subroutine ### sub parseMessageParts { my @messageParts = @_; my $partnum = 0; my $is_mime_message = 0; while(my $part = shift(@messageParts)) { $is_mime_message = 1; # Yes we have a mime message my $known_type = 0; # Did we find the type yet? # Get the Mime type of the part my $type=$part->head->mime_type || $part->head->effective_type; ## Loop through the types we understand foreach $valid_type (keys %mime_types) { if ($type =~ $valid_type) { $known_type = 1; for (my $i = 0; $i <= $#bad_attachments; $i++) { if ($part->head->recommended_filename =~ $bad_attachments[$i]) { $skip = 1; } } if (!$skip) { my $attachment = $part->bodyhandle->as_string; my $file_name = "attachment_" . time() . "_" . int(rand(1000)) . "\." . $mime_types{$valid_type}; my $image_file = $attachment_output_folder . $file_name; my $fh = new FileHandle "> $image_file"; if (defined $fh) { print $fh $attachment; $fh->close; } $attachments[++$#attachments] = $file_name; $attachments_type[++$#attachments_type] = $mime_types{$valid_type}; $attachments_relative[++$#attachments_relative] = $attachment_output_folder_relative . $file_name; } } } ## Not in our list, let's check for text or multipart messages if ($known_type == 0) { if ($type =~ /text\/plain/i) { my $message_bodyhandle = $part->bodyhandle; $mime_message_body = $message_bodyhandle->as_string; @mime_message_array = split('\n',$mime_message_body); foreach $message_line (@mime_message_array) { if ($message_line =~ /^\n/ || $message_line =~ /^\s*\n/ || $message_line !~ /\w/) { # Ignore blank lines } else { $body .= $message_line . "\n"; } } } elsif ($type =~ /text\/html/i) { # Plain Text portions or attachments my $message_bodyhandle = $part->bodyhandle; $mime_message_body = $message_bodyhandle->as_string; @mime_message_array = split('\n',$mime_message_body); foreach $message_line (@mime_message_array) { $message_line =~ s/<.*>//gi; # Strip out any HTML tags if ($message_line =~ /^\n/ || $message_line =~ /^\s*\n/ || $message_line !~ /\w/) { # Ignore blank lines } else { $body .= $message_line . "\n"; } } } elsif ($type =~ /multipart\/.*/i || $type =~ /message\/.*/i) { # Multipart Message, Parse This Again # Thanks again T-Mobile my @otherparts=$part->parts; &parseMessageParts(@otherparts); } else { if ($print_output) { print "Other Type: " . $type . "\n\n"; # OUTPUT } } } $partnum++; } return $is_mime_message; } ### # Main Program Execution ### if ($print_output) { print("Running at: " . localtime() . "\n"); } if ($pop->login($username, $password)) { $umask = oct($umask) if $umask =~ /^0/; umask $umask; if ($print_output) { print("Logged into mailserver\n"); } # Create the parser object my $parser = MIME::Parser->new(); $parser->output_dir($temp_folder); my $msgnums = $pop->list; # hashref of msgnum => size foreach my $msgnum (keys %$msgnums) { my $msg = $pop->get($msgnum); my $entity = $parser->parse_data($msg); ### # GET MESSAGE HEADER ### my $msg_head = $entity->head; my $subject = ""; my $to = ""; my $from = ""; ### # MESSAGE Related Vars ### $body = ""; @attachments = (); @attachments_type = (); @attachments_relative = (); ## # GET MESSAGE SUBJECT ## if ($msg_head->count('Subject') > 0) { $subject = $msg_head->get('Subject'); } ## # GET MESSAGE FROM ## if ($msg_head->count('From') > 0) { $from = $msg_head->get('From'); if ($from =~ /<(.*)>/) { $from = $1; } } ## # GET MESSAGE TO ## if ($msg_head->count('To') > 0) { $to = $msg_head->get('To'); if ($to =~ /<(.*)>/) { $to = $1; } } ### # GET MESSAGE PARTS (BODY AND ATTACHMENTS) ### my @parts=$entity->parts; my $is_mime = &parseMessageParts(@parts); ## Calling our parse subroutine ## # IF IT ISN'T A MIME MESSAGE (NO ATTACHMENTS) ## if (!$is_mime) { ### # GET MESSAGE BODY LINES ### $msg_body = $entity->body; foreach $message_line (@$msg_body) { if ($message_line =~ /^\n/) { } else { $body .= $message_line; } } } chomp($to); # REMOVE TRAILING LINE BREAKS chomp($from); chomp($subject); chomp($body); if ($post_to_blog) { my $attachment_html = ""; for (my $i = 0; $i <= $#attachments; $i++) { my $attachment = $attachments[$i]; my $attachment_type = $attachments_type[$i]; my $attachment_relative = $attachments_relative[$i]; if ($attachment_type eq "jpg" || $attachment_type eq "gif") { $attachment_html .= "\n"; } elsif ( $attachment_type eq "3gp" || $attachment_type eq "wav" || $attachment_type eq "mp4" || $attachment_type eq "3g2" || $attachment_type eq "mpg" || $attachment_type eq "mov" || $attachment_type eq "avi" ) { $attachment_html .= "

"; } } my $postresult=XMLRPC::Lite ->proxy($blog_xmlrpc_url) ->call('metaWeblog.newPost',$blog_id,$blog_username,$blog_password, { 'title'=>$subject, 'description'=>$body . $attachment_html, 'mt_allow_comments'=>1, 'mt_allow_pings'=>1 }, 1 ) ->result; if ($print_output) { print "Message To: $to\n"; print "Message From $from\n"; print "Message Subject $subject\n"; print "Message Body $body\n"; for (my $i = 0; $i <= $#attachments; $i++) { print "Message Attachment $attachments[$i] . " - " . $attachments_type[$i] . " - " . $attachments_relative[$i]\n"; } print "Post to Blog Result: " . $postresult . "\n"; print "--------------------------\n"; } } elsif ($print_output) { print "Message To: $to\n"; print "Message From $from\n"; print "Message Subject $subject\n"; print "Message Body $body\n"; for (my $i = 0; $i <= $#attachments; $i++) { print "Message Attachment $attachments[$i] . " - " . $attachments_type[$i] . " - " . $attachments_relative[$i]\n"; } print "Not Posted to Blog"; print "--------------------------\n"; } if ($delete_messages) { $pop->delete($msgnum); } } if ($delete_temp_files) { $parser->filer->purge; } } $pop->quit;