VoIP Tech Chat

Patrick and Fred Chat… sometimes about VoIP

Perl Script to put Weather on your Polycom Microbrowser

7 comments

VoIP Geeks Rock

VoIP Geeks Rock

Note: This is one of VoIP Tech Chat’s more technical articles. If you’re not a techie (or a trekkie), you may want to skip this one. In fact, we’d love it if you instead read our What is a VoIP? article instead.

Here’s a quick little perl script to create a static html/xml file that can be displayed on your Polycom’s microbrowser. The script uses the Google weather API to check the weather based on a given zip code. The script, of course, is just an example and can be customized as needed.

For PHP coders, the same script can be modified to PHP and save yourself a step. For those of us that really like Perl, this script will create a static page. Using a cron job, you can easily make the page update every 10 minutes or so, and keep weather information current.

You can download the zipped file (weather.pl), or view the code and geeky discussion below…

First, let’s look at an example of the rendered code needed to display “nicely” on a Polycom’s microbrowser. The following would be appropriate for a larger screened phone, such as a SoundPoint IP 650:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>Fort Lauderdale, FL</head>
<body>
It is 70 F (21 C), Clear. High 79, Low 63, Mostly Sunny. Humidity: 87%. Wind: E at 0 mph. Tomorrow: Mostly Sunny.
</body>
</html>

The above will display a bold title of “Fort Lauderdale, FL” and then start with the weather conditions on the following line. For those with a smaller screen (such as the 450) you might want to kill the title and some of the weather info — something like:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
It is 70 F (21 C), Clear. High 79, Low 63, Mostly Sunny.
</body>
</html>

Now, for the perl script. First, if you don’t have the XML::TreePP module, you’ll need to install it. Which is as easy as:

# perl -MCPAN -e shell
cpan> install XML::TreePP

That’s it… the install should be pretty quick. Ok, next for the perl script (weather.pl):

#!/usr/bin/perl -w
use strict;
use XML::TreePP;

my $ZipCode = $ARGV[0];

if ($ZipCode =~ /^(\d{5})$/) {
	$ZipCode = $1;
	}
else {
	print qq(ERROR: invalid zipcode format\n);
	open (MYFILE, '>/var/www/html/polyweather.html');
	print MYFILE qq(ERROR: invalid zipcode format\n);
	close MYFILE;
	exit(0);
} 

my $url = "http://www.google.com/ig/api?weather=" . $ZipCode ;

my $tpp = XML::TreePP->new();
my $tree = $tpp->parsehttp( GET => $url );

my $city = $tree->{xml_api_reply}->{weather}->{forecast_information}->{city}->{"-data"};

if (length($city) < 1) {
	print "Unable to get info -- most likely a bad zip code. \n";
	open (MYFILE, '>/var/www/html/polyweather.html');
	print MYFILE qq(Unable to get info -- most likely a bad zip code.\n);
	close MYFILE;
	exit(0);
}

my $currtempf = $tree->{xml_api_reply}->{weather}->{current_conditions}->{temp_f}->{"-data"};
my $currtempc = $tree->{xml_api_reply}->{weather}->{current_conditions}->{temp_c}->{"-data"};
my $currhumidity = $tree->{xml_api_reply}->{weather}->{current_conditions}->{humidity}->{"-data"};
my $currcondition = $tree->{xml_api_reply}->{weather}->{current_conditions}->{condition}->{"-data"};
my $currwind = $tree->{xml_api_reply}->{weather}->{current_conditions}->{wind_condition}->{"-data"};
my $todayhigh = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[0]->{high}->{"-data"};
my $todaylow = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[0]->{low}->{"-data"};
my $todaycond = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[0]->{condition}->{"-data"};
my $tomorrowcond = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[1]->{condition}->{"-data"};

