#!/usr/bin/perl -w
# Weather message
# Adam M. Bumpus <adam@bump.us>
# January 2007, updated to XML::Simple November 2010
# This script takes two arguments from the command line. The first is a 5 digit
# US zip code (or possibly some other identifier for non-US locations...?).
# The second is an e-mail address.
# 
# The script then downloads an xml file from accuweather.com. This XML file is
# intended to be used by the Forecastfox extension for Firefox/Mozilla.
# 
# The script then searches this XML and extracts some useful data and a url to
# download a radar image.
# 
# Finally, the script takes all of this and formats it into an SMIL message
# (aka MMS/Cellphone picture message) and sends it via e-mail.
# 
# The script depends on the existance of Perl, and the sendmail user
# binary (or alternate replacement thereof, I use the one provided by postfix).
# Some other assumptions probably exist about the script running on a Linuxish
# type system.
#

use XML::Simple;
use MIME::Base64;
use HTTP::Request;
use LWP::UserAgent;

if ($#ARGV != 1){
		  print "This script takes two arguments.\n";
		  print "*The first is the zip code to produce a weather report for\n";
		  print "*The second is an e-mail address to which to send the report\n";
		  exit;
}

$location = $ARGV[0];
$address = $ARGV[1];
$SEPARATE = time()."-$location-weatherreport";
$sendmailcommand = "/usr/sbin/sendmail -t";

# Use HTTP::Request to snarf the xml from accuweather
$request = HTTP::Request->new(GET => "http://forecastfox.accuweather.com/adcbin/forecastfox/weather_data.asp?location=$location");
$ua = LWP::UserAgent->new;
$weatherxml = $ua->request($request);

# Setup XML::Simple object to extract the data I'm interested in from the XML file delivered
# from accuweather.
my $xs1 = XML::Simple->new();
my $weatherreport = $xs1->XMLin($weatherxml->decoded_content);

if ($weatherreport->{watchwarnareas}->{isactive}){
   $warning = "Severe Weather Alert in Effect\n\n";
}else{
   $warning = "";
}

# Store the key informaiton into variables for use in formatting the message later
$city = $weatherreport->{local}->{city};
$state = $weatherreport->{local}->{state};

$radarurl = $weatherreport->{images}->{radar};
# $radarurl contains a lot of leading whitespace. eat it.
$radarurl =~ s/^\s*//;

# Fetch the image and store as base64 text
$request = HTTP::Request->new(GET => $radarurl);
$radargif = $ua->request($request);
@base64radar = encode_base64($radargif->decoded_content);
if (@base64radar == 0){
   exit;
}

$currenttemp = $weatherreport->{currentconditions}->{temperature};
$currenttext = $weatherreport->{currentconditions}->{weathertext};

for ($i=1;$i<=3;$i++){
   $idayname = $weatherreport->{forecast}->{day}[$i]->{daycode};
   $itxtlong = $weatherreport->{forecast}->{day}[$i]->{daytime}->{txtlong};
   $ihigh = $weatherreport->{forecast}->{day}[$i]->{daytime}->{hightemperature};
   $ilow = $weatherreport->{forecast}->{day}[$i]->{daytime}->{lowtemperature};

   $forecast[$i-1] = $idayname.": ".$itxtlong.", ".$ihigh."/".$ilow."\n\n";
}


# Open the sendmail command as a filehandle
open (SENDMAIL, "|$sendmailcommand");

# Print out an e-mail to the sendmail command
# Headers
print SENDMAIL "To: $address\n";
print SENDMAIL "From: Weather Report <adam\@bump.us>\n";
print SENDMAIL "Subject: Weather Report for $city, $state\n";
print SENDMAIL "Content-Type: multipart/mixed; type=\"application/smil\"; boundary=\"$SEPARATE\";\n\n";

# smil is the format for a picture message
print SENDMAIL "--$SEPARATE\n";
print SENDMAIL "Content-Type: application/smil; name=\"weather.smil\"\n";
print SENDMAIL "Content-Disposition: attachment; filename=\"weather.smil\"\n";
print SENDMAIL "\n"; 
print SENDMAIL "<smil xmlns=\"http://www.w3.org/2000/SMIL20/CR/Language\">\n";
print SENDMAIL "<head>\n";
print SENDMAIL "<layout>\n";
print SENDMAIL "<root-layout width=\"128\" height=\"115\" title=\"".$city.", ".$state." Weather Report\">\n";
print SENDMAIL "<region id=\"map\" height=\"115\" width=\"128\">\n";
print SENDMAIL "<region id=\"forecast\" height=\"115\" width=\"128\">\n";
print SENDMAIL "</layout>\n";
print SENDMAIL "</head>\n";
print SENDMAIL "<body>\n";
print SENDMAIL "<seq>\n";
print SENDMAIL "<img region=\"map\" src=\"radar.gif\" end=\"10s\" />\n";
print SENDMAIL "</seq>\n";
print SENDMAIL "<seq>\n";
print SENDMAIL "<img region=\"forecast\" src=\"weather.txt\" end=\"10s\" />\n";
print SENDMAIL "</seq>\n";
print SENDMAIL "</body>\n";
print SENDMAIL "</smil>\n";
print SENDMAIL "\n";

# Next up is the text of the weather report
print SENDMAIL "--$SEPARATE\n";
print SENDMAIL "Content-Type: text/plain\n";
print SENDMAIL "Content-Disposition: attachment; filename=\"weather.txt\"\n";
print SENDMAIL "\n"; 
print SENDMAIL "Weather From ".$city.", ".$state."\n\n";
print SENDMAIL $warning;
print SENDMAIL "Currently: $currenttext and $currenttemp\n\n";
print SENDMAIL @forecast;

# Add in the .gif radar image
print SENDMAIL "--$SEPARATE\n";
print SENDMAIL "Content-Type: image/gif;\n";
print SENDMAIL " name=\"radar.gif\";\n";
print SENDMAIL "Content-Transfer-Encoding: base64\n";
print SENDMAIL "Content-Disposition: inline; filename=\"radar.gif\"\n";
print SENDMAIL "\n";
print SENDMAIL @base64radar;
print SENDMAIL "--$SEPARATE--\n";

# All done, close out sendmail and the e-mail will take off.
close(SENDMAIL);

#Fin


