diff options
| author | Alexander Færøy | 2014-05-31 13:10:46 +0200 |
|---|---|---|
| committer | Alexander Færøy | 2014-05-31 13:10:46 +0200 |
| commit | 2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1 (patch) | |
| tree | 1c5e6d817c88e67b46e216a50e0aef5428bf63df /scripts/weather.pl | |
| parent | 2d080422d79d1fd49d6c5528593ccaaff9bfc583 (diff) | |
| download | scripts.irssi.org-2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1.tar.bz2 | |
Import scripts from scripts.irssi.org
Diffstat (limited to 'scripts/weather.pl')
| -rw-r--r-- | scripts/weather.pl | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/scripts/weather.pl b/scripts/weather.pl new file mode 100644 index 0000000..57163dc --- /dev/null +++ b/scripts/weather.pl @@ -0,0 +1,305 @@ +# Irssi weather as statusbar item and forecast command + +# Fixes in this version +# +# 1. Fixed issue with N/A°F in the windchill/feelslike variable. +# 2. Added more information in the /forecast command. +# 3. Added an extended function for three day forecasts. +# 4. Moved the extended function info /forecast -e (yippie! FLAGS!) +# 5. Added a /forecast -o option to print the info to the active window +# 6. 2.0 has a TOTAL rewrite on how to get the data. We no longer use weather.com its now Geo::Weather data +# 7. Removed the three day extended forecast for the 2.0 version, will rewrite it later. +# 8. 2.1 now has 10 day extended forecast, takes slightly longer to load +# 9. 2.2 has returned to writing statusbar info to a file to save time in window switching +# 10. 2.3 allows theme customization of weather in statusbar (written for ardya) + + +# Use the following format in your theme file +# weather_display = "$0%R>%n%_$2%_%G>%n$4"; +# +# $0 is temperature +# $2 is feelslike (windchill/headindex) +# $4 is current conditions (windy or partly cloudy) + +# - You have to modify this line to the path of your LWP-dir +use lib '/usr/lib/perl5/vendor_perl/5.6.1'; +use Irssi; +use Irssi::TextUI; +use Geo::Weather; +use 5.6.0; + +use vars qw($VERSION %IRSSI $zipcode $refresh $show_type $last_refresh $refresh_tag); + +$VERSION = '2.3'; +%IRSSI = ( + authors => 'GrayWolf', + contact => 'graywolf@i-differ.net', + name => 'Weather.pl', + description => 'Put local weather information in your statusbar as well as add a forecast command', + license => 'Public Domain' +); + +# +## Variable defaults, can be changed with /set in Irssi, to save trouble I recommend setting your zipcode here +# +if (!$zipcode) { + $zipcode = "46260"; +} +$zip = $zipcode; +$country = "us"; +$refresh = "900"; +$show_type = "yes"; +$in_celsius = "no"; + +# +## Bind our commands +# +Irssi::command_bind("weather", "show_usage"); +Irssi::command_bind("forecast", "show_weather"); +Irssi::command_bind("weathsecret", "get_weather_for_status"); + +# +## Usage information +# +sub show_usage { + Irssi::print("[Usage] Forecast Statusbar script v$VERSION"); + Irssi::print("/weather : shows usage info"); + Irssi::print("/forecast <zipcode> : Show current forecast for <zipcode>"); + Irssi::print("/forecast -o <zipcode> : Show current forecast for <zipcode> in the active window \(print to channel\)"); + Irssi::print("/forecast -e <zipcode> : Show extended ten day forecast for <zipcode>"); + Irssi::print("/set weather_refresh : Sets how often the statusbar is updated"); + Irssi::print("/set weather_zip : The zipcode of the area you want displayed in the statusbar"); + Irssi::print("/set weather_show_type (yes/no) : Choose if you want to see F/C in the statusbar"); + Irssi::print("/set weather_in_celsius (yes/no) : Choose if you want to see the temperature in celsius"); + Irssi::print("/statusbar <bar> add weather : see /help statusbar for more information."); +} + +# +## First thing run the status grab +# +get_weather_for_status(); + +# +## Get down to work +# +sub weather_us { +my $winfo = new Geo::Weather; +$winfo->{timeout} = 5; # set timeout to 5 seconds instead of the default of 10 + +# Get the $zip from a /forecast command +$zip = $_[0]; + +# Currently only the US is supported, hope to add more countries later + if ( $country == "us" ) { + # Lets go get the information + my $current = $winfo->get_weather($zip); + my $forecast = $winfo->report_forecast(); + + $temperature = $current->{temp}; + $feelslike = $current->{heat}; + $description = $current->{cond}; + $wind = $current->{wind}; + $wind =~ s/\<br\>/\n/g; + $wind =~ s/\<.+?\>//sg; + $wind =~ s/ //g; + $dewp = $current->{dewp}; + $humi = $current->{humi}; + $visb = $current->{visb}; + $visb =~ s/\<br\>/\n/g; + $visb =~ s/\<.+?\>//sg; + $baro = $current->{baro}; + $baro =~ s/\<br\>/\n/g; + $baro =~ s/\<.+?\>//sg; + return($temperature,$feelslike,$description,$wind,$dewp,$humi,$visb,$baro,$forecast); + } else { + Irssi::print("Unable to get weather for $country"); + return(0,0,0); + } +} + +# Statusbar formatting +sub get_weather_for_status { + + ($temperature,$feelslike,$description,$therest) = weather_us($zipcode); + + # If the user doesn't want to see F in the statusbar lets strip that out + if ( $show_type eq 'yes' ) { + $temperature .= 'F'; + $feelslike .= 'F'; + } + # If the user wants his temp in celsius lets convert it here + if ($in_celsius eq 'yes') { + $convert = $temperature; + $convert =~ s/F//g; + $temperature = ((5 / 9) * ($convert - 32)); + $temperature = sprintf('%d', $temperature); + $feelcon = $feelslike; + $feelcon =~ s/F//g; + $feelslike = ((5 / 9) * ($feelcon - 32)); + $feelslike = sprintf('%d', $feelslike); + # Now we have the temp in celsius, do they want to see the C? + if ($show_type eq 'yes') { + $temperature .= 'C'; + $feelslike .= 'C'; + } + } + chomp($temperature); + chomp($feelslike); + chomp($description); + open STATUS_FILE, ">.irssi/weather.status" or die "Can't write to status file: $!"; + print STATUS_FILE "$temperature,$feelslike,$description"; + close STATUS_FILE; +} + +# Status bar information + +sub theme_format { + open GET_STATUS, "<.irssi/weather.status" or die "Can't open status file: $!"; + + my $themed = ""; + my $themecmd = ""; + + while ($line = <GET_STATUS>) { + ($temperature,$feelslike,$description) = split(/,/, $line); + } + chomp($description); + $description =~ s/ /\_\_/g; + $themed = Irssi::current_theme->format_expand("{weather_display $temperature $feelslike $description}",Irssi::EXPAND_FLAG_IGNORE_REPLACES); + + $statusbar_output = $themed; + return $statusbar_output; + Irssi::statusbar_items_redraw('weather'); + close GET_STATUS; +} + +sub weather { + my ($item, $get_size_only) = @_; + + $sbar_out = theme_format(); + $sbar_out =~ s/ /\//g; + $sbar_out =~ s/\_\_/ /g; + chomp($sbar_out); + $item->default_handler($get_size_only, "{sb $sbar_out}", undef, 1 ); +} + +sub show_weather { + my ($commands, $item, $witem) = @_; + ($flag, $thezip) = split(/ /, $commands); + if ($flag =~ /^\s*$/) { + $thezip = $zipcode if $thezip < 1; + ($temperature,$feelslike,$description,$wind,$dewp,$humi,$visb,$baro) = weather_us($thezip); + Irssi::active_win()->print("Information for $thezip - Temp: $temperature, Feels Like: $feelslike, Currently: $description, Dew Point: $dewp, Humidity: $humi, Visibility: $visb, Pressure: $baro, Wind: $wind"); + } elsif ($flag =~ /^\d*$/) { + $flag = $zipcode if $flag < 1; + ($temperature,$feelslike,$description,$wind,$dewp,$humi,$visb,$baro) = weather_us($flag); + Irssi::active_win()->print("Information for $flag - Temp: $temperature, Feels Like: $feelslike, Currently: $description, Dew Point: $dewp, Humidity: $humi, Visibility: $visb, Pressure: $baro, Wind: $wind"); + $flag = $zipcode; + weather_us($flag); + } elsif ($flag =~ /\-o/) { + if ($witem) { + $thezip = $zipcode if $thezip < 1; + ($temperature,$feelslike,$description,$wind,$dewp,$humi,$visb,$baro) = weather_us($thezip); + $witem->command("MSG ".$witem->{name}." Information for $thezip - Temp: $temperature, Feels Like: $feelslike, Currently: $description, Dew Point: $dewp, Humidity: $humi, Visibility: $visb, Pressure: $baro, Wind: $wind"); + $thezip = $zipcode; + weather_us($thezip); + } + } elsif ($flag =~ /\-e/) { + if ($witem) { + $thezip = $zipcode if $thezip < 1; + ($temperature,$feelslike,$description,$wind,$dewp,$humi,$visb,$baro,$forecast) = weather_us($thezip); + my $count = 0; + my $active = 0; + my $day = 0; + my @days = (); + + $forecast =~ s/\<.+?\>//sg; + $forecast =~ s/ //g; + $forecast =~ s/°/F/g; + $forecast =~ s/FF/F/g; + $forecast =~ s/^\s+//gm; + + @fore = split(/\n/, $forecast); + $endres = undef; + + foreach $line (@fore) { + if ($count > 3) { + if ($active <= 4) { + if ($active eq 0) { + # This is necessary to prevent wrapping into the next call of /forecast -e + $endres .= "\n"; + } + chomp($line); + $line =~ s/ \/ /\//g; + $line =~ s/ \%/\% chance of precipitation/g; + $endres .= "$line "; + $active ++; + } else { + $active = 1; + $day ++; + if ($day < 11) { + chomp($line); + $line =~ s/ \/ /\//g; + $line =~ s/ \%/\% chance of precipitation/g; + $endres .= "\n$line"; + } + } + } + $count ++; + } + + @days = split(/\n/, $endres); + Irssi::active_win()->print("Extended Ten Day Forecast for $thezip"); + Irssi::active_win()->print("$days[1]"); + Irssi::active_win()->print("$days[2]"); + Irssi::active_win()->print("$days[3]"); + Irssi::active_win()->print("$days[4]"); + Irssi::active_win()->print("$days[5]"); + Irssi::active_win()->print("$days[6]"); + Irssi::active_win()->print("$days[7]"); + Irssi::active_win()->print("$days[8]"); + Irssi::active_win()->print("$days[9]"); + Irssi::active_win()->print("$days[10]"); + } + } else { + Irssi::active_win()->print("Cannot print to the active window"); + } +} + + +sub refresh_weather { + Irssi::statusbar_items_redraw('weather'); +} + +sub read_settings { + $zipcode = Irssi::settings_get_str('weather_zip'); + $show_type = Irssi::settings_get_str('weather_show_type'); + $in_celsius = Irssi::settings_get_str('weather_in_celsius'); + $refresh = Irssi::settings_get_int('weather_refresh'); + $refresh = 1 if $refresh < 1; + return if $refresh == $last_refresh; + $last_refresh = $refresh; + Irssi::timeout_remove($refresh_tag) if $refresh_tag; + $refresh_tag = Irssi::timeout_add($refresh * 1000, 'get_weather_for_status', undef); + $refresh_tag = Irssi::timeout_add($refresh * 1000, 'refresh_weather', undef); +} + +Irssi::settings_add_int('misc', 'weather_refresh', $refresh); +Irssi::settings_add_str('misc', 'weather_zip', $zipcode); +Irssi::settings_add_str('misc', 'weather_show_type', $show_type); +Irssi::settings_add_str('misc', 'weather_in_celsius', $in_celsius); + +Irssi::statusbar_item_register('weather', undef, 'weather'); +Irssi::statusbars_recreate_items(); + +read_settings(); +Irssi::signal_add('setup changed', 'read_settings'); + +# +## TODO +# +# 1. Add other countries -- (not sure if this will ever happen, feel free....) +# 2. Fix the read_settings so that changes are immediate -- (just update your zipcode at the top of the script and don't bug me) +# 3. Allow the extended function to show temps in C (currently only F) -- (I don't want to) +# 4. I want to add some type of error check for the zipcodes, so that you can't enter an invalid one +# 5. Make the lookup background or async so it doesn't tie up the irssi session -- (all I can find is fork() which requires a major rewrite. +# Wait the 10 damn seconds you lazy gits.) |
