#!/usr/bin/perl # # Grabs the latest local weather conditions from the # UF Physics department. Command line option is totally unneeded. # $ReportDir = '.wmWeatherReports'; $WeatherSrc = 'http://www.phys.ufl.edu/~weather/text/mysite.txt'; use strict; use vars qw( $ReportDir $WeatherSrc ); use IO::File; # # Change to users home directory. We used to dump into /tmp # but using home dir instead avoids multiple users interfering # with one another. (Yeah, we could "unique-ize" the filenames, but # this is easier for now...) # my $home = $ENV{HOME} || (getpwuid($<))[7]; chdir() || chdir($home) or die "chdir '$home' failed: $!"; unless(-e $ReportDir) { mkdir $ReportDir, 0755 or die "unable to mkdir '$ReportDir': $!"; } chdir $ReportDir or die "chdir '$ReportDir' failed: $!"; my $StationID = "UF"; my $HTMLFileName = "$StationID.TXT"; my $URL = "$WeatherSrc"; my $DataFileName = "$StationID.dat"; # Is LWP installed? eval { require LWP::UserAgent }; if ($@) { my $cmd = qq{wget --proxy=off --passive-ftp --tries=0 --quiet } . qq{--output-document=$home/$ReportDir/$HTMLFileName $URL}; `$cmd` == 0 or die "unable to fetch weather: $?"; } else { $ENV{FTP_PASSIVE} = 1; # LWP uses Net::FTP internally. my $ua = new LWP::UserAgent; my $req = new HTTP::Request( GET => $URL ); my $rsp = $ua->request( $req ); die $rsp->status_line unless $rsp->is_success; my $fh = new IO::File "> $home/$ReportDir/$HTMLFileName" or die "unable to write '$home/$ReportDir/$HTMLFileName': $!"; print $fh $rsp->content; close $fh or die "error closing '$home/$ReportDir/$HTMLFileName': $!"; } # # Parse HTML File. # my %stats = ( temp => -99.0, chill => -99.0, dew_point => -99.0, pressure => -99.0, humidity => -99.0, heat_index => -99.0, rainfall => -99.0, speed => -99.0, dir_word => 'UP', universal_time => '99:99', ); my $fh = new IO::File $HTMLFileName or die "unable to read '$HTMLFileName': $!"; chomp($stats{station_info} = <$fh>); chomp($stats{update_date} = <$fh>); chomp($stats{update_time} = <$fh>); # Grab all the data; go line by line, since I'm not a perl god and I don't know # how to chomp by two lines while getting the data correctly... uh, yeah. chomp($stats{null} = <$fh>); chomp($stats{temp} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{dew_point} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{heat_index} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{chill} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{humidity} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{pressure} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{rainfall} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{dir_word} = <$fh>); chomp($stats{null} = <$fh>); chomp($stats{speed} = <$fh>); if ($stats{temp} =~ /(\-{0,1}[0-9]{1,}).*/) { $stats{temp} = $1; } if ($stats{chill} =~ /(\-{0,1}[0-9]{1,}).*/) { $stats{chill} = $1; } if ($stats{dew_point} =~ /(\-{0,1}[0-9]{1,}).*/) { $stats{dew_point} = $1; } if ($stats{pressure} =~ /(\-{0,1}[0-9]{1,}).*/) { $stats{pressure} = $1; } if ($stats{humidity} =~ /(\-{0,1}[0-9]{1,}).*/) { $stats{humidity} = $1; } if ($stats{dir_word} =~ /(\-{0,1}[0-9]{1,}).*/) { $stats{dir_word} = $1; } if ($stats{speed} =~ /(\d{1,})\%.*/) { $stats{speed} = $1; } close $fh or die "error closing '$HTMLFileName': $!"; $stats{station_info} = "University of Florida Physics Department"; $stats{sky_conditions} = "Rainfall $stats{rainfall}in"; # Determine the wind direction... # Switch based on N, NW, WNW, W, SW, WSW, S... for ($stats{dir_word}) { if (/NNW\s*/) { $stats{direction} = 337; } elsif (/WNW\s*/) { $stats{direction} = 292; } elsif (/WSW\s*/) { $stats{direction} = 247; } elsif (/SSW\s*/) { $stats{direction} = 202; } elsif (/SSE\s*/) { $stats{direction} = 157; } elsif (/ESE\s*/) { $stats{direction} = 112; } elsif (/ENE\s*/) { $stats{direction} = 67; } elsif (/NNE\s*/) { $stats{direction} = 22; } elsif (/NW\s*/) { $stats{direction} = 315; } elsif (/SW\s*/) { $stats{direction} = 225; } elsif (/SE\s*/) { $stats{direction} = 135; } elsif (/NE\s*/) { $stats{direction} = 45; } elsif (/N\s*/) { $stats{direction} = 0; } elsif (/S\s*/) { $stats{direction} = 180; } elsif (/E\s*/) { $stats{direction} = 90; } elsif (/W\s*/) { $stats{direction} = 270; } else { $stats{direction} = 1.1; } # default } # # Get the Time out of the coded Metar Report. # my($hour) = 0; if ($stats{update_time} =~ /(\d{2}):(\d{2}) ([a-z])/) { $hour = $1 + 4; # We're GMT -4 in ET.. # Now, if it's PM, then we need to add 12, and if the # result is > 23, then subtract 24! :) if ($3 == "pm") { $hour = $hour + 12; } if ($hour > 23) { $hour = $hour - 24; } if ($hour > 9) { $stats{universal_time} = "$hour:$2"; } else { $stats{universal_time} = "0$hour:$2"; } } # # Write out the stuff we need to the Data File. This is the file that will # be read by GKrellWeather. # my $fh = new IO::File ">$DataFileName" or die "unable to write '$DataFileName': $!"; print $fh map { "$stats{$_}\n" } qw( station_info update_time sky_conditions universal_time temp dew_point chill pressure humidity direction speed ); close $fh or die "error closing '$DataFileName': $!";