#!/usr/bin/perl # showweather.pl $version = "v.1.4"; $lastchanged = "18 June 2007"; # Copyright 2006 Steven Lucy slucy@uchicago.edu # Released under the GPL version 2 # If you modify this code, I would enjoy seeing your version -- email me at address above. # This perl script sticks a bunch of weather on one page. Currently shows Chicago, but # could easily be changed for any other city by changing the source files... #There is a helper script, grabweather.sh, which should be run by cron every 30 minutes. # preliminaries ================================================ use CGI qw/:standard/; $datadir = "/var/www/weather"; # print source code if requested by user:#{{{ if (param("print") eq "grabweather.sh") { print "Content-type: text/plain\n\n"; print `cat grabweather.sh`; exit; } if (param("print") eq "showweather.pl") { print "Content-type: text/plain\n\n"; print `cat showweather.pl`; exit; }#}}} @supported_cities = ("chicago", "sf", "boston", "nola", "statecollege");#{{{ $current_url = url(-relative=>1, -query=>1); $current_url =~ m/(^|\/)([^\/]*)\.pl/; $selected_city = $2; $selected_city = "" if ($selected_city eq "" || $selected_city eq "showweather" || $selected_city eq "index"); $city = $selected_city; %zones = ("chicago" => "America/Chicago", "sf" => "America/Los_Angeles", "boston" => "America/New_York", "nola" => "America/Chicago", "statecollege" => "America/New_York"); %pretty = ("chicago" => "Chicago", "sf" => "San Francisco", "boston" => "Boston", "nola" => "New Orleans", "statecollege" => "State College, PA" ); %datafile = ("chicago" => "KMDW.xml", "sf" => "KSFO.xml", "boston" => "KBOS.xml", "nola" => "KNEW.xml", "statecollege" => "KUNV.xml"); %forecasts = ("chicago" => "mdw", "sf" => "sfo", "boston" => "bos", "nola" => "new", "statecollege" => "unv"); %radar_pics = ( "chicago_mosaic" => qq{radar loop}, "chicago_single" => qq{radar loop}, "boston_mosaic" => qq{radar loop}, "boston_single" => qq{radar loop}, "sf_mosaic" => qq{radar loop}, "sf_single" => qq{radar loop}, "nola_mosaic" => qq{radar loop}, "nola_single" => qq{radar loop}, "statecollege_mosaic" => qq{radar loop}, "statecollege_single" => qq{radar loop}, ); %clocks = ("chicago" => ["Chicago", "YerkesObIL"], "sf" => ["SanFranCA", "MtHamCA"], "boston" => ["Boston"], "nola" => ["NewOrlLA"], "statecollege" => ["StateCollegePA"]); # grab parameters from CGI: $radar_pic = param("radar_pic"); $radar_size = param("radar_size"); $clouds_size = param("clouds_size"); # set up some defaults: $city = "sf" unless ($city); $ENV{"TZ"} = $zones{$city}; ### - perlbal testing my $ifout = `/sbin/ifconfig eth0|grep inet`; $ifout =~ m/\s+inet\saddr:([\d\.]+)\s.+/g; $server = $1; # $default{"radar_pic"} = "mosaic"; $default{"radar_size"} = "small"; $default{"clouds_size"} = "small"; $radar_pic = $default{"radar_pic"} unless ($radar_pic); $radar_size = $default{"radar_size"} unless ($radar_size); $clouds_size = $default{"clouds_size"} unless ($clouds_size);#}}} &begin_html(); &print_current_conditions(); &print_radar_pic(); &print_clouds_pic(); &print_forecast(); &print_astro(); &print_nat_loop(); &print_links(); &print_footer(); sub begin_html {#{{{ $timeformat = '%e %b %Y %k:%M %Z'; $time = `date +'$timeformat'`; $utime = `date -u +'$timeformat'`; my $othercities = ""; for $i (@supported_cities) { $othercities .= qq{ - $pretty\{$i\} } unless ($i eq $city); } print < weather
Server: $server: $pretty{$city} $othercities Page loaded at $time or $utime
END }#}}} sub print_current_conditions {#{{{ open(FILE, "< $datadir/$datafile{$city}") or die "Can't open file: $!"; while (){ #go through XML file chomp; if (/^[ ]*]*)>([^<>]*)<[^<>]*>/; $c{$1} = $2; #build hash! } else {;} #nodata }; close(FILE); #make date pretty: ($dayofweek, $day, $month, $year, $time, $zone, $zonehuman) = split(/ +/, $c{"observation_time_rfc822"}, 7); $time =~ s/:00$//; $up = "$dayofweek $day $month $year $time $zonehuman"; #radation in basement of regenstein: if ($city eq "chicago") { $rad = `wget -q -T 3 -O- --tries=1 http://www.lib.uchicago.edu/~dean/float.htm | grep Current`; $rad =~ s/^[\D]*(\d*)[\D]*$/$1/; $radtext = qq{Current radiation in the basement of the Regenstein Library: $rad μR/hr (info)
}; } #make some changes to wind variable $c{"wind_mph"} =~ s/\..*//; #who cares about tenths of a mph? $wind_gust = " with gusts $c{'wind_gust_mph'}" unless $c{"wind_gust_mph"} =~ /NA/; print< Temp: $c{"temp_f"} F ($c{"temp_c"} C), Windchill: $c{"windchill_f"} F ($c{"windchill_c"} C)
Clouds: $c{"weather"}, Wind from $c{"wind_dir"} at $c{"wind_mph"} mph$wind_gust
$radtext Updated at $up ($c{"station_id"}) END }#}}} sub print_radar_pic {#{{{ $show_radar_pic = $radar_pics{$city."_".$radar_pic}; $show_radar_pic =~ s/width.*\//\// if ($radar_size eq "big"); $current_url = url(-relative=>1, -query=>1); #$current_url =~ s/index.pl//; $radar_options = &print_loop_options("radar_pic", $radar_pic, (keys(%radar_pics))); $radar_options .= " - " . &print_loop_options("radar_size", $radar_size, (qw{ big small })); print <
radar (precipitation)
$show_radar_pic$radar_options
END }#}}} sub print_clouds_pic {#{{{ $current_url = url(-relative=>1, -query=>1); $show_clouds_pic = qq{satellite loop}; $show_clouds_pic =~ s/width.*\//\// if ($clouds_size eq "big"); $clouds_options = &print_loop_options("clouds_size", $clouds_size, (qw{ big small })); if ($city eq "chicago") { print qq{
satellite (clouds)
$show_clouds_pic$clouds_options
}; } print< END }#}}} sub print_loop_options {#{{{ my $option_name = shift; my $option_current = shift; my @option_list = @_; my $options =""; for $pic (@option_list) { if ($pic =~ /^(${city}_|small|big)/ ) { $pic =~ s/^${city}_//; if ($pic eq $option_current) { #no link needed $options .= ""; } else { #change! my $new_url = $current_url; if ($pic eq $default{$option_name}) { #del from url $new_url =~ s/$option_name=\w*[;&]?//; $new_url =~ s/[;?&]$//; } else { #need to set in url if ($new_url =~ /$option_name=/) { #just need to change $new_url =~ s/$option_name=[^&;]*/$option_name=$pic/; } else { #need to add to url $new_url .= "?" unless ($new_url =~ /\?/); $new_url .= ";" unless ($new_url =~ /[;&?]$/); $new_url .= "$option_name=$pic"; } } $options .= qq{}; $end_a = 1; } $options .= $pic . ($end_a ? "" : ""); $end_a = 0; } } return $options; }#}}} sub print_forecast {#{{{ print "
", "
forecast
\n"; open(FORECAST, "< $datadir/$forecasts{$city}.forecast") or die "Can't open file $!"; if ($city eq "chicago") { my $ready = 0; $forecast = "NWS Chicago Metropolitan Forecast -- "; while() { $ready = 1 if (/^CHICAGO MET/); $ready = 0 if (/\$\$/); if ($ready == 1) { if (/^CHICAGO MET/ || /^NATIONAL WEA/ || /^[ ]*$/) {;} else { s/^\.([^.]*)\.\.\.(.*)/$1...<\/span>$2/; s/^(TODAY|TONIGHT)\.\.\.(.*)/$1...<\/span>$2/; $forecast .= (/" : "") . lc($_); } } } } elsif ($city eq "sf") {; while() { if (/SAN FRANCISCO/) { $forecast = "NWS San Francisco Peninsula Forecast -- "; s/.*-(.*)&&.*/$1/; s/
\.([^.]*)\.\.\./~~$1...<\/span>/g; s/
//g; s/~~/\n
/g; $forecast .= lc($_); } } } elsif ($city eq "boston") { my $ready = 0; $forecast = "NWS Boston Forecast -- "; while() { s/]*>//g; s/<\/span>//g; $ready = 1 if (/^INCLUDING/); $ready = 0 if (/<\/pre>/); if ($ready == 1) { if (/^INCLUDING/ || /^[ ]*$/) {;} else { s/^\.([^.]*)\.\.\.(.*)/$1...<\/span>$2/; s/^(TODAY|TONIGHT)\.\.\.(.*)/$1...<\/span>$2/; $forecast .= (/" : "") . lc($_); } } } } elsif ($city eq "nola") { $forecast = "NWS Orleans Parish Forecast -- "; my $ready = 0; while () { $ready = 1 if (/^INCLUDING/); $ready = 2 if ($ready == 1 and /^\d/); $ready = 0 if (/<\/PRE>/); if ($ready == 2) { if (/^INCLUDING/ || /^[ ]*$/) {;} else { s//\n/; s/<\/FONT><\/B>/...<\/span>/; $forecast .= lc($_); } } } } elsif ($city eq "statecollege") { $forecast = "NWS Southern Centre Forecast -- "; my $ready = 0; while() { if (/ E[DC]T.*2007$/) { $ready++; } if ($ready == 2) { if (/\$\$/) { $ready = 0; next; } s/^\.([^.]*)\.\.\.(.*)/$1...<\/span>$2/; s/^(TODAY|TONIGHT)\.\.\.(.*)/$1...<\/span>$2/; $forecast .= (/" : "") . lc($_); } } } close(FORECAST); print $forecast; print "
\n"; }#}}} sub print_astro {#{{{ print qq{
}, qq{
astronomical weather predictions
\n}; for $clock (@{$clocks{$city}}) { print<$clock clear sky clock\n END } print "
\n"; }#}}} sub print_nat_loop {#{{{ print <
national radar loop
national radar loop END }#}}} sub print_links {#{{{ if ($city eq "chicago") { print <
links
END } }#}}} sub print_footer {#{{{ print < END }#}}} #!/usr/bin/perl # showweather.pl $version = "v.1.4"; $lastchanged = "18 June 2007"; # Copyright 2006 Steven Lucy slucy@uchicago.edu # Released under the GPL version 2 # If you modify this code, I would enjoy seeing your version -- email me at address above. # This perl script sticks a bunch of weather on one page. Currently shows Chicago, but # could easily be changed for any other city by changing the source files... #There is a helper script, grabweather.sh, which should be run by cron every 30 minutes. # preliminaries ================================================ use CGI qw/:standard/; $datadir = "/home/slucy/weather"; # print source code if requested by user:#{{{ if (param("print") eq "grabweather.sh") { print "Content-type: text/plain\n\n"; print `cat grabweather.sh`; exit; } if (param("print") eq "showweather.pl") { print "Content-type: text/plain\n\n"; print `cat showweather.pl`; exit; }#}}} @supported_cities = ("chicago", "sf", "boston", "nola", "statecollege");#{{{ $current_url = url(-relative=>1, -query=>1); $current_url =~ m/(^|\/)([^\/]*)\.pl/; $selected_city = $2; $selected_city = "" if ($selected_city eq "" || $selected_city eq "showweather" || $selected_city eq "index"); $city = $selected_city; %zones = ("chicago" => "America/Chicago", "sf" => "America/Los_Angeles", "boston" => "America/New_York", "nola" => "America/Chicago", "statecollege" => "America/New_York"); %pretty = ("chicago" => "Chicago", "sf" => "San Francisco", "boston" => "Boston", "nola" => "New Orleans", "statecollege" => "State College, PA" ); %datafile = ("chicago" => "KMDW.xml", "sf" => "KSFO.xml", "boston" => "KBOS.xml", "nola" => "KNEW.xml", "statecollege" => "KUNV.xml"); %forecasts = ("chicago" => "mdw", "sf" => "sfo", "boston" => "bos", "nola" => "new", "statecollege" => "unv"); %radar_pics = ( "chicago_mosaic" => qq{radar loop}, "chicago_single" => qq{radar loop}, "boston_mosaic" => qq{radar loop}, "boston_single" => qq{radar loop}, "sf_mosaic" => qq{radar loop}, "sf_single" => qq{radar loop}, "nola_mosaic" => qq{radar loop}, "nola_single" => qq{radar loop}, "statecollege_mosaic" => qq{radar loop}, "statecollege_single" => qq{radar loop}, ); %clocks = ("chicago" => ["Chicago", "YerkesObIL"], "sf" => ["SanFranCA", "MtHamCA"], "boston" => ["Boston"], "nola" => ["NewOrlLA"], "statecollege" => ["StateCollegePA"]); # grab parameters from CGI: $radar_pic = param("radar_pic"); $radar_size = param("radar_size"); $clouds_size = param("clouds_size"); # set up some defaults: $city = "chicago" unless ($city); $ENV{"TZ"} = $zones{$city}; $default{"radar_pic"} = "mosaic"; $default{"radar_size"} = "small"; $default{"clouds_size"} = "small"; $radar_pic = $default{"radar_pic"} unless ($radar_pic); $radar_size = $default{"radar_size"} unless ($radar_size); $clouds_size = $default{"clouds_size"} unless ($clouds_size);#}}} &begin_html(); &print_current_conditions(); &print_radar_pic(); &print_clouds_pic(); &print_forecast(); &print_astro(); &print_nat_loop(); &print_links(); &print_footer(); sub begin_html {#{{{ $timeformat = '%e %b %Y %k:%M %Z'; $time = `date +'$timeformat'`; $utime = `date -u +'$timeformat'`; my $othercities = ""; for $i (@supported_cities) { $othercities .= qq{ - $pretty\{$i\} } unless ($i eq $city); } print < weather
server:$1 $pretty{$city} $othercities Page loaded at $time or $utime
END }#}}} sub print_current_conditions {#{{{ open(FILE, "< $datadir/$datafile{$city}") or die "Can't open file: $!"; while (){ #go through XML file chomp; if (/^[ ]*]*)>([^<>]*)<[^<>]*>/; $c{$1} = $2; #build hash! } else {;} #nodata }; close(FILE); #make date pretty: ($dayofweek, $day, $month, $year, $time, $zone, $zonehuman) = split(/ +/, $c{"observation_time_rfc822"}, 7); $time =~ s/:00$//; $up = "$dayofweek $day $month $year $time $zonehuman"; #radation in basement of regenstein: if ($city eq "chicago") { $rad = `wget -q -T 3 -O- --tries=1 http://www.lib.uchicago.edu/~dean/float.htm | grep Current`; $rad =~ s/^[\D]*(\d*)[\D]*$/$1/; $radtext = qq{Current radiation in the basement of the Regenstein Library: $rad μR/hr (info)
}; } #make some changes to wind variable $c{"wind_mph"} =~ s/\..*//; #who cares about tenths of a mph? $wind_gust = " with gusts $c{'wind_gust_mph'}" unless $c{"wind_gust_mph"} =~ /NA/; print< Temp: $c{"temp_f"} F ($c{"temp_c"} C), Windchill: $c{"windchill_f"} F ($c{"windchill_c"} C)
Clouds: $c{"weather"}, Wind from $c{"wind_dir"} at $c{"wind_mph"} mph$wind_gust
$radtext Updated at $up ($c{"station_id"}) END }#}}} sub print_radar_pic {#{{{ $show_radar_pic = $radar_pics{$city."_".$radar_pic}; $show_radar_pic =~ s/width.*\//\// if ($radar_size eq "big"); $current_url = url(-relative=>1, -query=>1); #$current_url =~ s/index.pl//; $radar_options = &print_loop_options("radar_pic", $radar_pic, (keys(%radar_pics))); $radar_options .= " - " . &print_loop_options("radar_size", $radar_size, (qw{ big small })); print <
radar (precipitation)
$show_radar_pic$radar_options
END }#}}} sub print_clouds_pic {#{{{ $current_url = url(-relative=>1, -query=>1); $show_clouds_pic = qq{satellite loop}; $show_clouds_pic =~ s/width.*\//\// if ($clouds_size eq "big"); $clouds_options = &print_loop_options("clouds_size", $clouds_size, (qw{ big small })); if ($city eq "chicago") { print qq{
satellite (clouds)
$show_clouds_pic$clouds_options
}; } print< END }#}}} sub print_loop_options {#{{{ my $option_name = shift; my $option_current = shift; my @option_list = @_; my $options =""; for $pic (@option_list) { if ($pic =~ /^(${city}_|small|big)/ ) { $pic =~ s/^${city}_//; if ($pic eq $option_current) { #no link needed $options .= ""; } else { #change! my $new_url = $current_url; if ($pic eq $default{$option_name}) { #del from url $new_url =~ s/$option_name=\w*[;&]?//; $new_url =~ s/[;?&]$//; } else { #need to set in url if ($new_url =~ /$option_name=/) { #just need to change $new_url =~ s/$option_name=[^&;]*/$option_name=$pic/; } else { #need to add to url $new_url .= "?" unless ($new_url =~ /\?/); $new_url .= ";" unless ($new_url =~ /[;&?]$/); $new_url .= "$option_name=$pic"; } } $options .= qq{}; $end_a = 1; } $options .= $pic . ($end_a ? "" : ""); $end_a = 0; } } return $options; }#}}} sub print_forecast {#{{{ print "
", "
forecast
\n"; open(FORECAST, "< $datadir/$forecasts{$city}.forecast") or die "Can't open file $!"; if ($city eq "chicago") { my $ready = 0; $forecast = "NWS Chicago Metropolitan Forecast -- "; while() { $ready = 1 if (/^CHICAGO MET/); $ready = 0 if (/\$\$/); if ($ready == 1) { if (/^CHICAGO MET/ || /^NATIONAL WEA/ || /^[ ]*$/) {;} else { s/^\.([^.]*)\.\.\.(.*)/$1...<\/span>$2/; s/^(TODAY|TONIGHT)\.\.\.(.*)/$1...<\/span>$2/; $forecast .= (/" : "") . lc($_); } } } } elsif ($city eq "sf") {; while() { if (/SAN FRANCISCO/) { $forecast = "NWS San Francisco Peninsula Forecast -- "; s/.*-(.*)&&.*/$1/; s/
\.([^.]*)\.\.\./~~$1...<\/span>/g; s/
//g; s/~~/\n
/g; $forecast .= lc($_); } } } elsif ($city eq "boston") { my $ready = 0; $forecast = "NWS Boston Forecast -- "; while() { s/]*>//g; s/<\/span>//g; $ready = 1 if (/^INCLUDING/); $ready = 0 if (/<\/pre>/); if ($ready == 1) { if (/^INCLUDING/ || /^[ ]*$/) {;} else { s/^\.([^.]*)\.\.\.(.*)/$1...<\/span>$2/; s/^(TODAY|TONIGHT)\.\.\.(.*)/$1...<\/span>$2/; $forecast .= (/" : "") . lc($_); } } } } elsif ($city eq "nola") { $forecast = "NWS Orleans Parish Forecast -- "; my $ready = 0; while () { $ready = 1 if (/^INCLUDING/); $ready = 2 if ($ready == 1 and /^\d/); $ready = 0 if (/<\/PRE>/); if ($ready == 2) { if (/^INCLUDING/ || /^[ ]*$/) {;} else { s//\n/; s/<\/FONT><\/B>/...<\/span>/; $forecast .= lc($_); } } } } elsif ($city eq "statecollege") { $forecast = "NWS Southern Centre Forecast -- "; my $ready = 0; while() { if (/ E[DC]T.*2007$/) { $ready++; } if ($ready == 2) { if (/\$\$/) { $ready = 0; next; } s/^\.([^.]*)\.\.\.(.*)/$1...<\/span>$2/; s/^(TODAY|TONIGHT)\.\.\.(.*)/$1...<\/span>$2/; $forecast .= (/" : "") . lc($_); } } } close(FORECAST); print $forecast; print "
\n"; }#}}} sub print_astro {#{{{ print qq{
}, qq{
astronomical weather predictions
\n}; for $clock (@{$clocks{$city}}) { print<$clock clear sky clock\n END } print "
\n"; }#}}} sub print_nat_loop {#{{{ print <
national radar loop
national radar loop END }#}}} sub print_links {#{{{ if ($city eq "chicago") { print <
links
END } }#}}} sub print_footer {#{{{ print < END }#}}}