SHOW:
|
|
- or go back to the newest paste.
| 1 | #!/usr/bin/perl | |
| 2 | ||
| 3 | ################################################################# | |
| 4 | # Yahoo Weather Rss Information Atomizer | |
| 5 | # Version 0.7.7 | |
| 6 | # Loud-Soft.com | |
| 7 | # [email protected] | |
| 8 | # Provided As Is | |
| 9 | ################################################################# | |
| 10 | ||
| 11 | use strict; | |
| 12 | use XML::XPath; | |
| 13 | use LWP::Simple; | |
| 14 | use XML::XPath::XMLParser; | |
| 15 | use Getopt::Long; | |
| 16 | use File::Copy; | |
| 17 | ||
| 18 | ################################################################# | |
| 19 | # Variables | |
| 20 | ################################################################# | |
| 21 | # Constants (Change these to localize) | |
| 22 | - | my $zipcode = "CAXX0504"; |
| 22 | + | my $zipcode = "2029043"; |
| 23 | my $unit = "c"; | |
| 24 | my $scripthome = "/Users/haroon/Documents/yweather-dir/"; | |
| 25 | my $icondir = $scripthome."images/"; | |
| 26 | my $datadir = $scripthome."data/"; | |
| 27 | my $datafile = $datadir."weather.xml"; | |
| 28 | my $imagefile = $icondir."weather.png"; | |
| 29 | ||
| 30 | # Constants (Do not change these) | |
| 31 | my $pre="yweather"; | |
| 32 | my $uri="http://xml.weather.yahoo.com/ns/rss/1.0"; | |
| 33 | my $url="http://xml.weather.yahoo.com/forecastrss?p=$zipcode&u=$unit"; | |
| 34 | my %data; | |
| 35 | my $xp; | |
| 36 | ||
| 37 | ################################################################# | |
| 38 | # Subroutines | |
| 39 | ################################################################# | |
| 40 | # Print usage | |
| 41 | sub usage {
| |
| 42 | print "Yahoo Weather Information\n\n"; | |
| 43 | print "Usage:\n"; | |
| 44 | print " ./yweather.pl -ct Displays current temperature\n\n"; | |
| 45 | print "Arguments: \n"; | |
| 46 | print " -lc City \n"; | |
| 47 | print " -lr Region\n"; | |
| 48 | print " -lt Country\n"; | |
| 49 | print " -cc Weather Code (used for images)\n"; | |
| 50 | print " -ct Current Temperature\n"; | |
| 51 | print " -cfl Current Feels Like\n"; | |
| 52 | print " -cw Current Weather Description\n"; | |
| 53 | print " -cd Current Date\n"; | |
| 54 | print " -ah Current Humidity\n"; | |
| 55 | print " -av Current Visibilty\n"; | |
| 56 | print " -ap Current Barometric Pressure\n"; | |
| 57 | print " -ar Change in Barometric Pressure\n"; | |
| 58 | print " -sr Time of Sunrise\n"; | |
| 59 | print " -ss Time of Sunset\n"; | |
| 60 | print " -wc Current Wind Chill\n"; | |
| 61 | print " -wd Current Wind Direction\n"; | |
| 62 | print " -ws Current Wind Speed\n"; | |
| 63 | print " -ut Temperature Unit\n"; | |
| 64 | print " -ud Distance Unit\n"; | |
| 65 | print " -up Pressure Unit \n"; | |
| 66 | print " -us Speed Unit\n"; | |
| 67 | print " -fd1 Today's Day\n"; | |
| 68 | print " -fg1 Today's Date\n"; | |
| 69 | print " -fl1 Today's Low Temp\n"; | |
| 70 | print " -fh1 Today's High Temp\n"; | |
| 71 | print " -ft1 Today's Description\n"; | |
| 72 | print " -fc1 Today's Weather Code\n"; | |
| 73 | print " -fd2 Tomorrow's Day\n"; | |
| 74 | print " -fg2 Tomorrow's Date\n"; | |
| 75 | print " -fl2 Tomorrow's Low Temp\n"; | |
| 76 | print " -fh2 Tomorrow's High Temp\n"; | |
| 77 | print " -ft2 Tomorrow's Description\n"; | |
| 78 | print " -fc2 Tomorrow's Weather Code\n"; | |
| 79 | print " --copyimage Copy Appropriate Image to Current Image (deprecated)\n"; | |
| 80 | print " --update Update xml source file\n" ; | |
| 81 | print " \n"; | |
| 82 | print "All data is returned without units. To get data with units,\n"; | |
| 83 | print "use a combination of commands.\n\n"; | |
| 84 | print "Example: (Displays Current temperature with unit)\n"; | |
| 85 | print " ./yweather.pl -ct && ./yweather.pl -ut\n"; | |
| 86 | } | |
| 87 | ||
| 88 | # Print data | |
| 89 | sub args{
| |
| 90 | my ($arg) = @_; | |
| 91 | print $data{$arg} . "\n";
| |
| 92 | } | |
| 93 | ||
| 94 | # Subroutine to update xml data from yahoo | |
| 95 | sub update_weather {
| |
| 96 | LWP::Simple::getstore($url,$datafile); | |
| 97 | } | |
| 98 | ||
| 99 | # Subroutine to download images from yahoo | |
| 100 | sub get_images {
| |
| 101 | my $imgurl = "http://l.yimg.com/a/i/us/nws/weather/gr/"; | |
| 102 | for (0..47) {
| |
| 103 | LWP::Simple::getstore($imgurl.$_."d.png",$icondir.$_."d.png"); | |
| 104 | LWP::Simple::getstore($imgurl.$_."n.png",$icondir.$_."n.png"); | |
| 105 | } | |
| 106 | } | |
| 107 | ||
| 108 | # Parse XML | |
| 109 | sub get_data {
| |
| 110 | my $ret; | |
| 111 | my($element, $attribute, $index) = @_; | |
| 112 | if ($index){$index=1;}
| |
| 113 | ||
| 114 | my $nodeset = $xp->find("//yweather:$element");
| |
| 115 | my $node = $nodeset->get_node($index); | |
| 116 | $ret = $node->getAttribute($attribute); | |
| 117 | return $ret; | |
| 118 | } | |
| 119 | ||
| 120 | # Calculate Feels Like (given temperature in fahrenheit and humidity) | |
| 121 | # source http://en.wikipedia.org/wiki/Heat_index#Formula | |
| 122 | sub calculate_feels_like {
| |
| 123 | my $unit = $data{'ut'};
| |
| 124 | ||
| 125 | # convert temperature to Fahrenheit | |
| 126 | my $tempf = $unit eq 'C' ? $data{'ct'} * 9/5 + 32 : $data{'ct'};
| |
| 127 | my $humid = $data{'ah'};
| |
| 128 | ||
| 129 | my $feels; | |
| 130 | ||
| 131 | # heat index calculation is only useful when temperature > 80F and humidity > 40% | |
| 132 | if ($humid > 40 && $tempf > 80) {
| |
| 133 | $feels = -42.379 + 2.04901523 * $tempf + 10.14333127 * $humid | |
| 134 | - 0.22475541 * $tempf * $humid - 6.83783 * 10**(-3)*($tempf**(2)) | |
| 135 | - 5.481717 * 10**(-2)*($humid**(2)) | |
| 136 | + 1.22874 * 10**(-3)*($tempf**(2))*($humid) | |
| 137 | + 8.5282 * 10**(-4)*($tempf)*($humid**(2)) | |
| 138 | - 1.99 * 10**(-6)*($tempf**(2))*($humid**(2)); | |
| 139 | ||
| 140 | # convert back to original unit if necessary | |
| 141 | if ($unit eq 'C') {
| |
| 142 | $feels = ($feels - 32) * 5/9; | |
| 143 | } | |
| 144 | } else {
| |
| 145 | # simply return wind chill | |
| 146 | $feels = $data{'wc'};
| |
| 147 | } | |
| 148 | return ($feels == int($feels)) ? int($feels) : int($feels + 1); | |
| 149 | } | |
| 150 | ||
| 151 | # Copy correct image to the image define in $imagefile | |
| 152 | sub copy_image {
| |
| 153 | my ($second, $minute, $hour, $dayOfMonth, $month, | |
| 154 | $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); | |
| 155 | my $night = $data{'ss'};
| |
| 156 | my $morning = $data{'sr'};
| |
| 157 | my $imagesub; | |
| 158 | if ($hour > 11){
| |
| 159 | if(($hour-12) < int(substr($night,0,1))){
| |
| 160 | $imagesub = "d"; | |
| 161 | }elsif(($minute) < int(substr($night,2,3))){
| |
| 162 | $imagesub = "d"; | |
| 163 | }else{
| |
| 164 | $imagesub = "n"; | |
| 165 | } | |
| 166 | } else {
| |
| 167 | if(($hour) < int(substr($morning,0,1))){
| |
| 168 | $imagesub = "n"; | |
| 169 | }elsif(($minute) < int(substr($morning,2,3))){
| |
| 170 | $imagesub = "n"; | |
| 171 | }else{
| |
| 172 | $imagesub = "d"; | |
| 173 | } | |
| 174 | } | |
| 175 | File::Copy::copy($icondir.$data{'cc'}.$imagesub.".png", $imagefile)
| |
| 176 | or die $icondir . $data{'cc'}.$imagesub.".png" . " could not be copied to " .
| |
| 177 | $imagefile; | |
| 178 | } | |
| 179 | ||
| 180 | ################################################################# | |
| 181 | # Check that files exist | |
| 182 | ################################################################# | |
| 183 | #ensure directories exist | |
| 184 | unless(-d $datadir){
| |
| 185 | mkdir $datadir or die; | |
| 186 | } | |
| 187 | unless(-d $icondir){
| |
| 188 | mkdir $icondir or die; | |
| 189 | } | |
| 190 | ||
| 191 | # Check if images exist | |
| 192 | if (!(-e $icondir."0d.png")){get_images()}
| |
| 193 | ||
| 194 | # Check if weather.xml exists | |
| 195 | if (!(-e $datafile)){update_weather()}
| |
| 196 | $xp = XML::XPath->new(filename => $datafile); | |
| 197 | $xp->set_namespace($pre, $uri); | |
| 198 | ||
| 199 | ||
| 200 | ################################################################# | |
| 201 | # Data Setup | |
| 202 | ################################################################# | |
| 203 | # Location Information | |
| 204 | $data{'lc'} = get_data("location","city");
| |
| 205 | $data{'lr'} = get_data("location","region");
| |
| 206 | $data{'lt'} = get_data("location","country");
| |
| 207 | ||
| 208 | # Current Weather Information | |
| 209 | $data{'cc'} = get_data("condition","code");
| |
| 210 | $data{'ct'} = get_data("condition","temp");
| |
| 211 | $data{'cw'} = get_data("condition","text");
| |
| 212 | $data{'cd'} = get_data("condition","date");
| |
| 213 | ||
| 214 | # Current Atmosphere Information | |
| 215 | $data{'ah'} = get_data("atmosphere","humidity");
| |
| 216 | $data{'av'} = get_data("atmosphere","visibility");
| |
| 217 | $data{'ap'} = get_data("atmosphere","pressure");
| |
| 218 | $data{'ar'} = get_data("atmosphere","rising");
| |
| 219 | ||
| 220 | # Todays Sunrise and sunset | |
| 221 | $data{'sr'} = get_data("astronomy","sunrise");
| |
| 222 | $data{'ss'} = get_data("astronomy","sunset");
| |
| 223 | ||
| 224 | # Current wind information | |
| 225 | $data{'wc'} = get_data("wind","chill");
| |
| 226 | $data{'wd'} = get_data("wind","direction");
| |
| 227 | $data{'ws'} = get_data("wind","speed");
| |
| 228 | ||
| 229 | # Unit information | |
| 230 | $data{'ut'} =get_data("units","temperature");
| |
| 231 | $data{'ud'} =get_data("units","distance");
| |
| 232 | $data{'up'} =get_data("units","pressure");
| |
| 233 | $data{'us'} =get_data("units","speed");
| |
| 234 | ||
| 235 | # Forecast (Today) | |
| 236 | $data{'fd1'} =get_data("forecast[1]","day");
| |
| 237 | $data{'fg1'} =get_data("forecast[1]","date");
| |
| 238 | $data{'fl1'} =get_data("forecast[1]","low");
| |
| 239 | $data{'fh1'} =get_data("forecast[1]","high");
| |
| 240 | $data{'ft1'} =get_data("forecast[1]","text");
| |
| 241 | $data{'fc1'} =get_data("forecast[1]","code");
| |
| 242 | ||
| 243 | # Forecast (Tomorrow) | |
| 244 | $data{'fd2'} =get_data("forecast[2]","day");
| |
| 245 | $data{'fg2'} =get_data("forecast[2]","date");
| |
| 246 | $data{'fl2'} =get_data("forecast[2]","low");
| |
| 247 | $data{'fh2'} =get_data("forecast[2]","high");
| |
| 248 | $data{'ft2'} =get_data("forecast[2]","text");
| |
| 249 | $data{'fc2'} =get_data("forecast[2]","code");
| |
| 250 | ||
| 251 | # Current feels like | |
| 252 | $data{'cfl'} = calculate_feels_like();
| |
| 253 | ||
| 254 | # Check if image exist | |
| 255 | if (!(-e $imagefile)){copy_image()}
| |
| 256 | ||
| 257 | ################################################################# | |
| 258 | # Parse arguments | |
| 259 | ################################################################# | |
| 260 | if(($#ARGV + 1) == 1){
| |
| 261 | my $arg = substr($ARGV[0],1); | |
| 262 | if (defined($data{$arg})){
| |
| 263 | args($arg); | |
| 264 | } elsif($arg eq "-update"){
| |
| 265 | update_weather(); | |
| 266 | } elsif($arg eq "-copyimage"){
| |
| 267 | copy_image(); | |
| 268 | } else {
| |
| 269 | usage(); | |
| 270 | } | |
| 271 | } else {
| |
| 272 | usage(); | |
| 273 | } |