#!/usr/bin/perl -w
###
# Perl modules that need to be installed
###
use MIME::Parser;
use MIME::Entity;
use MIME::Base64;
#use Net::POP3;
use Mail::POP3Client;
use XMLRPC::Lite;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
###
# User Configurable Variables
###
#THREE DIFFERENT POP MAILBOX EXAMPLES
# GMAIL SETTINGS
#my $username = "denspop"; ## CHANGE THIS LINE
#my $password = "password"; ## CHANGE THIS LINE
#my $mailserver = "pop.gmail.com"; ## CHANGE THIS LINE
# DREAMHOST SETTINGS
my $username = ""; ## CHANGE THIS LINE
my $password = ""; ## CHANGE THIS LINE
my $mailserver = ""; ## CHANGE THIS LINE
# HOTPOP SETTINGS
#my $username = "dpstyles97"; ## CHANGE THIS LINE
#my $password = "password"; ## CHANGE THIS LINE
#my $mailserver = "pop.hotpop.com"; ## CHANGE THIS LINE
# TWO DIFFERENT HOSTING EXAMPLES (NYU vs. DREAMHOST)
# MY DREAMHOST SETTINGS
my $temp_folder = "";
my $attachment_output_folder = "";
my $attachment_output_folder_relative = "";
# this is the URL to the hack.php folder. This passes all the needed information to hack.php.
my $logic_url = "";
# MY NYU SETTINGS
#my $temp_folder = "/home/dc788/public_html/ubicompmobile/tmp/"; ## CHANGE #THIS LINE
#my $attachment_output_folder = #"/home/dc788/public_html/ubicompmobile/img/"; ## CHANGE THIS LINE
#my $attachment_output_folder_relative = "img/"; ## CHANGE THIS LINE
#my $logic_url = "http://itp.nyu.edu/ubicompmobile/quick/logic.php";
# QUICK DEBUGGING SETTINGS
my $delete_messages = 1; # Should we delete messages when we pop them?
my $print_output = 1; # Print output (for error checking / debugging)
my $hit_url = 1; # Forward our parsed values (to + from + subject + body) to our PHP script
###
# Other Variables that *may be* changed
###
#my $pop = Net::POP3($mailserver, Timeout => 15, USESSL => 1);
my $pop = new Mail::POP3Client( USER => $username, PASSWORD => $password, HOST => $mailserver, USESSL => 1);
my $max_chars = 70; # Number of chars to allow in a line of text from an incoming message
my $delete_temp_files = 1; # Delete temporary files that are created
my $post_to_blog = 0; # 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 w$
my $umask = '0002'; # File creation to 775, 0022 would be 755
# THINGS WE'RE NOT USING (for posting to blogs)
my $blog_xmlrpc_url = ""; ## CHANGE THIS LINE
my $blog_id = 2; ## CHANGE THIS LINE
my $blog_username = ""; ## CHANGE THIS LINE
my $blog_password = ""; ## CHANGE THIS LINE
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 = "eastDown_" . 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))
if ($pop->login())
{
$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 $messageCount = $pop->Count;
if ($print_output)
{
print $messageCount . " messages\n";
print "--------------------------\n";
}
my $msgnum = 1;
while ($msgnum <= $messageCount)
{
#my $msg = $pop->get($msgnum);
my $msg = $pop->Retrieve($msgnum);
#print $msg;
my $entity = $parser->parse_data($msg);
###
# GET MESSAGE HEADER
###
my $msg_head = $entity->head;
my $subject = "";
my $to = "";
my $from = "";
my $attachment = "";
###
# 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 .= "
\n
";
}
}
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;
#### NEED TO POST ENCLOSURE TO XML-RPC and ADD FUNCTION TO XMLRPC.PHP
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)
{
# FOR HITTING URL, WE EDIT THIS PART
#strip out anythign after the first line break
$body =~ s/\n.*$//gis;
print "MESSAGE #" . $msgnum . "\n";
print "To: " . $to . "\n";
print "From: " . $from ."\n";
print "Subject: " . $subject ."\n";
print "Body: " . $body ."\n";
for (my $i = 0; $i <= $#attachments; $i++)
{
$attachment = $attachments[$i];
print "Attachment: " . $attachments[$i] . " - " . $attachments_type[$i] . " - " . $attachments_relative[$i] ."\n";
}
# $url = $logic_url . "?task=sms";
$url = $logic_url . "?task=sms&to=" . $to . "&from=" . $from . "&subject=" . $subject . "&file=" . $attachment . "&body=" . $body . "";
print "URL:" . $url . "\n";
if ($hit_url)
{
print "Data fwd'ed to URL!\n";
}
print "--------------------------\n";
$attachment = "";
}
if ($hit_url)
{
# added 2/9/06
for (my $i = 0; $i <= $#attachments; $i++)
{
$attachment = $attachments[$i];
}
# $url = $logic_url . "?task=sms";
$url = $logic_url . "?task=sms&to=" . $to . "&from=" . $from . "&subject=" . $subject . "&file=" . $attachment . "&body=" . $body . "";
my $ua = LWP::UserAgent->new();
my $req = POST $url;
$ua->request($req)->as_string;
}
if ($delete_messages)
{
$pop->delete_message($msgnum); # seems to work for all emails (include @gmail)
}
$msgnum++;
}
if ($delete_temp_files)
{
$parser->filer->purge;
}
}
else
{
print("Error: Can't log into mailbox. Make sure to check:\n");
print("(a) username + password + mailserver are correct\n");
print("(b) if using a gmail address, make sure POP is enabled in your gmail settings\n");
}
#$pop->quit;