Podcasting Weather Forecasts

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.

How to Use It

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.

The Code Itself

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;
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.99.19