00001 #! /usr/bin/perl
00002 # vim:ts=4:sw=4:ai:et:si:sts=4
00003
00004 use strict;
00005 use warnings;
00006
00007 use utf8;
00008 use encoding 'utf8';
00009 use English;
00010
00011 use File::Basename;
00012 use Cwd 'abs_path';
00013 use lib dirname(abs_path($0 or $PROGRAM_NAME)),
00014 '/usr/share/mythtv/mythweather/scripts/uk_bbc',
00015 '/usr/local/share/mythtv/mythweather/scripts/uk_bbc';
00016
00017 use XML::Simple;
00018 use LWP::Simple;
00019 use Getopt::Std;
00020 use File::Path;
00021
00022 use File::Basename;
00023 use lib dirname($0);
00024 use BBCLocation;
00025
00026 our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d, $opt_D);
00027
00028 my $name = 'BBC-3day-XML';
00029 my $version = 0.3;
00030 my $author = 'Gavin Hurlbut / Stuart Morgan';
00031 my $email = 'gjhurlbu@gmail.com / stuart@tase.co.uk';
00032 my $updateTimeout = 360*60; # 6 Hours
00033 my $retrieveTimeout = 30;
00034 my @types = ('3dlocation', 'station_id', 'copyright', 'weather_icon',
00035 'date-0', 'icon-0', 'low-0', 'high-0',
00036 'date-1', 'icon-1', 'low-1', 'high-1',
00037 'date-2', 'icon-2', 'low-2', 'high-2', 'updatetime');
00038 my $dir = "/tmp/uk_bbc";
00039 my $logdir = "/tmp/uk_bbc";
00040
00041 binmode(STDOUT, ":utf8");
00042
00043 if (!-d $logdir) {
00044 mkpath( $logdir, {mode => 0755} );
00045 }
00046
00047 getopts('Tvtlu:d:');
00048
00049 if (defined $opt_v) {
00050 print "$name,$version,$author,$email\n";
00051 log_print( $logdir, "-v\n" );
00052 exit 0;
00053 }
00054
00055 if (defined $opt_T) {
00056 print "$updateTimeout,$retrieveTimeout\n";
00057 log_print( $logdir, "-t\n" );
00058 exit 0;
00059 }
00060
00061 if (defined $opt_d) {
00062 $dir = $opt_d;
00063 }
00064
00065 if (!-d $dir) {
00066 mkpath( $dir, {mode => 0755} );
00067 }
00068
00069 if (defined $opt_l) {
00070 my $search = shift;
00071 log_print( $logdir, "-l $search\n" );
00072 my @results = BBCLocation::Search($search, $dir, $updateTimeout, $logdir);
00073 my $result;
00074
00075 foreach (@results) {
00076 print $_ . "\n";
00077 }
00078
00079 exit 0;
00080 }
00081
00082 if (defined $opt_t) {
00083 foreach (@types) {print; print "\n";}
00084 exit 0;
00085 }
00086
00087
00088 # we get here, we're doing an actual retrieval, everything must be defined
00089 my $locid = BBCLocation::FindLoc(shift, $dir, $updateTimeout, $logdir);
00090 if (!(defined $opt_u && defined $locid && !$locid eq "")) {
00091 die "Invalid usage";
00092 }
00093
00094 my $units = $opt_u;
00095 my $base_url = 'http://newsrss.bbc.co.uk/weather/forecast/';
00096 my $base_xml = '/Next3DaysRSS.xml';
00097
00098 if ($locid =~ s/^(\d*)/$1/)
00099 {
00100 $base_url = $base_url . $1 . $base_xml;
00101 }
00102 else
00103 {
00104 die "Invalid Location ID";
00105 }
00106
00107
00108 my $response = get $base_url;
00109 die unless defined $response;
00110
00111 my $xml = XMLin($response);
00112
00113 if (!$xml) {
00114 die "Not xml";
00115 }
00116
00117 printf "copyright::From bbc.co.uk\n";
00118 printf "station_id::" . $locid . "\n";
00119 my $location = $xml->{channel}->{title};
00120 $location =~ s/.*?Forecast for (.*)$/$1/s;
00121 printf "3dlocation::" . $location . "\n";
00122 printf "updatetime::Updated " . localtime() . "\n";
00123
00124 my $i = 0;
00125 my $item;
00126
00127 foreach $item (@{$xml->{channel}->{item}}) {
00128
00129 my $item_title = $item->{title};
00130 $item_title =~ s/\n
00131
00132 my $day = $item_title;
00133 $day =~ s/^(.*?):.*/$1/;
00134
00135 if ($day eq 'Sunday') {
00136 $day = '0';
00137 }
00138 elsif ($day eq 'Monday') {
00139 $day = '1';
00140 }
00141 elsif ($day eq 'Tuesday') {
00142 $day = '2';
00143 }
00144 elsif ($day eq 'Wednesday') {
00145 $day = '3';
00146 }
00147 elsif ($day eq 'Thursday') {
00148 $day = '4';
00149 }
00150 elsif ($day eq 'Friday') {
00151 $day = '5';
00152 }
00153 elsif ($day eq 'Saturday') {
00154 $day = '6';
00155 }
00156
00157 printf "date-" . $i . "::" . $day . "\n";
00158
00159 my $weather_string = $item_title;
00160 $weather_string =~ s/.*?\: (.*?),.*/$1/s;
00161 $weather_string = ucfirst($weather_string);
00162
00163 if ($weather_string =~ /^cloudy$/i ||
00164 $weather_string =~ /^grey cloud$/i ||
00165 $weather_string =~ /^white cloud$/i) {
00166 printf "icon-" . $i . "::cloudy.png\n";
00167 }
00168 elsif ($weather_string =~ /^fog$/i ||
00169 $weather_string =~ /^foggy$/i ||
00170 $weather_string =~ /^mist$/i ||
00171 $weather_string =~ /^misty$/i) {
00172 printf "icon-" . $i . "::fog.png\n";
00173 }
00174 elsif ($weather_string =~ /^sunny$/i) {
00175 printf "icon-" . $i . "::sunny.png\n";
00176 }
00177 elsif ($weather_string =~ /^sunny intervals$/i ||
00178 $weather_string =~ /^partly cloudy$/i) {
00179 printf "icon-" . $i . "::pcloudy.png\n";
00180 }
00181 elsif ($weather_string =~ /^drizzle$/i ||
00182 $weather_string =~ /^light rain$/i ||
00183 $weather_string =~ /^light rain showers?$/i ||
00184 $weather_string =~ /^light showers?$/i) {
00185 printf "icon-" . $i . "::lshowers.png\n";
00186 }
00187 elsif ($weather_string =~ /^heavy rain$/i ||
00188 $weather_string =~ /^heavy showers?$/i ||
00189 $weather_string =~ /^heavy rain showers?$/i) {
00190 printf "icon-" . $i . "::showers.png\n";
00191 }
00192 elsif ($weather_string =~ /^thundery rain$/i ||
00193 $weather_string =~ /^thunder storm$/i ||
00194 $weather_string =~ /^thundery showers?$/i) {
00195 printf "icon-" . $i . "::thunshowers.png\n";
00196 }
00197 elsif ($weather_string =~ /^heavy snow$/i) {
00198 printf "icon-" . $i . "::snowshow.png\n";
00199 }
00200 elsif ($weather_string =~ /^light snow$/i ||
00201 $weather_string =~ /^light snow showers?$/i) {
00202 printf "icon-" . $i . "::flurries.png\n";
00203 }
00204 elsif ($weather_string =~ /^sleet$/i ||
00205 $weather_string =~ /^sleet showers?$/i ||
00206 $weather_string =~ /^hail showers?$/i) {
00207 printf "icon-" . $i . "::rainsnow.png\n";
00208 }
00209 elsif ($weather_string =~ /^clear$/i ||
00210 $weather_string =~ /^clear sky$/i) {
00211 printf "icon-" . $i . "::fair.png\n";
00212 }
00213 else {
00214 printf "icon-" . $i . "::unknown.png\n";
00215 }
00216
00217 my @data = split(/, /, $item->{description});
00218 foreach (@data) {
00219 my $datalabel;
00220 my $datavalue;
00221
00222 ($datalabel, $datavalue) = split(': ', $_);
00223 if ($datalabel =~ /.*Temp$/) {
00224 if ($units =~ /ENG/) {
00225 $datavalue =~ s/^.*?\((-?\d{1,2}).*/$1/;
00226 }
00227 elsif ($units =~ /SI/) {
00228 $datavalue =~ s/^(-?\d{1,2}).*/$1/;
00229 }
00230 if ($datalabel =~ /^Max.*/) {
00231 $datalabel = "high-" . $i;
00232 }
00233 elsif ($datalabel =~ /^Min.*/) {
00234 $datalabel = "low-" . $i;
00235 }
00236
00237 }
00238 else {
00239 next;
00240 }
00241
00242 printf $datalabel . "::" . $datavalue . "\n";
00243 }
00244
00245 $i++;
00246 }
00247
00248 sub log_print {
00249 return if not defined $::opt_D;
00250 my $dir = shift;
00251
00252 open OF, ">>$dir/uk_bbc.log";
00253 print OF @_;
00254 close OF;
00255 }