The podcasting technique described in Chapter 4 is a hotbed of development at the moment. One idea put forward was to use it to deliver weather forecasts via a web service and a text-to-speech application.
Jorge
Velázquez put together a script to do just that. Released
at http://www.jorgev.com/archives/000115.html,
it requires an account with weather.com and an installation of
Lame
(from http://lame.sourceforge.net/) and
text2wave
on the server.
The URL accepts two parameters,
locid
and
unit
.
The locid
is the weather.com location identifier
for the city you require. For U.S. cities, this can be a zip code,
and for non-U.S. cities, it is a special weather.com code. (e.g.,
92126 for San Diego, CA, or ITXX0067 for Rome, Italy). The unit
parameter is optional and can be either m
for
metric or s
for imperial measurements. It defaults
to imperial.
The location code for Florence, Italy, is ITXX0028, so the URL for the feed would be http://www.example.com/cgi-bin/weather.cgi?locid=ITXX0028. Simple.
Jorge’s code is, in his own words, very simple. This is how he describes it:
A brief explanation of how the script works, it’s actually quite simple: I first call into weather.com’s XML Data Feed. Then I use XPath to extract the data in which I am interested. I format this information into a text file, which I then pass onto the text2wave utility which performs the text-to-speech conversion. Finally, since wav files are so huge, I convert it to MP3 using the LAME encoder. Piece of cake, eh?
#!/usr/bin/perl -w # 2004-12-13 Jorge Velázquez use strict; use CGI qw(:standard); use XML::RSS; use XML::XPath; use LWP::Simple; use File::Temp; use File::Basename; # partner and key information my $par = 'partneridhere'; my $key = 'keyhere'; # get parameters my $cgi = CGI::new( ); my $locid = $cgi->param('locid'), my $unit = $cgi->param('unit'), if ( not $unit ) { $unit = 's'; } my $mp3dir = 'enter/mp3/path/here'; # query weather info, current conditions with 2 day forecast my $xml = get( "http://xoap.weather.com/weather/local/ $locid?cc=*&dayf=2&prod=xoap&par=$par&key=$key&unit=$unit" ); #load it into XPath object my $xp = XML::XPath->new($xml); # extract unit information from feed my $ut = $xp->findvalue('/weather/head/ut'), my $ud = $xp->findvalue('/weather/head/ud'), my $us = $xp->findvalue('/weather/head/us'), # create rss 2.0 feed my $rss = new XML::RSS( version => '2.0' ); # channel information $rss->channel( title => 'Weather Podcast', link => 'http://www.weather.com/', description => 'Local weather podcasting feed', language => 'en' ); # get current weather conditions my $dnam = $xp->findvalue('/weather/loc/dnam'), my $ccobst = $xp->findvalue('/weather/cc/obst'), my $cclsup = $xp->findvalue('/weather/cc/lsup'), my $cctemp = $xp->findvalue('/weather/cc/tmp'), my $ccwind = $xp->findvalue('/weather/cc/wind/s'), my $cct = $xp->findvalue('/weather/cc/t'), my $ccbarr = $xp->findvalue('/weather/cc/bar/r'), my $ccbard = $xp->findvalue('/weather/cc/bar/d'), # convert the units to words my $utword = $ut eq 'F' ? 'fahrenheit' : 'celsius'; # build the text file for converting to speech my $text = "Current conditions for $dnam. $cct. The temperature is $cctemp $utword."; # write the file and get the stats my $filename = &writefile($text); my $basename = basename $filename; my $filesize = ( stat $filename )[7]; # add rss item for current weather $rss->add_item( title => "Current weather conditions for $ccobst", link => "http://www.weather.com/weather/local/$locid", description => $text, pubDate => $cclsup, enclosure => { url => "$mp3dir$basename", length => $filesize, type => 'audio/mpeg' } ); # get forecast timestamp my $lsup = $xp->findvalue('/weather/dayf/lsup'), # iterate through forecast days my $nodeset = $xp->find('/weather/dayf/day'), foreach my $node ( $nodeset->get_nodelist ) { # get the items of interest to our script my $t = $node->findvalue('@t'), my $dt = $node->findvalue('@dt'), my $hi = $node->findvalue('hi'), my $low = $node->findvalue('low'), my $d = $node->findvalue('part[@p="d"]/t'), my $n = $node->findvalue('part[@p="n"]/t'), # build the text file for converting to speech $text = "Weather forecast for $t, $dt in $dnam. "; if ( $d eq 'N/A' ) { $text .= "Daytime conditions not available. "; } else { $text .= "Daytime $d. "; } if ( $n eq 'N/A' ) { $text .= "Nighttime conditions not available. "; } else { $text .= "Nighttime $n. "; } if ( $hi eq 'N/A' ) { $text .= "The high is unavailable. "; } else { $text .= "The high is $hi $utword. "; } if ( $low eq 'N/A' ) { $text .= "The low is unavailable. "; } else { $text .= "The low is $low $utword. "; } # write the file and get the stats $filename = &writefile($text); $basename = basename $filename; $filesize = ( stat $filename )[7]; # add this forecast $rss->add_item( title => "Weather forecast for $t, $dt at $dnam", link => "http://www.weather.com/weather/local/$locid", description => $text, pubDate => $lsup, enclosure => { url => "$mp3dir$basename", length => $filesize, type => 'audio/mpeg' } ); } print header('application/rss+xml'), print $rss->as_string; sub writefile { # write the text file my $fhtxt = new File::Temp( suffix => '.txt' ); print $fhtxt $_[0]; close $fhtxt; # write the wav file my $fhwav = new File::Temp( suffix => '.wav' ); system "text2wave", "-o", $fhwav->filename, $fhtxt->filename; # convert it to mp3 my $fhmp3 = new File::Temp( unlink => 0, dir => '../mp3', suffix => '.mp3' ); system "lame", "-h", $fhwav->filename, $fhmp3->filename; # return the file name return $fhmp3->filename; }
3.142.99.19