simbot-commits Mailing List for SimBot (Page 10)
Status: Abandoned
Brought to you by:
kstange
This list is closed, nobody may subscribe to it.
| 2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(88) |
Jun
(11) |
Jul
(64) |
Aug
(74) |
Sep
(1) |
Oct
(4) |
Nov
(12) |
Dec
(4) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
(7) |
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
(3) |
Oct
(1) |
Nov
(4) |
Dec
|
| 2007 |
Jan
(5) |
Feb
(3) |
Mar
(1) |
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Pete P. <fou...@us...> - 2005-05-08 02:04:24
|
Update of /cvsroot/simbot/simbot/data In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27037/data Added Files: postalcodes Removed Files: USzip Log Message: Replaced the USzip file with a postalcodes file. We now have UK post codes, and %weather <uk post code> works. --- NEW FILE: postalcodes --- SQLite format 3 ON postalcodes (code)l'tablecountriescountriesCREATE TABLE countries ( id INTEGER PRIMARY KEY, name STRING UNIQUE )1E code STRING UNIQUE, latitude REAL, longitude REAL, poname STRING, state STRING, country INTEGER, geocode INTEGER )5I# wôèÛÎÁ´¦ éúôîèâÜÖÏÈÁº³¬¥{t bÍz 2[Ö Z@2d¢eðõ¡ÀPË»äG=AGUADAPRC)[@2t¶¶àÒ=ÀPÉTu£LAGUADILLAPRE)\@2~WS£ìÀPȲNEFAGUADILLAPRE) ]@2wÛYWÀPÉKµáAGUADILLAPRE'^@2,FA,ðúÀP¼lP2ÏMARICAOPR&b@2IçBØÀPÈðÇ}ØsANASCOPRK'c@2GW÷7ÚÀP³VÀÖõEANGELESPRÍ'd@2s__(RÀP¬°SARECIBOPRM'e@2uE5ËÀP®åÂ.äARECIBOPRM'f@2mÿ.Hè§ÀP«+6½+ARECIBOPRM(h@2qÝãu ¾ÀP© [...9163 lines suppressed...] YO10 WR10 WR11 WR12 WR13 WR14 WR15 WS10 WS11 WS12 WS13 WS14 WS15 WV10 WV11 WV12 WV13 WV14 WV15 WV16 --- USzip DELETED --- |
|
From: Pete P. <fou...@us...> - 2005-05-08 02:04:24
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27037/plugins Modified Files: weather.pl Log Message: Replaced the USzip file with a postalcodes file. We now have UK post codes, and %weather <uk post code> works. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -p -r1.80 -r1.81 --- weather.pl 8 May 2005 00:22:36 -0000 1.80 +++ weather.pl 8 May 2005 02:04:15 -0000 1.81 @@ -62,7 +62,7 @@ use DBI; # for sqlite database use Time::Local; # declare globals -use vars qw( $session $dbh $zip_dbh ); +use vars qw( $session $dbh $postalcodes_dbh ); # These constants define the phrases simbot will use when responding # to weather requests. @@ -102,8 +102,8 @@ sub cleanup_wx { $dbh->disconnect; # We shouldn't have done anything to the zip codes DB, but just in case - $zip_dbh->rollback; - $zip_dbh->disconnect; + $postalcodes_dbh->rollback; + $postalcodes_dbh->disconnect; } ### messup_wx @@ -115,7 +115,7 @@ sub messup_wx { $dbh = DBI->connect('dbi:SQLite:dbname=data/weather','','', { RaiseError => 1, AutoCommit => 0 }) or die; - $zip_dbh = DBI->connect('dbi:SQLite:dbname=data/USzip','','', + $postalcodes_dbh = DBI->connect('dbi:SQLite:dbname=data/postalcodes','','', { RaiseError => 1, AutoCommit => 0 }) or die; # let's create the table. If this fails, we don't care, as it @@ -193,7 +193,9 @@ sub do_wx { my($station, $postalcode, $lat, $long, $state, $geocode); - if ($location =~ /^\d{5}$/) { $postalcode = $location; } + if ($location =~ /^\d{5}$/) { $postalcode = $location; } # US + elsif($location =~ /^([A-Z]{1,2}[0-9]{1,2}[A-Z]?)(?: [0-9][A-Z]{2})?$/) + { $postalcode = $1; } # UK elsif($location =~ /^[A-Z0-9]{4}$/i) { $station = $location; } if(defined $station) { @@ -211,9 +213,9 @@ sub do_wx { } if(defined $postalcode) { # try to get lat/long/state/geocode from the postalcode db - my $query = $zip_dbh->prepare_cached( - 'SELECT latitude, longitude, state, geocode FROM uszips' - . ' WHERE zip = ? LIMIT 1' + my $query = $postalcodes_dbh->prepare_cached( + 'SELECT latitude, longitude, state, geocode FROM postalcodes' + . ' WHERE code = ? LIMIT 1' ); $query->execute($postalcode); ($lat, $long, $state, $geocode) = $query->fetchrow_array; @@ -1028,8 +1030,8 @@ sub find_closest_station { my ($zipcode) = @_; # OK, we need the lat/long for that zip code. - my $query = $zip_dbh->prepare( - 'SELECT latitude, longitude FROM uszips WHERE zip = ?' + my $query = $postalcodes_dbh->prepare( + 'SELECT latitude, longitude FROM postalcodes WHERE code = ?' ); $query->execute($zipcode); my ($zip_lat, $zip_long) = $query->fetchrow_array; |
|
From: Pete P. <fou...@us...> - 2005-05-08 00:22:59
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6241/plugins Modified Files: weather.pl Log Message: Fixed a nothing to do error. Also, DO_ALERTS can now be added to DEFAULT_FLAGS to get alerts, forecasts, and conditions by default, when available. This is still too verbose to be usable though... Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.79 retrieving revision 1.80 diff -u -d -p -r1.79 -r1.80 --- weather.pl 7 May 2005 23:43:44 -0000 1.79 +++ weather.pl 8 May 2005 00:22:36 -0000 1.80 @@ -80,6 +80,7 @@ use constant CANNOT_ACCESS => 'Sorry; I use constant PI => 3.1415926; # Flags +use constant USING_DEFAULTS => 512; use constant RAW_METAR => 256; use constant FORCE_METAR => 128; use constant UNITS_METRIC => 64; @@ -90,7 +91,9 @@ use constant DO_FORECAST => 4; use constant DO_CONDITIONS => 2; use constant DO_ALERTS => 1; -use constant DEFAULT_FLAGS => DO_CONDITIONS | UNITS_AUTO; +# USING_DEFAULTS *MUST* be in DEFAULT_FLAGS, otherwise you'll get annoying +# error messages when things fail. +use constant DEFAULT_FLAGS => USING_DEFAULTS | DO_CONDITIONS | UNITS_AUTO; ### cleanup_wx # This method is run when SimBot is exiting. We save the station names @@ -221,8 +224,13 @@ sub do_wx { $station = &find_closest_station($postalcode); } - if($flags & DO_ALERTS && defined $state && defined $geocode) { - $kernel->post($session => 'get_alerts', $nick, $lat, $long, $state, $geocode, $flags); + if($flags & DO_ALERTS) { + if(defined $state && defined $geocode) { + $kernel->post($session => 'get_alerts', $nick, $lat, $long, $state, $geocode, $flags); + } elsif(!($flags & USING_DEFAULTS)) { + &SimBot::send_message(&SimBot::option('network', 'channel'), + "$nick: Sorry, but I have no forecast for that location."); + } } if($flags & DO_CONDITIONS && defined $station) { @@ -982,16 +990,21 @@ sub handle_user_command { } } - if($command =~ /^.metar$/) { $flags |= RAW_METAR; } + if($command =~ /^.metar$/) { $flags |= RAW_METAR | DO_CONDITIONS; } foreach(@args) { if(m/^metar$/) { $flags |= FORCE_METAR | DO_CONDITIONS; } if(m/^m(etric)?$/) { $flags |= UNITS_METRIC; } if(m/^f(ore)?cast$/) { $flags |= DO_FORECAST | DO_ALERTS; } if(m/^(us|imp(erial)?)$/) { $flags |= UNITS_IMPERIAL; } - if(m/^raw$/) { $flags |= RAW_METAR; } + if(m/^raw$/) { $flags |= RAW_METAR | DO_CONDITIONS; } if(m/^cond(itions)?/) { $flags |= DO_CONDITIONS; } } - if($flags == 0) { $flags |= DEFAULT_FLAGS; } + if($flags == 0 + || $flags == UNITS_METRIC + || $flags == UNITS_IMPERIAL) + { + $flags |= DEFAULT_FLAGS; + } $kernel->post($session => 'do_wx', $nick, $station, $flags); } |
|
From: Pete P. <fou...@us...> - 2005-05-07 23:44:00
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31278/plugins Modified Files: weather.pl Log Message: Moved around how things are called to allow for doing forecast and conditions. Forecasts are now unit converted, so if NOAA ever decides to send celcius, we'll deal with it. You can request a metric forecast with %weather fcast <zip> metric (or just m) Also beginning to replace references to the uszips db with postalcode. The DB will soon have UK codes, so finding stations should be easier for them too. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.78 retrieving revision 1.79 diff -u -d -p -r1.78 -r1.79 --- weather.pl 7 May 2005 22:19:13 -0000 1.78 +++ weather.pl 7 May 2005 23:43:44 -0000 1.79 @@ -80,14 +80,17 @@ use constant CANNOT_ACCESS => 'Sorry; I use constant PI => 3.1415926; # Flags -use constant RAW_METAR => 128; -use constant FORCE_METAR => 64; -use constant UNITS_METRIC => 32; -use constant UNITS_IMPERIAL => 16; +use constant RAW_METAR => 256; +use constant FORCE_METAR => 128; +use constant UNITS_METRIC => 64; +use constant UNITS_IMPERIAL => 32; +use constant UNITS_AUTO => 16; use constant NO_UNITS => 8; -# => 4; -# => 2; -# => 1; +use constant DO_FORECAST => 4; +use constant DO_CONDITIONS => 2; +use constant DO_ALERTS => 1; + +use constant DEFAULT_FLAGS => DO_CONDITIONS | UNITS_AUTO; ### cleanup_wx # This method is run when SimBot is exiting. We save the station names @@ -169,70 +172,123 @@ sub bootstrap { ### do_wx # this is called when POE tells us someone wants weather sub do_wx { - my ($kernel, $nick, $station, $flags) = + my ($kernel, $nick, $location, $flags) = @_[KERNEL, ARG0, ARG1, ARG2]; &SimBot::debug(3, 'weather: Received request from ' . $nick - . " for $station\n"); + . " for $location\n"); - if(length($station) != 4) { - # Whine and bail + # So, what are we doing? + unless($flags & DO_CONDITIONS + || $flags & DO_ALERTS || $flags & DO_FORECAST) + { &SimBot::send_message(&SimBot::option('network', 'channel'), - "$nick: " - . ($station ? STATION_LOOKS_WRONG - : STATION_UNSPECIFIED) - . FIND_STATION_AT); + "$nick: Sorry, something unexpected happened. This has been logged, please try again later."); + &SimBot::debug(1, "weather: in do_wx with nothing to do!\n"); return; } - - $station = uc($station); - # Try to look up the station in the database. - # if it is there, check for a URL - # if there is no URL, it's metar, go do that - # if there is a URL, it's XML, go do that - # if it is not there, it's metar, go do that. - my $query = $dbh->prepare( - 'SELECT name, url FROM stations' - . ' WHERE id = ?' - ); - $query->execute($station); - my ($station_name, $url); - if((($station_name, $url) = $query->fetchrow_array) - && !($flags & RAW_METAR) - && !($flags & FORCE_METAR) - && (defined $url)) { - my $request = HTTP::Request->new(GET=>$url); - $kernel->post('wxua' => 'request', 'got_xml', - $request, "$nick!$station"); + my($station, $postalcode, $lat, $long, $state, $geocode); + + if ($location =~ /^\d{5}$/) { $postalcode = $location; } + elsif($location =~ /^[A-Z0-9]{4}$/i) { $station = $location; } + + if(defined $station) { + # try to get lat/long/state from the station + my $query = $dbh->prepare_cached( + 'SELECT latitude, longitude, state FROM stations' + . ' WHERE id = ? LIMIT 1' + ); + $query->execute($station); + ($lat, $long, $state) = $query->fetchrow_array; + $query->finish; - return; + # FIXME: OK, now try to get the geocode from the lat/long + # (find nearest zip, use it's geocode) + } + if(defined $postalcode) { + # try to get lat/long/state/geocode from the postalcode db + my $query = $zip_dbh->prepare_cached( + 'SELECT latitude, longitude, state, geocode FROM uszips' + . ' WHERE zip = ? LIMIT 1' + ); + $query->execute($postalcode); + ($lat, $long, $state, $geocode) = $query->fetchrow_array; + $query->finish; } - - # Damn, guess we need to parse METAR. - # do we have a station name? - unless(defined $station_name) { - &SimBot::debug(4, - "weather: Station name not found, looking it up\n"); - my $url = - 'http://weather.noaa.gov/cgi-bin/nsd_lookup.pl?station=' - . $station; - my $request = HTTP::Request->new(GET => $url); - $kernel->post('wxua' => 'request', 'got_station_name', - $request, "$nick!$station!$flags"); - # We're done here - got_station_name will handle requesting - # the weather - return; + if(defined $postalcode && !defined $station) { + $station = &find_closest_station($postalcode); + } + + if($flags & DO_ALERTS && defined $state && defined $geocode) { + $kernel->post($session => 'get_alerts', $nick, $lat, $long, $state, $geocode, $flags); + } + + if($flags & DO_CONDITIONS && defined $station) { + if(length($station) != 4) { + # Whine and bail + &SimBot::send_message(&SimBot::option('network', 'channel'), + "$nick: " + . ($station ? STATION_LOOKS_WRONG + : STATION_UNSPECIFIED) + . FIND_STATION_AT); + return; + } + + $station = uc($station); + + # Try to look up the station in the database. + # if it is there, check for a URL + # if there is no URL, it's metar, go do that + # if there is a URL, it's XML, go do that + # if it is not there, it's metar, go do that. + my $query = $dbh->prepare( + 'SELECT name, url FROM stations' + . ' WHERE id = ?' + ); + $query->execute($station); + my ($station_name, $url); + if((($station_name, $url) = $query->fetchrow_array) + && !($flags & RAW_METAR) + && !($flags & FORCE_METAR) + && (defined $url)) { + my $request = HTTP::Request->new(GET=>$url); + $kernel->post('wxua' => 'request', 'got_xml', + $request, "$nick!$station"); + + return; + } + + # Damn, guess we need to parse METAR. + + # do we have a station name? + unless(defined $station_name) { + &SimBot::debug(4, + "weather: Station name not found, looking it up\n"); + my $url = + 'http://weather.noaa.gov/cgi-bin/nsd_lookup.pl?station=' + . $station; + my $request = HTTP::Request->new(GET => $url); + $kernel->post('wxua' => 'request', 'got_station_name', + $request, "$nick!$station!$flags"); + # We're done here - got_station_name will handle requesting + # the weather + return; + } + # we already have the station name... let's request the weather + + $url = + 'http://weather.noaa.gov/pub/data/observations/metar/stations/' + . $station . '.TXT'; + my $request = HTTP::Request->new(GET=>$url); + $kernel->post('wxua' => 'request', 'got_metar', + $request, "$nick!$station!$flags"); + } + + if($flags & DO_FORECAST && defined $lat) { + } - # we already have the station name... let's request the weather - - $url = - 'http://weather.noaa.gov/pub/data/observations/metar/stations/' - . $station . '.TXT'; - my $request = HTTP::Request->new(GET=>$url); - $kernel->post('wxua' => 'request', 'got_metar', - $request, "$nick!$station!$flags"); } sub got_station_name { @@ -712,15 +768,20 @@ sub got_xml { sub got_alerts { my ($kernel, $request_packet, $response_packet) = @_[KERNEL, ARG0, ARG1]; - my ($nick, $lat, $long, $geocode) - = (split(/!/, $request_packet->[1], 4)); + my ($nick, $lat, $long, $geocode, $flags) + = (split(/!/, $request_packet->[1], 5)); my $response = $response_packet->[0]; + if(!defined $flags) { + my @caller = caller(1); + warn "get_forecast called with no flags from $caller[3] line $caller[2]"; + } + if ($response->is_error) { # The server isn't being nice to us. # Let's just move on to getting the forecast &SimBot::send_message(&SimBot::option('network', 'channel'), - "$nick: " . &get_forecast($nick, $lat, $long)); + "$nick: " . &get_forecast($nick, $lat, $long, $flags)); return; } my $raw_xml = $response->decoded_content; @@ -733,7 +794,7 @@ sub got_alerts { # Bad XML! Let's just move on to getting the forecast. &SimBot::send_message(&SimBot::option('network', 'channel'), - "$nick: " . &get_forecast($nick, $lat, $long)); + "$nick: " . &get_forecast($nick, $lat, $long, $flags)); return; } @@ -763,11 +824,22 @@ sub got_alerts { } # OK, we're done with the alerts... now do the forecast &SimBot::send_message(&SimBot::option('network', 'channel'), - "$nick: " . &get_forecast($nick, $lat, $long)); + "$nick: " . &get_forecast($nick, $lat, $long, $flags)); } sub get_forecast { - my ($nick, $lat, $long) = @_; + my ($nick, $lat, $long, $flags) = @_; + + if(!defined $flags) { + my @caller = caller(1); + warn "get_forecast called with no flags from $caller[3] line $caller[2]"; + $flags = UNITS_IMPERIAL; + } + + if(! ($flags & UNITS_IMPERIAL || $flags & UNITS_METRIC)) { + # Trying to provide both units is fugly. + $flags |= UNITS_IMPERIAL; + } my $serviceURI = 'http://weather.gov/forecasts/xml'; my $method = 'NDFDgenByDay'; @@ -855,12 +927,13 @@ sub get_forecast { if($conditions[$i]) { $cur_msg .= $conditions[$i] . ', '; } if($temp_highs[$i] && $temp_lows[$i] && $temp_highs[$i] !~ /^HASH/ - && $temp_lows[$i] !~ /^HASH/) { - $cur_msg .= $temp_highs[$i] . '/' . $temp_lows[$i]; + && $temp_lows[$i] !~ /^HASH/) + { + $cur_msg .= &temp($temp_highs[$i], $temp_highs_unit, $flags | NO_UNITS) . '/' . &temp($temp_lows[$i], $temp_lows_unit, $flags); } elsif($temp_highs[$i] && $temp_highs[$i] !~ /^HASH/) { - $cur_msg .= 'high ' . $temp_highs[$i]; + $cur_msg .= 'high ' . &temp($temp_highs[$i], $temp_highs_unit, $flags); } elsif($temp_lows[$i] && $temp_lows[$i] !~ /^HASH/) { - $cur_msg .= 'low ' . $temp_lows[$i]; + $cur_msg .= 'low ' . &temp($temp_lows[$i], $temp_lows_unit, $flags); } $cur_msg .= '; '; $msg .= $cur_msg; @@ -899,38 +972,32 @@ sub handle_user_command { my ($lat, $long, $state, $geocode); if($station =~ /f(ore)?cast/) { - if(defined $args[0] && $args[0] =~ /^\d{5}$/) { # zip code - my $get_lat_long_query = $zip_dbh->prepare_cached( - 'SELECT latitude, longitude, state, geocode FROM uszips' - . ' WHERE zip = ? LIMIT 1'); - $get_lat_long_query->execute($args[0]); - if(($lat, $long, $state, $geocode) = $get_lat_long_query->fetchrow_array) { - $kernel->post($session => 'get_alerts', $nick, $lat, $long, $state, $geocode); - } else { - &SimBot::send_message($channel, "$nick: I do not know where that zip code is."); - } - $get_lat_long_query->finish; + if(@args) { + $station = shift(@args); + $flags &= ~DO_CONDITIONS; + $flags |= DO_FORECAST | DO_ALERTS; } else { - &SimBot::send_message($channel, "$nick: For what US Zip code do you want a forecast?"); + &SimBot::send_message($channel, "$nick: For what US ZIP code do you want a forecast?"); + return; } - return; - } elsif($station =~ /^(\d\d\d\d\d)$/) { - $station = &find_closest_station($station); } if($command =~ /^.metar$/) { $flags |= RAW_METAR; } foreach(@args) { - if(m/^metar$/) { $flags |= FORCE_METAR; } + if(m/^metar$/) { $flags |= FORCE_METAR | DO_CONDITIONS; } if(m/^m(etric)?$/) { $flags |= UNITS_METRIC; } + if(m/^f(ore)?cast$/) { $flags |= DO_FORECAST | DO_ALERTS; } if(m/^(us|imp(erial)?)$/) { $flags |= UNITS_IMPERIAL; } if(m/^raw$/) { $flags |= RAW_METAR; } + if(m/^cond(itions)?/) { $flags |= DO_CONDITIONS; } } + if($flags == 0) { $flags |= DEFAULT_FLAGS; } $kernel->post($session => 'do_wx', $nick, $station, $flags); } sub get_alerts { - my ($kernel, $nick, $lat, $long, $state, $geocode) = - @_[KERNEL, ARG0, ARG1, ARG2, ARG3, ARG4 ]; + my ($kernel, $nick, $lat, $long, $state, $geocode, $flags) = + @_[KERNEL, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5 ]; &SimBot::debug(3, 'weather: Received forecast request from ' . $nick . " for $lat $long $geocode, in get_alerts\n"); @@ -939,7 +1006,7 @@ sub get_alerts { my $request = HTTP::Request->new(GET => $url); $request->header('Accept-Encoding' => 'gzip, deflate'); $kernel->post('wxua' => 'request', 'got_alerts', - $request, "$nick!$lat!$long!$geocode"); + $request, "$nick!$lat!$long!$geocode!$flags"); # We're done here - got_alerts will handle requesting the forecast } @@ -1019,8 +1086,8 @@ sub temp { return $temp; } - if( ($unit =~ m/C/i && $flags & UNITS_METRIC) - || ($unit =~ m/F/i && $flags & UNITS_IMPERIAL)) + if( ($unit =~ s/^C.*$/C/i && $flags & UNITS_METRIC) + || ($unit =~ s/^F.*$/F/i && $flags & UNITS_IMPERIAL)) { # Temperature is already in the desired units. return (int $temp) . ($flags & NO_UNITS ? '' : '°' . $unit); |
|
From: Pete P. <fou...@us...> - 2005-05-07 22:19:36
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14028/plugins Modified Files: weather.pl Log Message: Added a missing ), got_wx is now got_metar Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.77 retrieving revision 1.78 diff -u -d -p -r1.77 -r1.78 --- weather.pl 7 May 2005 21:37:21 -0000 1.77 +++ weather.pl 7 May 2005 22:19:13 -0000 1.78 @@ -148,7 +148,7 @@ EOT inline_states => { _start => \&bootstrap, do_wx => \&do_wx, - got_wx => \&got_wx, + got_metar => \&got_metar, got_xml => \&got_xml, get_alerts => \&get_alerts, got_alerts => \&got_alerts, @@ -231,7 +231,7 @@ sub do_wx { 'http://weather.noaa.gov/pub/data/observations/metar/stations/' . $station . '.TXT'; my $request = HTTP::Request->new(GET=>$url); - $kernel->post('wxua' => 'request', 'got_wx', + $kernel->post('wxua' => 'request', 'got_metar', $request, "$nick!$station!$flags"); } @@ -286,11 +286,11 @@ sub got_station_name { 'http://weather.noaa.gov/pub/data/observations/metar/stations/' . $station . '.TXT'; my $request = HTTP::Request->new(GET=>$url); - $kernel->post('wxua' => 'request', 'got_wx', + $kernel->post('wxua' => 'request', 'got_metar', $request, "$nick!$station!$flags"); } -sub got_wx { +sub got_metar { # This parses METAR reports. # This should be replaced with something. # Either stop using Geo::METAR, or find some service that gives @@ -583,7 +583,7 @@ sub got_xml { 'http://weather.noaa.gov/pub/data/observations/metar/stations/' . $station . '.TXT'; my $request = HTTP::Request->new(GET=>$url); - $kernel->post('wxua' => 'request', 'got_wx', + $kernel->post('wxua' => 'request', 'got_metar', $request, "$nick!$station!0"); return; } elsif ($response->is_error) { @@ -606,7 +606,7 @@ sub got_xml { 'http://weather.noaa.gov/pub/data/observations/metar/stations/' . $station . '.TXT'; my $request = HTTP::Request->new(GET=>$url); - $kernel->post('wxua' => 'request', 'got_wx', + $kernel->post('wxua' => 'request', 'got_metar', $request, "$nick!$station!0"); return; } @@ -922,7 +922,7 @@ sub handle_user_command { foreach(@args) { if(m/^metar$/) { $flags |= FORCE_METAR; } if(m/^m(etric)?$/) { $flags |= UNITS_METRIC; } - if(m/^(us|imp(erial)?$/) { $flags |= UNITS_IMPERIAL; } + if(m/^(us|imp(erial)?)$/) { $flags |= UNITS_IMPERIAL; } if(m/^raw$/) { $flags |= RAW_METAR; } } $kernel->post($session => 'do_wx', $nick, $station, $flags); |
|
From: Pete P. <fou...@us...> - 2005-05-07 21:37:30
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5128/plugins Modified Files: weather.pl Log Message: The beginnings of unit conversion. Only in metar reports right now. Use %weather <station> metric (or m) to show only metric, imp for imperial. Omit for both. Currently only temps and wind are converted. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.76 retrieving revision 1.77 diff -u -d -p -r1.76 -r1.77 --- weather.pl 7 May 2005 18:06:20 -0000 1.76 +++ weather.pl 7 May 2005 21:37:21 -0000 1.77 @@ -67,7 +67,7 @@ use vars qw( $session $dbh $zip_dbh ); # These constants define the phrases simbot will use when responding # to weather requests. use constant STATION_LOOKS_WRONG => - 'That doesn\'t look like a METAR station. '; + q(That doesn't look like a METAR station. ); #' use constant STATION_UNSPECIFIED => 'Please provide a METAR station ID. '; @@ -82,9 +82,9 @@ use constant PI => 3.1415926; # Flags use constant RAW_METAR => 128; use constant FORCE_METAR => 64; -#use constant USE_METRIC => 32; # future use -#use constant USE_IMPERIAL => 16; # future use -# => 8; +use constant UNITS_METRIC => 32; +use constant UNITS_IMPERIAL => 16; +use constant NO_UNITS => 8; # => 4; # => 2; # => 1; @@ -391,8 +391,7 @@ sub got_wx { my $temp_f = (defined $m->TEMP_F ? $m->TEMP_F : (9/5)*$temp_c+32); - my $temp = $temp_f . '°F (' . int($temp_c) . '°C)'; - push(@reply_with, $temp); + push(@reply_with, &temp($temp_c, 'C', $flags)); # this nonsense checks for the odd wind declaration NZSP # gives. I dunno what to make of the first part, I @@ -409,10 +408,9 @@ sub got_wx { my $windchill = 35.74 + (0.6215 * $temp_f) - 35.75 * ($wind_mph ** 0.16) + 0.4275 * $temp_f * ($wind_mph ** 0.16); - my $windchill_c = ($windchill - 32) * (5/9); - push(@reply_with, - sprintf('a wind chill of %.1f°F (%.1f°C)', - $windchill, $windchill_c)); + + push(@reply_with, 'a wind chill of ' + . &temp($windchill, 'F', $flags)); } # Humidity, only if we have a dewpoint! @@ -435,10 +433,8 @@ sub got_wx { - 0.00000199 * $temp_f ** 2 * $humidity ** 2; - my $heatindex_c = ($heatindex - 32) * (5/9); - push(@reply_with, - sprintf('a heat index of %.1f°F (%.1f°C)', - $heatindex, $heatindex_c)); + push(@reply_with, 'a heat index of ' + . &temp($heatindex, 'F', $flags)); } } } else { @@ -447,7 +443,7 @@ sub got_wx { } if($wind_mph) { - my $tmp = int($wind_mph) . ' mph'; + my $tmp = &speed($wind_mph, 'MPH', $flags); if ($m->WIND_DIR_ENG) { $tmp .= ' winds from the ' . $m->WIND_DIR_ENG; } else { @@ -890,14 +886,14 @@ sub nlp_match { } if (defined $station) { - &new_get_wx($kernel, $nick, $channel, " weather", $station); + &handle_user_command($kernel, $nick, $channel, " weather", $station); return 1; } else { return 0; } } -sub new_get_wx { +sub handle_user_command { my ($kernel, $nick, $channel, $command, $station, @args) = @_; my $flags = 0; @@ -925,7 +921,8 @@ sub new_get_wx { if($command =~ /^.metar$/) { $flags |= RAW_METAR; } foreach(@args) { if(m/^metar$/) { $flags |= FORCE_METAR; } -# if(m/^metric$/) { $flags |= USE_METRIC; } + if(m/^m(etric)?$/) { $flags |= UNITS_METRIC; } + if(m/^(us|imp(erial)?$/) { $flags |= UNITS_IMPERIAL; } if(m/^raw$/) { $flags |= RAW_METAR; } } $kernel->post($session => 'do_wx', $nick, $station, $flags); @@ -1003,23 +1000,104 @@ sub acos { } sub deg2rad { - my ($deg) = @_; - return ($deg * PI / 180); + my ($deg) = @_; + return ($deg * PI / 180); } sub rad2deg { - my ($rad) = @_; - return ($rad * 180 / PI); + my ($rad) = @_; + return ($rad * 180 / PI); +} + +sub temp { + my ($temp, $unit, $flags) = @_; + if(!defined $unit + || $unit !~ m/C|F/i) + { + my @caller = caller(1); + warn "unit missing or invalid in temp, called from $caller[3] line $caller[2]"; + return $temp; + } + + if( ($unit =~ m/C/i && $flags & UNITS_METRIC) + || ($unit =~ m/F/i && $flags & UNITS_IMPERIAL)) + { + # Temperature is already in the desired units. + return (int $temp) . ($flags & NO_UNITS ? '' : '°' . $unit); + } + + my ($temp_c, $temp_f); + if($unit =~ /C/i) { + $temp_c = $temp; + $temp_f = $temp * 1.8 + 32; + } elsif($unit =~ /F/i) { + $temp_f = $temp; + $temp_c = ($temp - 32) * (5/9); + } + + if($flags & UNITS_METRIC) { + return (int $temp_c) + . ($flags & NO_UNITS ? '' : '°C'); + } + + if($flags & UNITS_IMPERIAL) { + return (int $temp_f) + . ($flags & NO_UNITS ? '' : '°F'); + } + + return (int $temp_f) . ($flags & NO_UNITS ? '' : '°F') + . ' (' . (int $temp_c) . ($flags & NO_UNITS ? '' : '°C') . ')'; +} + +sub speed { + my ($speed, $unit, $flags) = @_; + + if(!defined $unit + || $unit !~ m(kt|km/h|mph)i) + { + my @caller = caller(1); + warn "unit missing or invalid in speed, called from $caller[3] line $caller[2]"; + return $speed; + } + + if($unit =~ m(mph)) { $unit = 'MPH'; } + + if( ($unit =~ m(km/h)i && $flags & UNITS_METRIC) + || ($unit =~ m(MPH)i && $flags & UNITS_IMPERIAL)) + { + return (int $speed) . ($flags & NO_UNITS ? '' : ' ' . $unit); + } + + my ($speed_kmh, $speed_mph); + if($unit =~ /kt/i) { + $speed_kmh = 1.85325 * $speed; + $speed_mph = 1.15155 * $speed; + } elsif($unit =~ /MPH/i) { + $speed_kmh = 1.609344 * $speed; + $speed_mph = $speed; + } elsif($unit =~ m(km/h)i) { + $speed_kmh = $speed; + $speed_mph = 0.621371; + } + + if($flags & UNITS_METRIC) { + return (int $speed_kmh) . ($flags & NO_UNITS ? '' : ' km/h'); + } + + if($flags & UNITS_IMPERIAL) { + return (int $speed_mph) . ($flags & NO_UNITS ? '' : ' MPH'); + } + return (int $speed_mph) . ($flags & NO_UNITS ? '' : ' MPH'). ' (' . (int $speed_kmh) . ($flags & NO_UNITS ? '' : ' km/h') . ')'; } # Register Plugins &SimBot::plugin_register( plugin_id => "weather", - plugin_params => "(<station ID|zip> [metar|raw] | forecast <zip>)", + plugin_params => "(<station ID|zip> [metar|raw] [metric|us] | forecast <zip>)", plugin_help => "Gets a weather report for the given station or zip.\nSpecifying %bold%metar%bold% will force the parsing the metar report instead of using the NOAA XML data.\nSpecifying %bold%raw%bold% will show the METAR report in its original form.\nforecast <zip> will get the forecast for that US zip code.", - event_plugin_call => \&new_get_wx, + event_plugin_call => \&handle_user_command, event_plugin_load => \&messup_wx, event_plugin_unload => \&cleanup_wx, @@ -1040,6 +1118,7 @@ sub rad2deg { plugin_params => "<station ID>", plugin_help => "Gives a raw METAR report for the given station.", - event_plugin_call => \&new_get_wx, + event_plugin_call => \&handle_user_command, ); + |
|
From: Pete P. <fou...@us...> - 2005-05-07 18:39:51
|
Update of /cvsroot/simbot/simbot/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29823/tools Modified Files: create_wx_station_db.pl Log Message: Get the directory listing of the folder where all the METAR reports are, remove any stations that don't have reports from our known stations. Index: create_wx_station_db.pl =================================================================== RCS file: /cvsroot/simbot/simbot/tools/create_wx_station_db.pl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -p -r1.3 -r1.4 --- create_wx_station_db.pl 7 May 2005 03:53:32 -0000 1.3 +++ create_wx_station_db.pl 7 May 2005 18:39:41 -0000 1.4 @@ -28,6 +28,7 @@ use Compress::Zlib; use LWP::UserAgent; use DBI; use XML::Simple; +use File::Listing; use warnings; use strict; @@ -85,7 +86,7 @@ if($response->is_error) { while($content) { if(++$line_count % 300 == 0) { print '.'; } ($cur_line, $content) = split(/\n/, $content, 2); - my ($station, undef, undef, $name, $state, $country, undef, $lat_dms, $long_dms) = split(/;/, $cur_line, 10); + my ($station, undef, undef, $name, $state, $country, undef, $lat_dms, $long_dms, undef, undef, $rbsn) = split(/;/, $cur_line); my ($long_deg); my ($lat_deg, $minutes, $seconds, $dir) = $lat_dms @@ -108,7 +109,7 @@ if($response->is_error) { ); } } - print "\nDone! Read $line_count lines\n" + print " Done! Read $line_count lines\n" } # now let's get the XML data file. @@ -138,10 +139,54 @@ if($response->is_error) { $cur_station->{'station_id'} ); } - print "\nDone! Read $line_count lines\n"; + print " Done! Read $line_count lines\n"; } } +# OK, now we have a great list of station codes. However, not all have +# METAR reports. Let's find codes to remove... + +print "Downloading METAR directory listing (this may take a while)... "; +$response = $ua->get('ftp://weather.noaa.gov/data/observations/metar/stations/'); + +if($response->is_error) { + print STDERR "Failed! " . $response->code . ' ' . $response->message . "\n"; +} else { + my $line_count = 0; + print "Done!\nReading it in"; + + # Stations with URLs are XML stations, we don't care if METAR is unavailable + # Create a temprary table as a list of candidates for deletion + $dbh->do(<<EOT); +CREATE TEMPORARY TABLE delrows AS SELECT id FROM stations WHERE url IS NULL; +CREATE UNIQUE INDEX delstationid ON delrows (id); +EOT + + my $remove_from_deletion_list_query = $dbh->prepare( + 'DELETE FROM delrows WHERE id = ?'); + + my @listing = parse_dir($response->content); + + foreach my $cur_file (@listing) { + if(++$line_count % 300 == 0) { print '.'; } + my ($name) = @$cur_file; + + if($name =~ /^([A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9])/) { + $remove_from_deletion_list_query->execute($1); + } + } + print " Done! Read $line_count lines.\n"; + + my $useless_fact_query = $dbh->prepare('SELECT count() FROM delrows'); + $useless_fact_query->execute; + my ($deletion_count) = $useless_fact_query->fetchrow_array; + print "Removing $deletion_count stations without reports... "; + + $dbh->do( + 'DELETE FROM stations WHERE id IN (SELECT id FROM delrows)'); + print "Done!\n"; +} + { local $dbh->{RaiseError}; # let's not die on errors local $dbh->{PrintError}; # and let's be quiet |
|
From: Pete P. <fou...@us...> - 2005-05-07 18:06:29
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21716/plugins Modified Files: weather.pl Log Message: Help text Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.75 retrieving revision 1.76 diff -u -d -p -r1.75 -r1.76 --- weather.pl 7 May 2005 18:03:29 -0000 1.75 +++ weather.pl 7 May 2005 18:06:20 -0000 1.76 @@ -1015,9 +1015,9 @@ sub rad2deg { # Register Plugins &SimBot::plugin_register( plugin_id => "weather", - plugin_params => "(<station ID> [metar|raw] | forecast <zip>)", + plugin_params => "(<station ID|zip> [metar|raw] | forecast <zip>)", plugin_help => -"Gets a weather report for the given station.\nSpecifying %bold%metar%bold% will force the parsing the metar report instead of using the NOAA XML data.\nSpecifying %bold%raw%bold% will show the METAR report in its original form.\nforecast <zip> will get the forecast for that US zip code.", +"Gets a weather report for the given station or zip.\nSpecifying %bold%metar%bold% will force the parsing the metar report instead of using the NOAA XML data.\nSpecifying %bold%raw%bold% will show the METAR report in its original form.\nforecast <zip> will get the forecast for that US zip code.", event_plugin_call => \&new_get_wx, event_plugin_load => \&messup_wx, |
|
From: Pete P. <fou...@us...> - 2005-05-07 18:03:46
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20699/plugins Modified Files: weather.pl Log Message: Now %weather <zip> will give you the current conditions for the nearest station. (US zips only, find me a free list of postal codes for other countries and they'll work too) Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.74 retrieving revision 1.75 diff -u -d -p -r1.74 -r1.75 --- weather.pl 7 May 2005 15:35:52 -0000 1.74 +++ weather.pl 7 May 2005 18:03:29 -0000 1.75 @@ -30,7 +30,6 @@ # * Known stations searching. (%weather ny should be able to list # stations in NY. %weather massena, ny should get the weather for # KMSS) -# * use zip->lat/long to find closest station # * find other postal codes -> lat/long databases so we can find the closest # station outside the US # * KILL Geo::METAR DAMN IT @@ -78,6 +77,8 @@ use constant FIND_STATION_AT => 'You can use constant CANNOT_ACCESS => 'Sorry; I could not access NOAA.'; +use constant PI => 3.1415926; + # Flags use constant RAW_METAR => 128; use constant FORCE_METAR => 64; @@ -917,6 +918,8 @@ sub new_get_wx { &SimBot::send_message($channel, "$nick: For what US Zip code do you want a forecast?"); } return; + } elsif($station =~ /^(\d\d\d\d\d)$/) { + $station = &find_closest_station($station); } if($command =~ /^.metar$/) { $flags |= RAW_METAR; } @@ -944,6 +947,45 @@ sub get_alerts { # We're done here - got_alerts will handle requesting the forecast } +sub find_closest_station { + my ($zipcode) = @_; + + # OK, we need the lat/long for that zip code. + my $query = $zip_dbh->prepare( + 'SELECT latitude, longitude FROM uszips WHERE zip = ?' + ); + $query->execute($zipcode); + my ($zip_lat, $zip_long) = $query->fetchrow_array; + + $query->finish; + + # OK, now we need to find potential stations. + $query = $dbh->prepare( + 'SELECT id, latitude, longitude FROM stations' + . ' WHERE latitude BETWEEN ? AND ?' + . ' AND longitude BETWEEN ? AND ?'); + + $query->execute($zip_lat - 1, $zip_lat + 1, + $zip_long - 1, $zip_long + 1); + + my $nearest_station; + my $nearest_dist; + while(my ($cur_station, $cur_lat, $cur_long) = $query->fetchrow_array) { + my $theta = $cur_long - $zip_long; + my $dist = rad2deg(acos( + sin(deg2rad($cur_lat)) * sin(deg2rad($zip_lat)) + + cos(deg2rad($cur_lat)) * cos(deg2rad($zip_lat)) * cos(deg2rad($theta)) + )) * 60 * 1.1515; + + if(!defined $nearest_station || $nearest_dist > $dist) { + $nearest_station = $cur_station; + $nearest_dist = $dist; + } + } + + return $nearest_station; +} + sub dms_to_degrees { my ($degrees, $minutes, $seconds, $dir) = @_; @@ -955,6 +997,21 @@ sub dms_to_degrees { return $degrees; } +sub acos { + my ($rad) = @_; + return(atan2(sqrt(1 - $rad**2), $rad)); +} + +sub deg2rad { + my ($deg) = @_; + return ($deg * PI / 180); +} + +sub rad2deg { + my ($rad) = @_; + return ($rad * 180 / PI); +} + # Register Plugins &SimBot::plugin_register( plugin_id => "weather", |
|
From: Pete P. <fou...@us...> - 2005-05-07 15:39:45
|
Update of /cvsroot/simbot/simbot/data In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17544/data Modified Files: USzip Log Message: Filter out some bogus lat/longs for Hawai'i, and hard code Honolulu. Index: USzip =================================================================== RCS file: /cvsroot/simbot/simbot/data/USzip,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -p -r1.1 -r1.2 Binary files /tmp/cvsUxjtBu and /tmp/cvsuNkHow differ |
|
From: Pete P. <fou...@us...> - 2005-05-07 15:39:14
|
Update of /cvsroot/simbot/simbot/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17544/tools Modified Files: create_zip_db.pl Log Message: Filter out some bogus lat/longs for Hawai'i, and hard code Honolulu. Index: create_zip_db.pl =================================================================== RCS file: /cvsroot/simbot/simbot/tools/create_zip_db.pl,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -p -r1.4 -r1.5 --- create_zip_db.pl 7 May 2005 02:38:32 -0000 1.4 +++ create_zip_db.pl 7 May 2005 15:38:58 -0000 1.5 @@ -101,9 +101,25 @@ for my $row (0 .. $last_row) { $lat =~ s/^\s*//; $long =~ s/^\s*//; - $insert_row_query->execute($cur_row->{'ZIP_CODE'}, $lat, - $long, $cur_row->{'ZIP_CLASS'}, - $cur_row->{'PONAME'}, $state, $geocode); + if($lat == 24.859832 && $long == -168.021815) { + # Bogus lat/long for many zips in Hawai'i + # unless there's a post office on the ocean floor. + + if($cur_row->{'PONAME'} eq 'HONOLULU') { + $lat = 21.307039; + $long = -157.858343; + } else { + undef $lat; + undef $long; + } + } + + { + no warnings qw( uninitialized ); + $insert_row_query->execute($cur_row->{'ZIP_CODE'}, $lat, + $long, $cur_row->{'ZIP_CLASS'}, + $cur_row->{'PONAME'}, $state, $geocode); + } } print "Done!\nCreating indices..."; |
|
From: Pete P. <fou...@us...> - 2005-05-07 15:36:00
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17189/plugins Modified Files: weather.pl Log Message: We now request the alerts file compressed. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.73 retrieving revision 1.74 diff -u -d -p -r1.73 -r1.74 --- weather.pl 7 May 2005 13:57:15 -0000 1.73 +++ weather.pl 7 May 2005 15:35:52 -0000 1.74 @@ -30,20 +30,16 @@ # * Known stations searching. (%weather ny should be able to list # stations in NY. %weather massena, ny should get the weather for # KMSS) -# * Find a way to convert zip codes to lat/long, use to find closest -# station +# * use zip->lat/long to find closest station +# * find other postal codes -> lat/long databases so we can find the closest +# station outside the US # * KILL Geo::METAR DAMN IT -# * Forecasts would be nice. http://www.nws.noaa.gov/forecasts/xml/ -# * Fix crash if simbot quits before station name cache is updated -# (don't try to update DB if it's closed) package SimBot::plugin::weather; use strict; use warnings; -use Data::Dumper; - # The weather, more or less! use Geo::METAR; @@ -730,7 +726,7 @@ sub got_alerts { "$nick: " . &get_forecast($nick, $lat, $long)); return; } - my $raw_xml = $response->content; + my $raw_xml = $response->decoded_content; my $cap_alert; @@ -912,8 +908,6 @@ sub new_get_wx { . ' WHERE zip = ? LIMIT 1'); $get_lat_long_query->execute($args[0]); if(($lat, $long, $state, $geocode) = $get_lat_long_query->fetchrow_array) { - #&get_forecast($nick, $channel, $lat, $long); - #&get_alerts($kernel, $nick, $channel, $lat, $long, $state, $geocode); $kernel->post($session => 'get_alerts', $nick, $lat, $long, $state, $geocode); } else { &SimBot::send_message($channel, "$nick: I do not know where that zip code is."); @@ -943,6 +937,7 @@ sub get_alerts { my $url = 'http://weather.gov/alerts/' . lc($state) . '.cap'; my $request = HTTP::Request->new(GET => $url); + $request->header('Accept-Encoding' => 'gzip, deflate'); $kernel->post('wxua' => 'request', 'got_alerts', $request, "$nick!$lat!$long!$geocode"); |
|
From: Pete P. <fou...@us...> - 2005-05-07 13:57:26
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24560/plugins Modified Files: weather.pl Log Message: Yes, I committed with the debug file on again. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.72 retrieving revision 1.73 diff -u -d -p -r1.72 -r1.73 --- weather.pl 7 May 2005 13:56:03 -0000 1.72 +++ weather.pl 7 May 2005 13:57:15 -0000 1.73 @@ -803,8 +803,8 @@ sub get_forecast { if ($response->fault) { return 'Something unexpected happened: ' . $response->faultstring; } else { - open(OUT, ">forecast_debug"); - print OUT $response->result; +# open(OUT, ">forecast_debug"); +# print OUT $response->result; my $xml = $response->result; |
|
From: Pete P. <fou...@us...> - 2005-05-07 13:56:16
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23781/plugins Modified Files: weather.pl Log Message: Properly pad the forecast start date with zeros. This fixes the server randomly giving us very little data. Now that we can actually get lots of data, be even less verbose (combined day and night) so an entire week fits. Also, redid the entire parsing function so I can actually understand what it does. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.71 retrieving revision 1.72 diff -u -d -p -r1.71 -r1.72 --- weather.pl 7 May 2005 11:53:13 -0000 1.71 +++ weather.pl 7 May 2005 13:56:03 -0000 1.72 @@ -42,6 +42,8 @@ package SimBot::plugin::weather; use strict; use warnings; +use Data::Dumper; + # The weather, more or less! use Geo::METAR; @@ -62,6 +64,8 @@ use HTTP::Status; use DBI; # for sqlite database +use Time::Local; + # declare globals use vars qw( $session $dbh $zip_dbh ); @@ -744,11 +748,7 @@ sub got_alerts { my @alerts; my @alerts_link; - my $cap_info = $cap_alert->{'cap:info'}; - -# for my $i (0 .. $#$cap_info) { foreach my $cur_cap_info (@{$cap_alert->{'cap:info'}}) { - #my $cur_geocode = int $cap_info->[$i]->{'cap:area'}->{'cap:geocode'}; if(defined $cur_cap_info->{'geocode'} && $cur_cap_info->{'geocode'} == $geocode) { @@ -774,47 +774,42 @@ sub got_alerts { } sub get_forecast { - # Credit/blame to http://golem.ph.utexas.edu/~distler/blog/archives/000500.html - # for much of this script my ($nick, $lat, $long) = @_; my $serviceURI = 'http://weather.gov/forecasts/xml'; my $method = 'NDFDgenByDay'; my $endpoint = "$serviceURI/SOAP_server/ndfdXMLserver.php"; my $soapAction = "$serviceURI/DWMLgen/wsdl/ndfdXML.wsdl#$method"; - - # how many days should we ask for? Max NOAA lets us is 7. - # Occasionally NOAA seems to give bogus data towards the end of the set - # this seems to happen no matter how many days we ask for, so let's - # ask for all 7 to hopefully get good data for 5 or so. + my $numDays = 7; - my $format = '12 hourly'; + my $format = '24 hourly'; my @time = localtime; - my $startDate = ($time[5] + 1900) . '-' . ($time[4] + 1) . '-' - . ($time[3]) . '-00:00'; + my $startDate = sprintf('%04d-%02d-%02d', + ($time[5] + 1900), ($time[4] + 1), ($time[3])); + my $weather = SOAP::Lite->new(uri => $soapAction, proxy => $endpoint); my $response = $weather->call( - SOAP::Data->name($method) - => SOAP::Data->type(decimal => $lat )->name('latitude'), - => SOAP::Data->type(decimal => $long )->name('longitude'), - => SOAP::Data->type(date => $startDate)->name('startDate'), - => SOAP::Data->type(integer => $numDays )->name('numDays'), - => SOAP::Data->type(string => $format )->name('format') - ); + SOAP::Data->name($method) + => SOAP::Data->type(decimal => $lat )->name('latitude'), + => SOAP::Data->type(decimal => $long )->name('longitude'), + => SOAP::Data->type(date => $startDate)->name('startDate'), + => SOAP::Data->type(integer => $numDays )->name('numDays'), + => SOAP::Data->type(string => $format )->name('format') + ); if ($response->fault) { return 'Something unexpected happened: ' . $response->faultstring; } else { -# open(OUT, ">forecast_debug"); -# print OUT $response->result; + open(OUT, ">forecast_debug"); + print OUT $response->result; my $xml = $response->result; my $forecast; - if (!eval { $forecast = XMLin($xml); }) { + if (!eval { $forecast = XMLin($xml, KeyAttr=>['type']); }) { return 'The forecast could not be parsed. Blame NOAA.'; } @@ -824,69 +819,61 @@ sub get_forecast { my $info_url = $forecast->{'head'}->{'source'}->{'more-information'}; my ($maxperiodkey, $minperiodkey, $condsperiodkey); + my @days; # arrays of keys for the time-periods in the forecast - LAYOUT: - for my $i (0 .. $#$layout) { - my $period_key = $layout->[$i]->{'start-valid-time'}; - my $layout_key = $layout->[$i]->{'layout-key'}; - $layout_key =~ /k-p24h-n\d-1/ ? do {$maxperiodkey=$period_key; next LAYOUT;} : - $layout_key =~ /k-p24h-n\d-2/ ? do {$minperiodkey=$period_key; next LAYOUT;} : - $layout_key =~ /k-p12h-n\d/ ? ($condsperiodkey=$period_key) : - die "unknown period key\n"; + foreach my $cur_time_layout (@{$forecast->{'data'}->{'time-layout'}}) { + if($cur_time_layout->{'layout-key'} =~ m/k-p24h-n\d-1/) { + @days = @{$cur_time_layout->{'start-valid-time'}}; + last; + } } - $numDays = 5; - if ($numDays > $#$maxperiodkey + 1) { - $numDays = $#$maxperiodkey + 1; + my (undef, undef, undef, $today_day, $today_mon, $today_year, $toay_wday) = localtime; + foreach (@days) { + my ($year, $month, $day) = m/^(\d+)-(\d+)-(\d+)/; + if($year == $today_year+1900 + && $month == $today_mon+1 + && $day == $today_day) + { + $_ = 'Today'; + } else { + my $wday = (localtime(timelocal(undef, undef, undef, $day, $month-1, $year-1900)))[6]; + $_ = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')[$wday]; + } } - my ($conditions, $temperatures, $hilo, $times, $precip, $icons); - # turn the forecast into hashes, keyed by time-period - for my $i (0 .. 2*$numDays-1) { - $times->[$i] = $condsperiodkey->[$i]->{'period-name'}; - $conditions->{$times->[$i]} = - $params->{'weather'}->{'weather-conditions'}->[$i]->{'weather-summary'}; - $precip->{$times->[$i]} = - $params->{'probability-of-precipitation'}->{'value'}->[$i]; - # towards the end of a 12-hour period, NOAA doesn't deign to "forecast" the - # weather for that period. So we hack around them. - $icons->{$times->[$i]} = - ($params->{'conditions-icon'}->{'icon-link'}->[$i] =~ /^HASH/ ) ? - '' : - $params->{'conditions-icon'}->{'icon-link'}->[$i]; - } - for my $i (0 .. $numDays-1) { - $temperatures->{$maxperiodkey->[$i]->{'period-name'}} = - $params->{'temperature'}->{'Daily Maximum Temperature'}->{'value'}->[$i]; - $temperatures->{$minperiodkey->[$i]->{'period-name'}} = - $params->{'temperature'}->{'Daily Minimum Temperature'}->{'value'}->[$i]; - $hilo->{$maxperiodkey->[$i]->{'period-name'}} = 'High'; - $hilo->{$minperiodkey->[$i]->{'period-name'}} = 'Low'; - } + my (@temp_highs, @temp_lows, $temp_highs_unit, $temp_lows_unit); - # OK, so we have weather. Let's do something with it. - my $msg = ''; + @temp_highs = @{$forecast->{'data'}->{'parameters'}->{'temperature'}->{'maximum'}->{'value'}}; + $temp_highs_unit = $forecast->{'data'}->{'parameters'}->{'temperature'}->{'maximum'}->{'units'}; + @temp_lows = @{$forecast->{'data'}->{'parameters'}->{'temperature'}->{'minimum'}->{'value'}}; + $temp_lows_unit = $forecast->{'data'}->{'parameters'}->{'temperature'}->{'minimum'}->{'units'}; + + my @conditions; + foreach my $cur_weather_conditions (@{$forecast->{'data'}->{'parameters'}->{'weather'}->{'weather-conditions'}}) { + push(@conditions, $cur_weather_conditions->{'weather-summary'}); + } - for my $i (@$times) { - my $cur_msg = $i . ': '; - my $got_something = 0; - if($conditions->{$i}) { - $cur_msg .= $conditions->{$i} . ', '; - $got_something = 1; - } - if($temperatures->{$i} && $temperatures->{$i} !~ /^HASH/ ) { - $cur_msg .= $temperatures->{$i} . '°F'; - $got_something = 1; - } - $cur_msg .= '; '; + my $msg; + for my $i (0 .. $#days) { + my $cur_msg = "%bold%$days[$i]%bold%: "; - if($got_something) { - $msg .= $cur_msg; + if($conditions[$i]) { $cur_msg .= $conditions[$i] . ', '; } + if($temp_highs[$i] && $temp_lows[$i] + && $temp_highs[$i] !~ /^HASH/ + && $temp_lows[$i] !~ /^HASH/) { + $cur_msg .= $temp_highs[$i] . '/' . $temp_lows[$i]; + } elsif($temp_highs[$i] && $temp_highs[$i] !~ /^HASH/) { + $cur_msg .= 'high ' . $temp_highs[$i]; + } elsif($temp_lows[$i] && $temp_lows[$i] !~ /^HASH/) { + $cur_msg .= 'low ' . $temp_lows[$i]; } + $cur_msg .= '; '; + $msg .= $cur_msg; } $msg =~ s/; $//; - return $msg; + return &SimBot::parse_style($msg); } } @@ -937,12 +924,6 @@ sub new_get_wx { } return; } -# if(($lat) = $station =~ /(-?[\d\.]+)/) { -# my $long = $args[0]; -# -# &get_forecast($nick, $channel, $lat, $long); -# return; -# } if($command =~ /^.metar$/) { $flags |= RAW_METAR; } foreach(@args) { |
|
From: Pete P. <fou...@us...> - 2005-05-07 11:53:24
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28809/plugins Modified Files: weather.pl Log Message: We no longer crash simbot if a forecast is requested in a state with no alerts. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.70 retrieving revision 1.71 diff -u -d -p -r1.70 -r1.71 --- weather.pl 7 May 2005 02:35:59 -0000 1.70 +++ weather.pl 7 May 2005 11:53:13 -0000 1.71 @@ -730,7 +730,7 @@ sub got_alerts { my $cap_alert; - if (!eval { $cap_alert = XMLin($raw_xml, SuppressEmpty => 1, NormaliseSpace => 2); }) { + if (!eval { $cap_alert = XMLin($raw_xml, NormaliseSpace => 2, ForceArray => ('cap:info')); }) { &SimBot::debug(3, "weather: XML parse error for alerts\n"); &SimBot::debug(4, "weather: XML parser failure: $@"); @@ -746,12 +746,15 @@ sub got_alerts { my $cap_info = $cap_alert->{'cap:info'}; - for my $i (0 .. $#$cap_info) { - my $cur_geocode = int $cap_info->[$i]->{'cap:area'}->{'cap:geocode'}; - if($cur_geocode == $geocode) { +# for my $i (0 .. $#$cap_info) { + foreach my $cur_cap_info (@{$cap_alert->{'cap:info'}}) { + #my $cur_geocode = int $cap_info->[$i]->{'cap:area'}->{'cap:geocode'}; + if(defined $cur_cap_info->{'geocode'} + && $cur_cap_info->{'geocode'} == $geocode) + { # We have a warning! - push(@alerts, $cap_info->[$i]->{'cap:event'}); - push(@alerts_link, $cap_info->[$i]->{'cap:web'}); + push(@alerts, $cur_cap_info->{'cap:event'}); + push(@alerts_link, $cur_cap_info->{'cap:web'}); } } |
|
From: Kevin S. <ks...@us...> - 2005-05-07 03:53:41
|
Update of /cvsroot/simbot/simbot/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27462 Modified Files: create_wx_station_db.pl Log Message: This seems to have been completely wrong. :) Index: create_wx_station_db.pl =================================================================== RCS file: /cvsroot/simbot/simbot/tools/create_wx_station_db.pl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -p -r1.2 -r1.3 --- create_wx_station_db.pl 7 May 2005 03:43:18 -0000 1.2 +++ create_wx_station_db.pl 7 May 2005 03:53:32 -0000 1.3 @@ -62,11 +62,8 @@ EOT # Set up our user agent my $ua = LWP::UserAgent->new; -if (defined &HTTP::Response::decoded_content) { - $ua->default_header('Accept-Encoding' => 'gzip, deflate'); -} else { - print "Warning: Your HTTP::Response does not support gzip\n"; -} +$ua->default_header('Accept-Encoding' => 'gzip, deflate'); + # Now with the boring stuff down, get the rather large METAR list print "Downloading METAR station list... "; @@ -77,12 +74,7 @@ if($response->is_error) { . $response->message . "\n"; } else { print "Done!\nReading it in"; - my $content; - if (defined &HTTP::Response::decoded_content) { - $content = $response->decoded_content; - } else { - $content = $response->content; - } + my $content = $response->decoded_content; my $cur_line; my $line_count = 0; @@ -95,17 +87,15 @@ if($response->is_error) { ($cur_line, $content) = split(/\n/, $content, 2); my ($station, undef, undef, $name, $state, $country, undef, $lat_dms, $long_dms) = split(/;/, $cur_line, 10); - my ($lat_deg, $long_deg, $minutes, $seconds, $dir); - if (defined $lat_dms) { - ($lat_deg, $minutes, $seconds, $dir) = $lat_dms - =~ m/(\d+)-(\d+)(?:-(\d+))?([NS])/; - $lat_deg = &dms_to_degrees($lat_deg, $minutes, $seconds, $dir); - } - if (defined $long_dms) { - ($long_deg, $minutes, $seconds, $dir) = $long_dms - =~ m/(\d+)-(\d+)(?:-(\d+))?([EW])/; - $long_deg = &dms_to_degrees($long_deg, $minutes, $seconds, $dir); - } + my ($long_deg); + my ($lat_deg, $minutes, $seconds, $dir) = $lat_dms + =~ m/(\d+)-(\d+)(?:-(\d+))?([NS])/; + $lat_deg = &dms_to_degrees($lat_deg, $minutes, $seconds, $dir); + + ($long_deg, $minutes, $seconds, $dir) = $long_dms + =~ m/(\d+)-(\d+)(?:-(\d+))?([EW])/; + $long_deg = &dms_to_degrees($long_deg, $minutes, $seconds, $dir); + { no warnings qw( uninitialized ); $update_station_query->execute( @@ -133,13 +123,7 @@ if($response->is_error) { } else { print "Done!\nReading it in"; my $xml; - my $content; - if (defined &HTTP::Response::decoded_content) { - $content = $response->decoded_content; - } else { - $content = $response->content; - } - if (!eval { $xml = XMLin($content, SuppressEmpty => 1); }) { + if (!eval { $xml = XMLin($response->decoded_content, SuppressEmpty => 1); }) { print STDERR " Failed!\n$@\n"; } else { my $update_station_query = $dbh->prepare( |
|
From: Kevin S. <ks...@us...> - 2005-05-07 03:43:31
|
Update of /cvsroot/simbot/simbot/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25291/tools Modified Files: create_wx_station_db.pl Log Message: This works for me. It makes it so that since my LWP doesn't support gzip, it doesn't explode. Index: create_wx_station_db.pl =================================================================== RCS file: /cvsroot/simbot/simbot/tools/create_wx_station_db.pl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -p -r1.1 -r1.2 --- create_wx_station_db.pl 7 May 2005 02:35:59 -0000 1.1 +++ create_wx_station_db.pl 7 May 2005 03:43:18 -0000 1.2 @@ -62,8 +62,11 @@ EOT # Set up our user agent my $ua = LWP::UserAgent->new; -$ua->default_header('Accept-Encoding' => 'gzip, deflate'); - +if (defined &HTTP::Response::decoded_content) { + $ua->default_header('Accept-Encoding' => 'gzip, deflate'); +} else { + print "Warning: Your HTTP::Response does not support gzip\n"; +} # Now with the boring stuff down, get the rather large METAR list print "Downloading METAR station list... "; @@ -74,7 +77,12 @@ if($response->is_error) { . $response->message . "\n"; } else { print "Done!\nReading it in"; - my $content = $response->decoded_content; + my $content; + if (defined &HTTP::Response::decoded_content) { + $content = $response->decoded_content; + } else { + $content = $response->content; + } my $cur_line; my $line_count = 0; @@ -87,15 +95,17 @@ if($response->is_error) { ($cur_line, $content) = split(/\n/, $content, 2); my ($station, undef, undef, $name, $state, $country, undef, $lat_dms, $long_dms) = split(/;/, $cur_line, 10); - my ($long_deg); - my ($lat_deg, $minutes, $seconds, $dir) = $lat_dms - =~ m/(\d+)-(\d+)(?:-(\d+))?([NS])/; - $lat_deg = &dms_to_degrees($lat_deg, $minutes, $seconds, $dir); - - ($long_deg, $minutes, $seconds, $dir) = $long_dms - =~ m/(\d+)-(\d+)(?:-(\d+))?([EW])/; - $long_deg = &dms_to_degrees($long_deg, $minutes, $seconds, $dir); - + my ($lat_deg, $long_deg, $minutes, $seconds, $dir); + if (defined $lat_dms) { + ($lat_deg, $minutes, $seconds, $dir) = $lat_dms + =~ m/(\d+)-(\d+)(?:-(\d+))?([NS])/; + $lat_deg = &dms_to_degrees($lat_deg, $minutes, $seconds, $dir); + } + if (defined $long_dms) { + ($long_deg, $minutes, $seconds, $dir) = $long_dms + =~ m/(\d+)-(\d+)(?:-(\d+))?([EW])/; + $long_deg = &dms_to_degrees($long_deg, $minutes, $seconds, $dir); + } { no warnings qw( uninitialized ); $update_station_query->execute( @@ -123,7 +133,13 @@ if($response->is_error) { } else { print "Done!\nReading it in"; my $xml; - if (!eval { $xml = XMLin($response->decoded_content, SuppressEmpty => 1); }) { + my $content; + if (defined &HTTP::Response::decoded_content) { + $content = $response->decoded_content; + } else { + $content = $response->content; + } + if (!eval { $xml = XMLin($content, SuppressEmpty => 1); }) { print STDERR " Failed!\n$@\n"; } else { my $update_station_query = $dbh->prepare( |
|
From: Pete P. <fou...@us...> - 2005-05-07 03:03:16
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17364/plugins Modified Files: rss.pl Log Message: Missed one. Index: rss.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/rss.pl,v retrieving revision 1.67 retrieving revision 1.68 diff -u -d -p -r1.67 -r1.68 --- rss.pl 7 May 2005 02:59:14 -0000 1.67 +++ rss.pl 7 May 2005 03:03:06 -0000 1.68 @@ -393,6 +393,7 @@ sub latest_headlines { # cache is stale or missing &SimBot::debug(4, "rss: $feed is old or missing.\n"); my $request = HTTP::Request->new(GET => $url); + $request->header('Accept-Encoding' => 'gzip, deflate'); $request->if_modified_since($last_update); $kernel->post('ua' => 'request', 'got_response', |
|
From: Pete P. <fou...@us...> - 2005-05-07 02:59:23
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16551/plugins Modified Files: rss.pl Log Message: We now request and understand (I hope... ;-) ) compressed data. Index: rss.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/rss.pl,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -p -r1.66 -r1.67 --- rss.pl 4 May 2005 20:39:05 -0000 1.66 +++ rss.pl 7 May 2005 02:59:14 -0000 1.67 @@ -230,6 +230,8 @@ sub do_rss { if(!$announce) { next; } $request = HTTP::Request->new(GET => $url); + $request->header('Accept-Encoding' => 'gzip, deflate'); + if(defined $last_update) { $request->if_modified_since($last_update); } @@ -295,7 +297,7 @@ sub got_response { $last_update = time; } elsif($response->is_success) { $last_update = time; - if (!eval { $rss->parse($response->content); }) { + if (!eval { $rss->parse($response->decoded_content); }) { &SimBot::debug(1, "rss: Parse error in $key: $@"); return; } |
|
From: Pete P. <fou...@us...> - 2005-05-07 02:52:45
|
Update of /cvsroot/simbot/simbot In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15405 Modified Files: INSTALL Log Message: Oops. currency.pl no longer requires LWP Index: INSTALL =================================================================== RCS file: /cvsroot/simbot/simbot/INSTALL,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -p -r1.20 -r1.21 --- INSTALL 1 May 2005 20:11:11 -0000 1.20 +++ INSTALL 7 May 2005 02:52:30 -0000 1.21 @@ -20,7 +20,7 @@ features in SimBot: For weather.pl, rss.pl LWP: (libwwwperl) - For google.pl, currency.pl, tinyurl.pl + For google.pl, tinyurl.pl HTML::Entities: For google.pl, rss.pl |
|
From: Pete P. <fou...@us...> - 2005-05-07 02:38:48
|
Update of /cvsroot/simbot/simbot/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12943/tools Modified Files: create_zip_db.pl Log Message: We now set $| so output doesn't wait for \n. Index: create_zip_db.pl =================================================================== RCS file: /cvsroot/simbot/simbot/tools/create_zip_db.pl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -p -r1.3 -r1.4 --- create_zip_db.pl 6 May 2005 19:11:46 -0000 1.3 +++ create_zip_db.pl 7 May 2005 02:38:32 -0000 1.4 @@ -37,6 +37,7 @@ use strict; use CAM::DBF; use DBI; +$| = 1; my %states = qw( 01 AL 02 AK 04 AZ 05 AR 06 CA 08 CO 09 CT 10 DE 11 DC @@ -116,4 +117,4 @@ EOT print " Done!\nCommitting..."; $sqlite_dbh->commit; -print " Done!\n"; \ No newline at end of file +print " Done!\n"; |
|
From: Pete P. <fou...@us...> - 2005-05-07 02:36:14
|
Update of /cvsroot/simbot/simbot/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12433/tools Added Files: create_wx_station_db.pl Log Message: create_wx_station_db.pl creates data/weather, which contains station names and locations weather.pl now uses this file instead of caches/weather --- NEW FILE: create_wx_station_db.pl --- #!/usr/bin/perl # SimBot Weather Station Names Importer # # DESCRIPTION: # Imports the list of METAR stations from NOAA's web site. # # USAGE: # While inside SimBot's directory, run tools/create_wx_station_db.pl # # COPYRIGHT: # Copyright (C) 2005, Pete Pearson # # This program is free software; you can redistribute and/or modify it # under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use Compress::Zlib; use LWP::UserAgent; use DBI; use XML::Simple; use warnings; use strict; # turn off IO buffering on STDOUT $| = 1; # let's create our database my $dbh = DBI->connect('dbi:SQLite:dbname=data/weather','','', { RaiseError => 1, AutoCommit => 0 }) or die; # let's create the table. If this fails, we don't care, as it # probably already exists { local $dbh->{RaiseError}; # let's not die on errors local $dbh->{PrintError}; # and let's be quiet $dbh->do(<<EOT); CREATE TABLE stations ( id STRING UNIQUE, name STRING, state STRING, country STRING, latitude REAL, longitude REAL, url STRING ); EOT } # we'll create the indices when we are done, it's supposedly faster # Set up our user agent my $ua = LWP::UserAgent->new; $ua->default_header('Accept-Encoding' => 'gzip, deflate'); # Now with the boring stuff down, get the rather large METAR list print "Downloading METAR station list... "; my $response = $ua->get('http://weather.noaa.gov/data/nsd_cccc.gz'); if($response->is_error) { print STDERR "Failed!\n " . $response->code . ' ' . $response->message . "\n"; } else { print "Done!\nReading it in"; my $content = $response->decoded_content; my $cur_line; my $line_count = 0; my $update_station_query = $dbh->prepare( 'INSERT OR REPLACE INTO stations (id, name, state, country, latitude, longitude)' . ' VALUES (?,?,?,?,?,?)'); while($content) { if(++$line_count % 300 == 0) { print '.'; } ($cur_line, $content) = split(/\n/, $content, 2); my ($station, undef, undef, $name, $state, $country, undef, $lat_dms, $long_dms) = split(/;/, $cur_line, 10); my ($long_deg); my ($lat_deg, $minutes, $seconds, $dir) = $lat_dms =~ m/(\d+)-(\d+)(?:-(\d+))?([NS])/; $lat_deg = &dms_to_degrees($lat_deg, $minutes, $seconds, $dir); ($long_deg, $minutes, $seconds, $dir) = $long_dms =~ m/(\d+)-(\d+)(?:-(\d+))?([EW])/; $long_deg = &dms_to_degrees($long_deg, $minutes, $seconds, $dir); { no warnings qw( uninitialized ); $update_station_query->execute( $station, $name, ($state ? $state : undef), $country, $lat_deg, $long_deg, ); } } print "\nDone! Read $line_count lines\n" } # now let's get the XML data file. # this only has US stations, and generally lacks lat/long. print "Downloading XML station list... "; $response = $ua->get('http://www.nws.noaa.gov/data/current_obs/index.xml'); if($response->is_error) { print STDERR "Failed!\n " . $response->code . ' ' . $response->message . "\n"; } else { print "Done!\nReading it in"; my $xml; if (!eval { $xml = XMLin($response->decoded_content, SuppressEmpty => 1); }) { print STDERR " Failed!\n$@\n"; } else { my $update_station_query = $dbh->prepare( 'UPDATE stations SET url = ? WHERE id = ?'); my $line_count = 0; foreach my $cur_station (@{$xml->{'station'}}) { if(++$line_count % 300 == 0) { print '.'; } no warnings qw( uninitialized ); $update_station_query->execute( $cur_station->{'xml_url'}, $cur_station->{'station_id'} ); } print "\nDone! Read $line_count lines\n"; } } { local $dbh->{RaiseError}; # let's not die on errors local $dbh->{PrintError}; # and let's be quiet $dbh->do(<<EOT); CREATE UNIQUE INDEX stationid ON stations (id); CREATE INDEX latlong ON stations (latitude, longitude); EOT } $dbh->commit; $dbh->disconnect; sub dms_to_degrees { my ($degrees, $minutes, $seconds, $dir) = @_; if(defined $minutes) { $degrees += $minutes * 0.0166666667; } if(defined $seconds) { $degrees += $seconds * 0.000277777778; } if(defined $dir && $dir =~ m/[SW]/) { $degrees = $degrees * -1; } return $degrees; } |
|
From: Pete P. <fou...@us...> - 2005-05-07 02:36:14
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12433/plugins Modified Files: weather.pl Log Message: create_wx_station_db.pl creates data/weather, which contains station names and locations weather.pl now uses this file instead of caches/weather Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.69 retrieving revision 1.70 diff -u -d -p -r1.69 -r1.70 --- weather.pl 7 May 2005 01:05:29 -0000 1.69 +++ weather.pl 7 May 2005 02:35:59 -0000 1.70 @@ -105,7 +105,7 @@ sub cleanup_wx { # instead of giving up quickly so as to not block simbot sub messup_wx { # let's create our database - $dbh = DBI->connect('dbi:SQLite:dbname=caches/weather','','', + $dbh = DBI->connect('dbi:SQLite:dbname=data/weather','','', { RaiseError => 1, AutoCommit => 0 }) or die; $zip_dbh = DBI->connect('dbi:SQLite:dbname=data/USzip','','', @@ -152,7 +152,6 @@ EOT get_alerts => \&get_alerts, got_alerts => \&got_alerts, got_station_name => \&got_station_name, - got_station_list => \&got_station_list, shutdown => \&shutdown, } ); @@ -164,12 +163,6 @@ sub bootstrap { # Let's set an alias so our session will hang around # instead of just leaving since it has nothing to do $kernel->alias_set('wx_session'); - - # and let's go update our known stations list... - &SimBot::debug(3, "weather: Updating known stations...\n"); - my $request = HTTP::Request->new(GET=>'http://www.nws.noaa.gov/data/current_obs/index.xml'); - $kernel->post('wxua' => 'request', 'got_station_list', - $request); } ### do_wx @@ -241,57 +234,6 @@ sub do_wx { $request, "$nick!$station!$flags"); } -sub got_station_list { - my ($kernel, $request_packet, $response_packet) - = @_[KERNEL, ARG0, ARG1]; - - my $response = $response_packet->[0]; - - if($response->is_error) { - &SimBot::debug(3, "weather: Could not get station list!\n"); - return; - } - my $xml; - if (!eval { $xml = XMLin($response->content, SuppressEmpty => 1); }) { - &SimBot::debug(3, "weather: XML parse error for stations list: $@\n"); - return; - } - &SimBot::debug(3, "weather: Got station list.\n"); - - my $update_station_query = $dbh->prepare( - 'INSERT OR REPLACE INTO stations (id, name, state, country, latitude, longitude, url)' - . ' VALUES (?,?,?,?,?,?,?)'); - - foreach my $cur_station (@{$xml->{'station'}}) { - no warnings qw( uninitialized ); - - my ($lat_deg, $lat_min, $lat_sec, $lat_dir); - if(($lat_deg, $lat_min, $lat_sec, $lat_dir) = $cur_station->{'latitude'} - =~ m/(\d+)\.(\d+)(?:\.(\d+))([NS])/) - { - $lat_deg = &dms_to_degrees($lat_deg, $lat_min, $lat_sec, $lat_dir); - } - - my ($long_deg, $long_min, $long_sec, $long_dir); - if(($long_deg, $long_min, $long_sec, $long_dir) = $cur_station->{'longitude'} - =~ m/(\d+)\.(\d+)(?:\.(\d+))?([EW])/) - { - $long_deg = &dms_to_degrees($long_deg, $long_min, $long_sec, $long_dir); - } - - $update_station_query->execute( - $cur_station->{'station_id'}, - $cur_station->{'station_name'}, - $cur_station->{'state'}, - 'United States', - $lat_deg, - $long_deg, - $cur_station->{'xml_url'} - ); - } - $dbh->commit; -} - sub got_station_name { my ($kernel, $request_packet, $response_packet) = @_[KERNEL, ARG0, ARG1]; |
|
From: Pete P. <fou...@us...> - 2005-05-07 01:05:46
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26685/plugins Modified Files: weather.pl Log Message: OCD Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.68 retrieving revision 1.69 diff -u -d -p -r1.68 -r1.69 --- weather.pl 7 May 2005 00:48:22 -0000 1.68 +++ weather.pl 7 May 2005 01:05:29 -0000 1.69 @@ -265,11 +265,6 @@ sub got_station_list { foreach my $cur_station (@{$xml->{'station'}}) { no warnings qw( uninitialized ); -# NOAA seems to be inconsistant with how they represent -# latitude and longitude. It appears to be degrees.minutes.seconds -# but in some cases the number is X.Y . Is that X degrees, Y minutes, -# and 0 seconds, or X.Y degrees? -# I'll figure it out later... most stations just report NA anyway. my ($lat_deg, $lat_min, $lat_sec, $lat_dir); if(($lat_deg, $lat_min, $lat_sec, $lat_dir) = $cur_station->{'latitude'} =~ m/(\d+)\.(\d+)(?:\.(\d+))([NS])/) @@ -289,8 +284,8 @@ sub got_station_list { $cur_station->{'station_name'}, $cur_station->{'state'}, 'United States', - $lat_deg, #$latitude, - $long_deg, #$longitude, + $lat_deg, + $long_deg, $cur_station->{'xml_url'} ); } @@ -335,8 +330,8 @@ sub got_station_name { $name, $state, $country, - $lat_deg, #FIXME: lat - $long_deg, #FIXME: long + $lat_deg, + $long_deg, undef # URL is undef for metar ); } |
|
From: Pete P. <fou...@us...> - 2005-05-07 00:48:38
|
Update of /cvsroot/simbot/simbot/plugins In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22075/plugins Modified Files: weather.pl Log Message: METAR stations' latitudes and longitudes are now stored when the station names are downloaded. Delete caches/weather so old stations are updated. Index: weather.pl =================================================================== RCS file: /cvsroot/simbot/simbot/plugins/weather.pl,v retrieving revision 1.67 retrieving revision 1.68 diff -u -d -p -r1.67 -r1.68 --- weather.pl 6 May 2005 23:56:05 -0000 1.67 +++ weather.pl 7 May 2005 00:48:22 -0000 1.68 @@ -274,22 +274,14 @@ sub got_station_list { if(($lat_deg, $lat_min, $lat_sec, $lat_dir) = $cur_station->{'latitude'} =~ m/(\d+)\.(\d+)(?:\.(\d+))([NS])/) { - $lat_deg += $lat_min * 0.0166666667; - $lat_deg += $lat_sec * 0.000277777778; - if($lat_dir eq 'S') { - $lat_deg = $lat_deg * -1; - } + $lat_deg = &dms_to_degrees($lat_deg, $lat_min, $lat_sec, $lat_dir); } my ($long_deg, $long_min, $long_sec, $long_dir); if(($long_deg, $long_min, $long_sec, $long_dir) = $cur_station->{'longitude'} =~ m/(\d+)\.(\d+)(?:\.(\d+))?([EW])/) { - $long_deg += $long_min * 0.0166666667; - $long_deg += $long_sec * 0.000277777778; - if($long_dir eq 'W') { - $long_deg = $long_deg * -1; - } + $long_deg = &dms_to_degrees($long_deg, $long_min, $long_sec, $long_dir); } $update_station_query->execute( @@ -317,25 +309,37 @@ sub got_station_name { && $response->content !~ /No station matched the supplied identifier/) { - $response->content =~ m|Station Name:.*?<B>(.*?)\s*</B>|s; - my $name = $1; + my ($name) = $response->content =~ m|Station Name:.*?<B>(.*?)\s*</B>|s; $response->content =~ m|State:.*?<B>(.*?)\s*</B>|s; my $state = ($1 eq $name ? undef : $1); - $response->content =~ m|Country:.*?<B>(.*?)\s*</B>|s; - my $country = $1; + my ($country) = $response->content =~ m|Country:.*?<B>(.*?)\s*</B>|s; + + my ($lat_deg, $lat_min, $lat_sec, $lat_dir, + $long_deg, $long_min, $long_sec, $long_dir); + if(($lat_deg, $lat_min, $lat_sec, $lat_dir, + $long_deg, $long_min, $long_sec, $long_dir) = + $response->content =~ m|Station Position:.*?<B>(\d+)-(\d+)(?:-(\d+))?([NS]).*?(\d+)-(\d+)(?:-(\d+))?([EW])|s) + { + $lat_deg = &dms_to_degrees($lat_deg, $lat_min, $lat_sec, $lat_dir); + $long_deg = &dms_to_degrees($long_deg, $long_min, $long_sec, $long_dir); + } my $update_station_query = $dbh->prepare( 'INSERT OR REPLACE INTO stations (id, name, state, country, latitude, longitude, url)' . ' VALUES (?,?,?,?,?,?,?)'); - $update_station_query->execute( - $station, - $name, - $state, - $country, - undef, #FIXME: lat - undef, #FIXME: long - undef # URL is undef for metar - ); + + { + no warnings qw( uninitialized ); + $update_station_query->execute( + $station, + $name, + $state, + $country, + $lat_deg, #FIXME: lat + $long_deg, #FIXME: long + undef # URL is undef for metar + ); + } $dbh->commit; } &SimBot::debug(4, "weather: Got station name for $station\n"); @@ -1024,6 +1028,17 @@ sub get_alerts { # We're done here - got_alerts will handle requesting the forecast } +sub dms_to_degrees { + my ($degrees, $minutes, $seconds, $dir) = @_; + + if(defined $minutes) { $degrees += $minutes * 0.0166666667; } + if(defined $seconds) { $degrees += $seconds * 0.000277777778; } + + if(defined $dir && $dir =~ m/[SW]/) { $degrees = $degrees * -1; } + + return $degrees; +} + # Register Plugins &SimBot::plugin_register( plugin_id => "weather", |