#
# weather.pl v0.1
# Fetch weather information for given city from FMI (Finnish Meteorological Institute).
# Returns always weather information for Helsinki if given city not found.
# Works ONLY with cities in Finland. Usage: !saa <city> (eg. !saa Turku).
# by Teemu Ikonen 4/2010 - http://iconen.org - teemu@iconen.org
#
use LWP::Simple;
use HTML::Entities;
OerPerl::add_command_handler("saa", "oer_weather_cmd");
sub oer_weather_cmd
{
my($command, $target, $nick, $userhost, $args) = @_;
my $tochan = OerPerl::is_valid_channel($target) ? 1 : 0;
my $target_type = $tochan ? OerPerl::CHANNEL : OerPerl::USER;
my($temp, $place, $details);
$temp = get "http://www.fmi.fi/saa/paikalli.html?place=" . ucfirst $args;
if(defined $temp) {
# Decode html entities to plain characters.
$_ = decode_entities($temp);
chomp;
# Trying to find city's measure point from <option> element (= given city has several measure points).
m/\<option value=\"\d+\" selected=\"selected\"\>(([a-z\xE4\xF6]+)\s([a-z\xE4\xF6\.\s\W]+))\<\/option\>/i;
if (!defined $2) {
# Not found - only one measure point for given city, so grab it's name.
m/\<p class=\"station-description\"\>(([a-z\xE4\xF6]+)\s([a-z\xE4\xF6\.\s\W]+))\</i;
# Set city and measure point name to variable.
$place = trim(encode_entities($2)) . " (" . trim(encode_entities($3)) . ")";
} else {
# Several measure points found, set city and first measure point name to variable.
$place = trim(encode_entities($2)) . " (" . trim(encode_entities($3)) . ")";
}
# Trying to find weather information.
m/\<p class=\"observation-text\"\>(.*)\<\/p\>/;
if (defined $1) {
# Weather information found, clean html tags etc.
$details = $1;
$details =~ s/Tuorein/tuorein/;
$details =~ s/Suomen aikaa//;
$details =~ s/\<[^\<]+\>//g;
} else {
# Not found, grab text for missing data and clean html tags etc.
m/\<p class=\"missing-data\"\>([a-z\.\s\W]*)\<\/p\>/i;
$details = $1;
$details =~ s/Havainnot/havainnot/;
$details =~ s/\<[^\<]+\>//g;
}
# We're finished, send weather information to user/channel if we have something to return.
OerPerl::sendto($tochan ? $target : $nick, $target_type, "$place $details") if defined $place && $details;
}
}
sub trim($)
{
my $str = shift;
$str =~ s/^(\s|\ )+//;
$str =~ s/(\s|\ )+$//;
return decode_entities($str);
}