my $polyhtml = qq(<?xml version="1.0" encoding="utf-8"?>\n);
$polyhtml = $polyhtml . qq(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">\n);
$polyhtml = $polyhtml . qq(<html xmlns="http://www.w3.org/1999/xhtml">\n);
$polyhtml = $polyhtml . qq(<head>$city</head>\n);
$polyhtml = $polyhtml . qq(<body>\n);
$polyhtml = $polyhtml . qq-It is $currtempf F ($currtempc C), $currcondition. High $todayhigh, Low $todaylow, $todaycond. $currhumidity. $currwind. Tomorrow: $tomorrowcond. \n-;
$polyhtml = $polyhtml . qq(</body>\n);
$polyhtml = $polyhtml . qq(</html>\n);

open (MYFILE, '>/var/www/html/polyweather.html');
print MYFILE $polyhtml;
close MYFILE;

print $polyhtml;

How does it work?

Google has a nice little weather API which will provide a weather forecast for a given zip code via xml. A sample output looks like:

<?xml version="1.0"?>
	<xml_api_reply version="1">
		<weather module_id="0" tab_id="0">
			<forecast_information>
				<city data="Fort Lauderdale, FL"/>
				<postal_code data="33325"/>
				<latitude_e6 data=""/>
				<longitude_e6 data=""/>
				<forecast_date data="2009-01-05"/>
				<current_date_time data="2009-01-05 20:19:00 +0000"/>
				<unit_system data="US"/>
			</forecast_information>
			<current_conditions>
				<condition data="Clear"/>
				<temp_f data="77"/>
				<temp_c data="25"/>
				<humidity data="Humidity: 68%"/>
				<icon data="/images/weather/sunny.gif"/>
				<wind_condition data="Wind: E at 5 mph"/>
			</current_conditions>
		<forecast_conditions>
			<day_of_week data="Today"/>
			<low data="65"/>
			<high data="79"/>
			<icon data="/images/weather/mostly_sunny.gif"/>
			<condition data="Mostly Sunny"/>
		</forecast_conditions>
		<forecast_conditions>
			<day_of_week data="Tue"/>
			<low data="67"/>
			<high data="81"/>
			<icon data="/images/weather/mostly_sunny.gif"/>
			<condition data="Mostly Sunny"/>
		</forecast_conditions>
		<forecast_conditions>
			<day_of_week data="Wed"/>
			<low data="56"/>
			<high data="81"/>
			<icon data="/images/weather/chance_of_rain.gif"/>
			<condition data="Chance of Showers"/>
		</forecast_conditions><forecast_conditions>
			<day_of_week data="Thu"/>
			<low data="52"/>
			<high data="74"/>
			<icon data="/images/weather/sunny.gif"/>
			<condition data="Clear"/>
		</forecast_conditions>
	</weather>
</xml_api_reply>

A sample output for a bad zip code looks like:

<?xml version="1.0"?>
<xml_api_reply version="1">
	<weather module_id="0" tab_id="0">
		<problem_cause data=""/>
	</weather>
</xml_api_reply>

The perl script scrolls through the xml, parsing for the requested data and making a little webpage. To call the script, you would run something such as:

perl weather.pl 90210

The above would create the web page giving the weather for Brenda, Dylan, and the rest of the Beverly Hills crowd.

Now, for those that love the Mason Perl website engine (like Fred), you can code this in one quick dynamic file, this one is called weatherbyzip.html and is optimized for a smaller screen:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<% $message %>
</body>
</html>

<%init>
use XML::TreePP;
my $message = "";

if ($ZipCode =~ /^(\d{5})$/) {
	$ZipCode = $1;
	my $url = "http://www.google.com/ig/api?weather=" . $ZipCode ;
	my $tpp = XML::TreePP->new();
	my $tree = $tpp->parsehttp( GET => $url );
	my $city = $tree->{xml_api_reply}->{weather}->{forecast_information}->{city}->{"-data"};
	if (length($city) > 0) {
		my $currtempf = $tree->{xml_api_reply}->{weather}->{current_conditions}->{temp_f}->{"-data"};
		my $currtempc = $tree->{xml_api_reply}->{weather}->{current_conditions}->{temp_c}->{"-data"};
		my $currcondition = $tree->{xml_api_reply}->{weather}->{current_conditions}->{condition}->{"-data"};
		my $todayhigh = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[0]->{high}->{"-data"};
		my $todaylow = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[0]->{low}->{"-data"};
		my $todaycond = $tree->{xml_api_reply}->{weather}->{forecast_conditions}->[0]->{condition}->{"-data"};
		$message = "It is $currtempf F ($currtempc C), $currcondition. High $todayhigh, Low $todaylow, $todaycond.";
		}
		else {
			$message = "Unable to get info -- most likely a bad zip code.";
		}
	}
else {
	$message = "Invalid Zip Code." ;
} 

</%init>

<%args>
	$ZipCode => ''
</%args>

You would then call the page with weatherbyzip.html?ZipCode=90210

Ok… this was one of our more technical posts… we’ll be back to normal tomorrow. We promise.

Download the files:

Written by Fred

January 5th, 2009 at 8:50 pm

Posted in VoIP,tech

Tagged with , , , ,

7 Responses to 'Perl Script to put Weather on your Polycom Microbrowser'

Subscribe to comments with RSS or TrackBack to 'Perl Script to put Weather on your Polycom Microbrowser'.

  1. This could easily be adapted to work with Aastra phone displays too.

    Fred's Weather

  2. [...] Tech Chat posted a nice little script for putting a quick, no frills weather report directly onto your Polycom [...]

  3. [...] Cepstral. Since the parking spots wouldn’t change, maybe the weather would. So, using another script to check the weather, you can modify the results and create a sound file using Cepstral (and swift), such [...]


  4. <?php
    //god
    //syn
    //original idea: http://www.voiptechchat.com/voip/208/perl-script-to-put-weather-on-your-polycom-microbrowser/
    //Requires PHP 5 or greater

    //config:
    $zip = 33325; //default zipcode
    $showhead = 1; //show header
    $urlzip = 1; //allow URL defined zipcode
    $cache = 0; //cache
    $cachepath = "/var/www/mysite.com/cache"; //cache path (not used if cache == 0);
    //end config

    //credit where credit is due (class only)
    /*
    * Grabs weather data from Google.com's weather API and return a nicely formatted array
    * @author Ashwin Surajbali
    * @package Redink Design
    * @version 0.9.1
    * @url http://www.redinkdesign.net/google_weather_api_class
    */
    class googleWeather{
    public $zip;
    public $enable_cache = 0;
    public $cache_path = '';
    public $cache_time = 3600; // 1 hour
    private $cache_file;
    private $gweather_api_url = 'http://www.google.com/ig/api?weather=';
    private $raw_data;
    public function get_weather_data($zip = 0){
    if ($zip == 0 || strlen($zip) zip = $zip;
    }
    if ($this->enable_cache && !empty($this->cache_path)){
    $this->cache_file = $this->cache_path . '/' . $this->zip;
    return $this->load_from_cache();
    }
    // build the url
    $this->gweather_api_url = $this->gweather_api_url . $this->zip;
    if ($this->make_request()){
    $xml = new SimpleXMLElement($this->raw_data);
    $return_array = array();
    $return_array['forecast_info']['city'] = $xml->weather->forecast_information->city['data'];
    $return_array['forecast_info']['zip'] = $xml->weather->forecast_information->postal_code['data'];
    $return_array['forecast_info']['date'] = $xml->weather->forecast_information->forecast_date['data'];
    $return_array['forecast_info']['date_time'] = $xml->weather->forecast_information->current_date_time['data'];
    $return_array['current_conditions']['condition'] = $xml->weather->current_conditions->condition['data'];
    $return_array['current_conditions']['temp_f'] = $xml->weather->current_conditions->temp_f['data'];
    $return_array['current_conditions']['temp_c'] = $xml->weather->current_conditions->temp_c['data'];
    $return_array['current_conditions']['humidity'] = $xml->weather->current_conditions->humidity['data'];
    $return_array['current_conditions']['icon'] = 'http://www.google.com' . $xml->weather->current_conditions->icon['data'];
    $return_array['current_conditions']['wind'] = $xml->weather->current_conditions->wind_condition['data'];
    for ($i = 0; $i weather->forecast_conditions); $i++){
    $data = $xml->weather->forecast_conditions[$i];
    $return_array['forecast'][$i]['day_of_week'] = $data->day_of_week['data'];
    $return_array['forecast'][$i]['low'] = $data->low['data'];
    $return_array['forecast'][$i]['high'] = $data->high['data'];
    $return_array['forecast'][$i]['icon'] = 'http://www.google.com' . $data->icon['data'];
    $return_array['forecast'][$i]['condition'] = $data->condition['data'];
    }
    }
    if ($this->enable_cache && !empty($this->cache_path)){
    $this->write_to_cache();
    }
    return $return_array;
    }
    private function load_from_cache(){
    if (file_exists($this->cache_file)){
    $file_time = filectime($this->cache_file);
    $now = time();
    $diff = ($now-$file_time);
    if ($diff cache_file));
    }
    }
    }
    private function write_to_cache(){
    if (!file_exists($this->cache_path)){
    // attempt to make the dir
    mkdir($this->cache_path, 0777);
    }
    if (!file_put_contents($this->cache_file, serialize($return_array))){
    echo "Could not save data to cache. Please make sure your cache directory exists and is writable.";
    }
    }
    private function make_request(){
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_URL, $this->gweather_api_url);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $this->raw_data = curl_exec ($ch);
    curl_close ($ch);
    if (empty($this->raw_data)){
    return false;
    }else{
    return true;
    }
    }
    }
    //end class
    if (isset($_GET['z']) && $urlzip == 1){
    $zip = preg_replace("[^0-9]", "", $_GET['z']);
    }
    $w = new googleWeather();
    $w->enable_cache = 0;
    if ($usecache == 1){
    $w->enable_cache = 1;
    $w->cache_path = $cachepath;
    }
    $ar_data = $w->get_weather_data($zip);
    $currtempf = $ar_data['current_conditions']['temp_f'];
    $currtempc = $ar_data['current_conditions']['temp_c'];
    $currcondition = $ar_data['current_conditions']['condition'];
    $todayhigh = $ar_data['forecast'][0]['high'];
    $todaylow = $ar_data['forecast'][0]['low'];
    $todaycond = $ar_data['forecast'][0]['condition'];
    $currhumidity = $ar_data['current_conditions']['humidity'];
    $currwind = $ar_data['current_conditions']['wind'];
    $tomorrowcond = $ar_data['forecast'][1]['condition'];
    if ($showhead == 1){
    $city = "\n".$ar_data['forecast_info']['city']."\n\n";
    } else {
    $city = "\n\n\n";
    }
    echo "\n\n".$city."\n\n";
    echo "It is ".$currtempf."°F (".$currtempc."°C), ".$currcondition.". High ".$todayhigh.", Low ".$todaylow.", ".$todaycond.". ".$currhumidity.". ".$currwind.". Tomorrow: ".$tomorrowcond.".";
    echo "\n\n";
    ?>

    Php5 version. Doesn’t require a cron entry.

    syn

    12 Feb 09 at 5:20 am

  5. please change
    $urlzip = 1; //allow URL defined zipcode
    to
    $urlzip = 1; //allow URL defined zipcode (?z=zipcode)
    and delete this comment.

    syn

    12 Feb 09 at 5:23 am

  6. Thank you very much for this great piece of code, but you failed to mention a small fact about the need to execute this perl script with su (sudo) privileges and have the html folder created under /var/www/ prior to running it for the first time if using apache2 web server, because that’s where the resulting polyweather.html file is to be created.

    The only thing I haven’t figured out yet is how to get the weatherbyzip.html to work because all it shows on my web browser is the code that’s in it, nothing gets created worthy of looking at. Also, this php file isn’t working for me either even though I have the php5 installed (I’m using Ubuntu Intrepid).

    Thanks in advance!

    Dragan Tomas

    9 Apr 09 at 1:45 pm

  7. Cool code but I am not sure how to get the XML-TreePP perl module as we are behing firewall and proxy gateways info are not disclosed to users. I downloaded the XML-TreePP-0.39.tar.gz from CPAN.org and in PPM i set my repository to local with the ppd file. However the installation failed with

    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.

    C:\>perl
    -version
    Exit
    ;Quit
    Can’t locate object method “version” via package “Exit” (perhaps you forgot to l
    oad “Exit”?) at – line 1.

    C:\>perl ?
    Can’t open perl script “?”: Invalid argument

    C:\>perl -help

    Usage: C:\Perl\bin\perl.exe [switches] [--] [programfile] [arguments]
    -0[octal] specify record separator (, if no argument)
    -a autosplit mode with -n or -p (splits $_ into @F)
    -C enable native wide character system interfaces
    -c check syntax only (runs BEGIN and CHECK blocks)
    -d[:debugger] run program under debugger
    -D[number/list] set debugging flags (argument is a bit mask or alphabets)
    -e ‘command’ one line of program (several -e’s allowed, omit programfile)
    -F/pattern/ split() pattern for -a switch (//’s are optional)
    -i[extension] edit files in place (makes backup if extension supplied)
    -Idirectory specify @INC/#include directory (several -I’s allowed)
    -l[octal] enable line ending processing, specifies line terminator
    -[mM][-]module execute `use/no module…’ before executing program
    -n assume ‘while () { … }’ loop around program
    -p assume loop like -n but print line also, like sed
    -P run program through C preprocessor before compilation
    -s enable rudimentary parsing for switches after programfile
    -S look for programfile using PATH environment variable
    -T enable tainting checks
    -t enable tainting warnings
    -u dump core after parsing program
    -U allow unsafe operations
    -v print version, subversion (includes VERY IMPORTANT perl info)
    -V[:variable] print configuration summary (or a single Config.pm variable)
    -w enable many useful warnings (RECOMMENDED)
    -W enable all warnings
    -X disable all warnings
    -x[directory] strip off text before #!perl line and perhaps cd to directory

    C:\>PPM -help
    Unknown or ambiguous command ‘-help’; type ‘help’ for commands.

    C:\>ppm
    PPM – Programmer’s Package Manager version 3.0.1.
    Copyright (c) 2001 ActiveState SRL. All Rights Reserved.

    Entering interactive shell. Using Term::ReadLine::Stub as readline library.

    Profile tracking is not enabled. If you save and restore profiles manually,
    your profile may be out of sync with your computer. See ‘help profile’ for
    more information.

    Type ‘help’ to get started.

    ppm> help
    Type ‘help command’ for more detailed help on a command.
    Commands:
    describe – describes packages in detail
    exit – exits the program
    help – prints this screen, or help on ‘command’
    install – installs packages
    profiles – manage PPM profiles
    properties – describes installed packages in detail
    q – exits the program
    query – queries installed packages
    quickstart – a crash course in using PPM
    quit – exits the program
    remove – uninstalls packages
    repository – adds, removes, or sets repositories
    s – searches for packages in a repository – no help available
    search – searches for packages in a repository
    settings – view or set PPM options
    targets – views or sets target installer backends
    tree – shows package dependency tree
    uninstall – uninstalls packages
    upgrade – shows availables upgrades for installed packages
    version – displays the PPM version (3.0.1)
    Extra Help Topics: (not commands)
    ppm_migration – guide for those familiar with PPM
    prompt – how to interpret the PPM prompt
    unicode – notes about unicode author names
    ppm> install
    No search results to install — use ‘search’ to find a package.
    ppm> repository
    Repositories:
    [1] ActiveState PPM2 Repository
    [2] ActiveState Package Repository
    ppm> quit

    C:\>cd dload

    C:\dload>cd cpan

    C:\dload\cpan>dir
    Volume in drive C has no label.
    Volume Serial Number is 887B-3050

    Directory of C:\dload\cpan

    08/12/2009 09:06 AM .
    08/12/2009 09:06 AM ..
    08/12/2009 08:52 AM 80,485 XML-TreePP-0.39.tar.gz
    08/12/2009 09:06 AM 338 XML-TreePP.ppd
    2 File(s) 80,823 bytes
    2 Dir(s) 28,102,840,320 bytes free

    C:\dload\cpan>PPM
    PPM – Programmer’s Package Manager version 3.0.1.
    Copyright (c) 2001 ActiveState SRL. All Rights Reserved.

    Entering interactive shell. Using Term::ReadLine::Stub as readline library.

    Profile tracking is not enabled. If you save and restore profiles manually,
    your profile may be out of sync with your computer. See ‘help profile’ for
    more information.

    Type ‘help’ to get started.

    ppm> set repository localhost ./
    Unknown or ambiguous setting ‘repository’. See ‘help settings’.
    ppm> set
    case-sensitivity: 0
    download-chunksize: 16384
    fields: name version abstract
    follow-install: 1
    force-install: 0
    install-verbose: 1
    pager:
    profile-track: 0
    prompt-context: 0
    prompt-slotsize: 11
    prompt-verbose: 0
    remove-verbose: 1
    sort-field: name
    tempdir: C:\TEMP
    trace-file: ppm3.log
    trace-level: 0
    upgrade-verbose: 1
    verbose-startup: 1
    ppm> quit

    C:\dload\cpan>ppm3
    ‘ppm3′ is not recognized as an internal or external command,
    operable program or batch file.

    C:\dload\cpan>ppm
    PPM – Programmer’s Package Manager version 3.0.1.
    Copyright (c) 2001 ActiveState SRL. All Rights Reserved.

    Entering interactive shell. Using Term::ReadLine::Stub as readline library.

    Profile tracking is not enabled. If you save and restore profiles manually,
    your profile may be out of sync with your computer. See ‘help profile’ for
    more information.

    Type ‘help’ to get started.

    ppm> quit

    C:\dload\cpan>ppm2
    PPM interactive shell (2.1.6) – type ‘help’ for available commands.
    PPM> set repository localpc ./
    PPM> set
    Commands will be confirmed.
    Temporary files will be deleted.
    Download status will be updated every 16384 bytes.
    Case-sensitive searches will be performed.
    Package installations will continue if a dependency cannot be installed.
    Tracing info will not be written.
    Screens will pause after 24 lines.
    Query/search results will be verbose.
    Current PPD repository paths:
    localpc: ./
    ActiveState Package Repository: http://ppm.ActiveState.com/cgibin/PPM/pp
    mserver-5.8-windows.pl?urn:/PPMServer
    Packages will be built under: C:\DOCUME~1\98013\LOCALS~1\Temp
    PPM> install XML-TreePP
    Install package ‘XML-TreePP?’ (y/N): y
    Installing package ‘XML-TreePP’…
    Bytes transferred: 80485
    Writing C:\Perl\site\lib\auto\XML\TreePP\.packlist
    Duplicate POD found (shadowing?): Tk::CmdLine (C:\Perl\site\lib/Tk/CmdLine.pod)
    Already seen in C:\Perl\site\lib/Tk/CmdLine.pm
    PPM> locate
    Unknown or ambiguous command ‘locate’; type ‘help’ for commands.
    PPM> find
    Unknown or ambiguous command ‘find’; type ‘help’ for commands.
    PPM> help
    Commands:
    exit – leave the program.
    help [command] – prints this screen, or help on ‘command’.
    install PACKAGES – installs specified PACKAGES.
    quit – leave the program.
    query [options] – query information about installed packages.
    remove PACKAGES – removes the specified PACKAGES from the system.
    search [options] – search information about available packages.
    set [options] – set/display current options.
    verify [options] – verifies current install is up to date.
    version – displays PPM version number

    PPM> query
    Archive-Tar [0.072 ] module for manipulation of tar archives.
    Compress-Zlib [1.16 ] Interface to zlib compression library
    Digest-HMAC [1.01 ] Keyed-Hashing for Message Authentication
    Digest-MD2 [2 ] Perl interface to the MD2 Algorithm
    Digest-MD4 [1.1 ] Perl interface to the MD4 Algorithm
    Digest-SHA1 [2.01 ] Perl interface to the SHA-1 Algorithm
    File-CounterFile [0.12 ] Persistent counter class
    Font-AFM [1.18 ] Interface to Adobe Font Metrics files
    HTML-Parser [3.26 ] HTML parser class
    HTML-Tagset [3.03 ] Data tables useful in parsing HTML
    HTML-Tree [3.11 ] HTML syntax tree builder
    MD5 [2.02 ] Perl interface to the MD5 Algorithm (obsolete)
    PPM [2.1.6 ] Perl Package Manager: locate, install, upgrade
    software packages.
    SOAP-Lite [0.55 ] Library for Simple Object Access Protocol (SOAP)
    clients and servers in Perl
    Tk [800.024] A Graphical User Interface Toolkit
    URI [1.19 ] Uniform Resource Identifiers (absolute and relative)
    XML-Parser [2.31 ] A Perl module for parsing XML documents
    XML-Simple [1.06 ] Easy API to read/write XML (esp config files)
    XML-TreePP [6.3 ] Blah
    libwin32 [0.20 ] A collection of extensions that aims to provide
    comprehensive access to the Windows API.
    [Press return to continue or 'q' to quit]
    PPM> query XML-TreePP
    XML-TreePP [6.3] Blah
    PPM> uninstall
    Unknown or ambiguous command ‘uninstall’; type ‘help’ for commands.
    PPM> install XML-TreePP
    Install package ‘XML-TreePP?’ (y/N): y
    Installing package ‘XML-TreePP’…
    Bytes transferred: 80485
    Writing C:\Perl\site\lib\auto\XML\TreePP\.packlist
    Duplicate POD found (shadowing?): Tk::CmdLine (C:\Perl\site\lib/Tk/CmdLine.pod)
    Already seen in C:\Perl\site\lib/Tk/CmdLine.pm
    PPM> query XML-TreePP
    XML-TreePP [6.3] Blah
    PPM>

    Any Idea how to workaround this? Tks.

    BradPiper

    12 Aug 09 at 10:27 am

Leave a Reply