#!/usr/bin/perl ### # No Copyright. Use as you wish. Don't blame me if it doesn't work as it should. # Send me a note if you feel like it. Bug fixes and enhancements appreciated. # Shawn Van Every: vanevery@walking-productions.com # # To Do: ## Figure-out what is up with Verizon double posting - Fixed ## Figure-out what is going on with Verizon regex - Fixed # Make Category Posting Work # Get Spring Messages Working (need a tester) ## Test latest fixes on providers other than T-Mobile # Post videos as a screenshot or perhaps as a flash video but still with enclosure # Post images sized correctly for display instead of full size # Add in FFMPEG conversion to Flash if wanted ### ### # Perl modules that need to be installed ### use MIME::Parser; use MIME::Entity; use MIME::Base64; use Net::POP3; use LWP::UserAgent; use HTTP::Request::Common qw(POST); ### # User Configurable Variables ### my $username = "xxxxxx "; ## CHANGE THIS LINE my $password = "xxxxx"; ## CHANGE THIS LINE my $mailserver = "mail.freeformed.org"; ## CHANGE THIS LINE my $temp_folder = "/home/.fidel/catmindeye/freeformed.org/temp/"; ## CHANGE THIS LINE my $attachment_output_folder = "/home/.fidel/catmindeye/freeformed.org/phone/"; ## CHANGE THIS LINE my $attachment_output_folder_relative = "www.freeformed.org/phone/"; ## CHANGE THIS LIN my $image_width = 320; my $use_wp_plugin = 1; ### # 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 = 0; # Delete temporary files that are created my $print_output = 1; # Print output my $hit_url = 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","dottedLine_600.gif","spacer.gif","video.gif","dottedLine_350.gif"); # A list of attachment filename regular expressions that you don't want included my @allowed_domains = ("itp-721bway-167.roam.net.nyu.edu","mobile.att.net","cingularme.com","messaging.sprintpcs.com","tmomail.net","vtext.com","mmode.com","alltel.net","walking-productions.com","vzwpix.com","mms.mycingular.com"); # A list of domains that are allowed to post to this site $logic_url = "http://freeformed.org/rediallogic.pl"; my @bad_text = ("nothingatall", "PIX.*FLIX.*Messaging", "To.*learn.*how.*you.*can.*snap.*pictures.*with.*your.*wireless.*phone", "To.*learn.*how.*you.*can", "www\.verizonwireless\.com", "To.*play.*video.*messages.*sent.*to.*email", "process.*when.*asked.*to.*choose.*an.*installation.*type.*Minimum.*Recommended.*or.*Custom.*select", "If.*you.*can.*read.*this.*text", "^T-Mobile\$", "If.*you.*are.*having.*trouble.*playing.*this.*attachment", "This.*Video.*Message.*was.*sent.*from.*a.*T-Mobile.*video.*phone", "\.footer.*{", "font-family:.*Arial,.*;", "font-size.*;", "color:.*;", "text-decoration:.*;", "normal.*{", "This.*message.*was.*sent.*using.*service.*from.*Verizon.*Wireless!", "visit /getitnow/getflix.", ",.*QuickTime.*6.5.*or.*higher.*is.*required..*Visit.*www.apple.com/quicktime/download.*to.*download.*the.*free.*player.*or.*upgrade.*your.*existing.*QuickTime.*Player..*Note:.*During.*the.*download", "Minimum.*for.*faster.*download." ); # a list of text regular expressions that you don't want included # NEED TO WORK ON THIS my $umask = '0002'; # File creation to 775, 0022 would be 755 my %mime_types = ("image\/jpeg", "jpg", "image\/jpg", "jpg", "image\/gif", "gif", "audio\/x-wav", "wav", "audio/wav", "wav", "video\/mp4", "mp4", "video\/3gpp2", "3g2", # Match this before 3gp as both are matching same file "video\/3gpp", "3gp", "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; my $already_matched = 0; # 3gp and 3gp2 are both matching on same file.. ## Loop through the types we understand foreach $valid_type (keys %mime_types) { if ($already_matched != 1) # This is a hack because my matching isn't right { 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; $already_matched = 1; } } } # End $already_matched } ## 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_body =~ s/<.*>//sgi; # Strip out any HTML tags foreach $badline (@bad_text) { $mime_message_body =~ s/$badline//sgi; } @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 if ($print_output) { print "skipping" . $message_line; } } else { $message_line =~ s/^\s//; $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_body =~ s/<.*>//sgi; # Strip out any HTML tags foreach $badline (@bad_text) { $mime_message_body =~ s/$badline//sgi; } @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 if ($print_output) { print "skipping " . $message_line . "\n"; } } else { $message_line =~ s/^\s//; $body .= $message_line . "\n"; # Only grabbing first line } } } 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; } } my $posting_allowed = 0; foreach $allowed_domain (@allowed_domains) { if ($from =~ /.*$allowed_domain.*/) { $posting_allowed = 1; if ($print_output) { print "Matched: $allowed_domain\n"; } } } ## # 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) { ## Skip bad lines $skip = 0; foreach $badline (@bad_text) { if ($message_line =~ /$badline/) { $skip = 1; if ($print_output) { print "should be skipping\n"; } } } if ($message_line =~ /^\n/ || $skip == 1) { if ($print_output) { print "skipping " . $message_line . "\n"; } } else { $body .= $message_line; } } } # IF SUBJECT IS BLANK TAKE FIRST LINE OF BODY if ($subject eq "") { @body_array = split('\n',$body); $subject = $body_array[0]; $body = ""; for ($b = 1; $b<=$#body_array; $b++) { $body .= $body_array[$b]; } } chomp($to); # REMOVE TRAILING LINE BREAKS chomp($from); chomp($subject); chomp($body); if ($hit_url) { print "Got here"; for (my $i = 0; $i <= $#attachments; $i++) { $attachment = $attachments[$i]; } $url = $logic_url . "?to=" . $to . "&from=" . $from . "&subject=" . $subject . "&file=" . $attachment . "&body=" . $body . ""; my $ua = LWP::UserAgent->new(); my $req = HTTP::Request->new('GET', $url); my $response = $ua->request($req)->as_string; print $response; print $url; } if ($delete_messages) { $pop->delete($msgnum); } if ($delete_temp_files) { $parser->filer->purge; } } } $pop->quit;