00001 #! /usr/bin/perl -w
00002
00003 #
00004 # Based on nwsxml.pl by Lucien Dunning
00005 #
00006
00007 use strict;
00008 use XML::Simple;
00009 use LWP::Simple;
00010 # Ideally we would use the If-Modified-Since header
00011 # to reduce server load, but they ignore it
00012 #use HTTP::Cache::Transparent;
00013 use Getopt::Std;
00014 use File::Basename;
00015 use lib dirname($0);
00016 use BBCLocation;
00017
00018 our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d);
00019
00020 my $name = 'BBC-3day-XML';
00021 my $version = 0.1;
00022 my $author = 'Stuart Morgan';
00023 my $email = 'stuart@tase.co.uk';
00024 my $updateTimeout = 360*60; # 6 Hours
00025 my $retrieveTimeout = 30;
00026 my @types = ('3dlocation', 'station_id', 'copyright', 'weather_icon',
00027 'date-0', 'icon-0', 'low-0', 'high-0',
00028 'date-1', 'icon-1', 'low-1', 'high-1',
00029 'date-2', 'icon-2', 'low-2', 'high-2', 'updatetime');
00030 my $dir = "./";
00031
00032 getopts('Tvtlu:d:');
00033
00034 if (defined $opt_v) {
00035 print "$name,$version,$author,$email\n";
00036 exit 0;
00037 }
00038
00039 if (defined $opt_T) {
00040 print "$updateTimeout,$retrieveTimeout\n";
00041 exit 0;
00042 }
00043
00044 if (defined $opt_l) {
00045
00046 my $search = shift;
00047 my @results = BBCLocation::Search($search);
00048 my $result;
00049
00050 foreach (@results) {
00051 print $_ . "\n";
00052 }
00053
00054 exit 0;
00055 }
00056
00057 if (defined $opt_t) {
00058 foreach (@types) {print; print "\n";}
00059 exit 0;
00060 }
00061
00062 if (defined $opt_d) {
00063 $dir = $opt_d;
00064 }
00065
00066
00067 # we get here, we're doing an actual retrieval, everything must be defined
00068 my $locid = shift;
00069 if (!(defined $opt_u && defined $locid && !$locid eq "")) {
00070 die "Invalid usage";
00071 }
00072
00073 my $units = $opt_u;
00074 my $base_url;
00075 my $local_base_url = 'http://feeds.bbc.co.uk/weather/feeds/rss/5day/id/';
00076 my $world_base_url = 'http://feeds.bbc.co.uk/weather/feeds/rss/5day/world/';
00077
00078 if ($locid =~ s/^W(.*)/$1/)
00079 {
00080 $base_url = $world_base_url;
00081 }
00082 elsif ($locid =~ s/^L(.*)/$1/)
00083 {
00084 $base_url = $local_base_url;
00085 }
00086 else
00087 {
00088 die "Invalid Location ID";
00089 }
00090
00091 my $response = get $base_url . $locid . '.xml';
00092 die unless defined $response;
00093
00094 my $xml = XMLin($response);
00095
00096 if (!$xml) {
00097 die "Not xml";
00098 }
00099
00100 printf "copyright::From bbc.co.uk\n";
00101 printf "station_id::" . $locid . "\n";
00102 my $location = $xml->{channel}->{title};
00103 $location =~ s/.*?Forecast for (.*)$/$1/s;
00104 printf "3dlocation::" . $location . "\n";
00105 printf "updatetime::Updated " . localtime() . "\n";
00106
00107 my $i = 0;
00108 my $item;
00109
00110 foreach $item (@{$xml->{channel}->{item}}) {
00111
00112 my $item_title = $item->{title};
00113 $item_title =~ s/\n
00114
00115 my $day = $item_title;
00116 $day =~ s/^(.*?):.*/$1/;
00117 printf "date-" . $i . "::" . $day . "\n";
00118
00119 my $weather_string = $item_title;
00120 $weather_string =~ s/.*?\: (.*?),.*/$1/s;
00121 $weather_string = ucfirst($weather_string);
00122
00123 if ($weather_string =~ /^cloudy$/i) {
00124 printf "icon-" . $i . "::cloudy.png\n";
00125 }
00126 elsif ($weather_string =~ /^foggy$/i ||
00127 $weather_string =~ /^misty$/i) {
00128 printf "icon-" . $i . "::fog.png\n";
00129 }
00130 elsif ($weather_string =~ /^sunny$/i) {
00131 printf "icon-" . $i . "::sunny.png\n";
00132 }
00133 elsif ($weather_string =~ /^sunny intervals$/i ||
00134 $weather_string =~ /^partly cloudy$/i) {
00135 printf "icon-" . $i . "::pcloudy.png\n";
00136 }
00137 elsif ($weather_string =~ /^drizzle$/i ||
00138 $weather_string =~ /^light rain$/i ||
00139 $weather_string =~ /^light showers$/i) {
00140 printf "icon-" . $i . "::lshowers.png\n";
00141 }
00142 elsif ($weather_string =~ /^heavy rain$/i ||
00143 $weather_string =~ /^heavy showers$/i) {
00144 printf "icon-" . $i . "::showers.png\n";
00145 }
00146 elsif ($weather_string =~ /^thundery rain$/i ||
00147 $weather_string =~ /^thundery showers$/i) {
00148 printf "icon-" . $i . "::thunshowers.png\n";
00149 }
00150 elsif ($weather_string =~ /^heavy snow$/i) {
00151 printf "icon-" . $i . "::snowshow.png\n";
00152 }
00153 elsif ($weather_string =~ /^light snow$/i ||
00154 $weather_string =~ /^light snow showers$/i) {
00155 printf "icon-" . $i . "::flurries.png\n";
00156 }
00157 elsif ($weather_string =~ /^sleet$/i ||
00158 $weather_string =~ /^sleet showers$/i ||
00159 $weather_string =~ /^hail showers$/i) {
00160 printf "icon-" . $i . "::rainsnow.png\n";
00161 }
00162 elsif ($weather_string =~ /^clear$/i) {
00163 printf "icon-" . $i . "::fair.png\n";
00164 }
00165 else {
00166 printf "icon-" . $i . "::unknown.png\n";
00167 }
00168
00169 my @data = split(/, /, $item->{description});
00170 foreach (@data) {
00171 my $datalabel;
00172 my $datavalue;
00173
00174 ($datalabel, $datavalue) = split(': ', $_);
00175 if ($datalabel =~ /.*Temp$/) {
00176 if ($units =~ /ENG/) {
00177 $datavalue =~ s/^.*?\((-?\d{1,2}).*/$1/;
00178 }
00179 elsif ($units =~ /SI/) {
00180 $datavalue =~ s/^(-?\d{1,2}).*/$1/;
00181 }
00182 if ($datalabel =~ /^Max.*/) {
00183 $datalabel = "high-" . $i;
00184 }
00185 elsif ($datalabel =~ /^Min.*/) {
00186 $datalabel = "low-" . $i;
00187 }
00188
00189 }
00190 else {
00191 next;
00192 }
00193
00194 printf $datalabel . "::" . $datavalue . "\n";
00195 }
00196
00197 $i++;
00198 }