weather: for one-line weather report.
This commit is contained in:
parent
d6ae54bb68
commit
8347488f34
|
@ -0,0 +1,148 @@
|
|||
#!/usr/bin/perl -w
|
||||
# Inspired by "ansiweather".
|
||||
|
||||
use English qw(-no_match_vars);
|
||||
use strict;
|
||||
use File::Basename;
|
||||
use Getopt::Long;
|
||||
use JSON;
|
||||
use WWW::Mechanize;
|
||||
use POSIX qw(strftime);
|
||||
use Time::Piece;
|
||||
use utf8;
|
||||
|
||||
my $verbose = 0;
|
||||
|
||||
sub show_help {
|
||||
my ($exit_code) = @_;
|
||||
my $name = basename($PROGRAM_NAME);
|
||||
print <<EOF;
|
||||
usage: $name [OPTION] LOCATION
|
||||
Print a weather report for LOCATION using data from
|
||||
openweathermap.org.
|
||||
|
||||
OPTIONS
|
||||
--verbose Be verbose and print the data structure returned
|
||||
by openweathermap.
|
||||
|
||||
--help Print this help.
|
||||
|
||||
LOCATION
|
||||
A city name or "city,xx" where xx is the two-letter country code.
|
||||
|
||||
Examples
|
||||
\$ $name --verbose "Paris,FR"
|
||||
\$ $name "Asunción,PY"
|
||||
EOF
|
||||
exit($exit_code);
|
||||
}
|
||||
|
||||
sub tstamp { strftime("%F %T %Z ", localtime); }
|
||||
sub vprint { print(@_) if ($verbose); }
|
||||
sub vprintf { printf(@_) if ($verbose); }
|
||||
sub vtprint { vprint(tstamp()); vprint(@_); }
|
||||
sub vtprintf { vprint(tstamp()); vprintf(@_); }
|
||||
|
||||
STDERR->autoflush(1);
|
||||
STDOUT->autoflush(1);
|
||||
binmode(STDOUT, ":utf8");
|
||||
|
||||
GetOptions(
|
||||
"help" => \my $help,
|
||||
"verbose" => \$verbose,
|
||||
);
|
||||
|
||||
show_help(0) if ($help);
|
||||
|
||||
my $location = do {
|
||||
1 == (scalar @ARGV) or show_help(1);
|
||||
$ARGV[0];
|
||||
};
|
||||
|
||||
# Return the weather report as a character string.
|
||||
sub get_response {
|
||||
vtprint("get_response begins\n");
|
||||
my $mech = WWW::Mechanize->new();
|
||||
|
||||
vprint("Getting weather report...\n");
|
||||
my $wthr_response = $mech->get(
|
||||
'http://api.openweathermap.org/data/2.5/weather?q='
|
||||
. $location . '&units=metric&appid=85a4e3c55b73909f42c6a23ec35b7147'
|
||||
);
|
||||
my $wthr_str = $wthr_response->content(raw => 1);
|
||||
die("Didn't find content in http response.\n") if (! $wthr_str);
|
||||
utf8::decode($wthr_str) or die("failed to decode response\n");
|
||||
|
||||
vprint("get_response returning\n");
|
||||
return $wthr_str;
|
||||
}
|
||||
|
||||
sub format_time {
|
||||
my ($r) = @_;
|
||||
my $t = localtime($r->{dt});
|
||||
return $t->strftime('%H:%M %Z');
|
||||
}
|
||||
|
||||
sub format_speed {
|
||||
my ($r) = @_;
|
||||
return sprintf("%.0fKm/h", 3.6 * $r->{wind}->{speed});
|
||||
}
|
||||
|
||||
my @directions = qw(N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW);
|
||||
my $point_count = scalar(@directions);
|
||||
|
||||
sub format_direction {
|
||||
my ($r) = @_;
|
||||
my $deg = $r->{wind}->{deg};
|
||||
if (0 == $r->{wind}->{speed}) {
|
||||
return "";
|
||||
} else {
|
||||
my $idx = (
|
||||
($deg + (365 / (2 * $point_count))) / (365 / $point_count)
|
||||
) % $point_count;
|
||||
return sprintf(" %s", $directions[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
sub format_wind {
|
||||
my ($r) = @_;
|
||||
return sprintf("%s%s", format_speed($r), format_direction($r));
|
||||
}
|
||||
|
||||
sub format_temperature {
|
||||
my ($r) = @_;
|
||||
return sprintf("%.1f°C", $r->{main}->{temp});
|
||||
}
|
||||
|
||||
sub format_humidity {
|
||||
my ($r) = @_;
|
||||
return sprintf("%d%% RH", $r->{main}->{humidity});
|
||||
}
|
||||
|
||||
sub format_sky {
|
||||
my ($r) = @_;
|
||||
return sprintf("%s", $r->{weather}->[0]->{main});
|
||||
}
|
||||
|
||||
sub format_response {
|
||||
my ($r) = @_;
|
||||
return sprintf(
|
||||
"Weather at %s ► %s ◆ %s ◆ %s ◆ %s\n",
|
||||
format_time($r),
|
||||
format_temperature($r),
|
||||
format_sky($r),
|
||||
format_wind($r),
|
||||
format_humidity($r),
|
||||
);
|
||||
}
|
||||
|
||||
my $wthr_str = get_response();
|
||||
vprint("turning the response string into a hashref...\n");
|
||||
my $json = JSON->new;
|
||||
my $wthr_hashref = $json->decode($wthr_str);
|
||||
vprintf("pretty-printing the hashref...\n");
|
||||
printf("%s\n", $json->pretty->encode($wthr_hashref)) if ($verbose);
|
||||
vprint("formatting weather report...\n");
|
||||
print format_response($wthr_hashref);
|
||||
|
||||
exit(0);
|
Loading…
Reference in New Issue