Use dedicated geo api instead of builtin for openweathermap api requests
This commit is contained in:
@@ -29,6 +29,74 @@ sub Weather {
|
||||
|
||||
$city = ucfirst $city;
|
||||
|
||||
my $cache = CHI->new (
|
||||
driver => 'BerkeleyDB',
|
||||
root_dir => $c->{cachedir},
|
||||
namespace => __PACKAGE__,
|
||||
);
|
||||
|
||||
my $geoCallBack = sub {
|
||||
my $appid = $c->{openweathermap}->{appid};
|
||||
my $geo;
|
||||
|
||||
my $r;
|
||||
|
||||
# Try 3 times and giveup
|
||||
for (1..3) {
|
||||
my $http = HTTP::Tiny->new (timeout => 3);
|
||||
$r = $http->get (
|
||||
sprintf (
|
||||
'http://api.openweathermap.org/geo/1.0/direct?q=%s&limit=1&APPID=%s',
|
||||
urlencode ($city),
|
||||
$appid,
|
||||
),
|
||||
);
|
||||
|
||||
if ($r->{success}) {
|
||||
last;
|
||||
}
|
||||
|
||||
sleep 2;
|
||||
}
|
||||
|
||||
# All 3 times it can give us error, so check this case here
|
||||
if ($r->{success}) {
|
||||
$geo = eval {
|
||||
decode_json ($r->{content});
|
||||
};
|
||||
|
||||
unless ($geo) {
|
||||
$log->warn ("[WARN] openweathermap geo api returns corrupted json: $EVAL_ERROR");
|
||||
return undef;
|
||||
}
|
||||
} else {
|
||||
$log->warn (
|
||||
sprintf (
|
||||
'[WARN] Server api.openweathermap.org return status %s with message: %s in request to geo',
|
||||
$r->{status},
|
||||
$r->{reason},
|
||||
),
|
||||
);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (defined ($geo->[0]->{lat}) && defined ($geo->[0]->{lon})) {
|
||||
# Success
|
||||
return $geo->[0];
|
||||
} else {
|
||||
# Error, no coordinates
|
||||
$log->warn ('[WARN] Server api.openweathermap.org does not return coordinates in response to geo request');
|
||||
return undef;
|
||||
}
|
||||
};
|
||||
|
||||
my $geo = $cache->compute (
|
||||
$city,
|
||||
'2 months',
|
||||
$geoCallBack,
|
||||
);
|
||||
|
||||
my $weatherCallBack = sub {
|
||||
my $appid = $c->{openweathermap}->{appid};
|
||||
|
||||
@@ -41,10 +109,18 @@ sub Weather {
|
||||
my $w;
|
||||
my $r;
|
||||
|
||||
if (defined $geo) {
|
||||
# try 3 times and giveup
|
||||
for (1..3) {
|
||||
my $http = HTTP::Tiny->new (timeout => 3);
|
||||
$r = $http->get (sprintf ('http://api.openweathermap.org/data/2.5/weather?q=%s&lang=ru&APPID=%s', urlencode ($city), $appid));
|
||||
$r = $http->get (
|
||||
sprintf (
|
||||
'http://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&lang=ru&APPID=%s',
|
||||
$geo->{lat},
|
||||
$geo->{lon},
|
||||
$appid,
|
||||
),
|
||||
);
|
||||
|
||||
if ($r->{success}) {
|
||||
last;
|
||||
@@ -121,16 +197,14 @@ sub Weather {
|
||||
}
|
||||
|
||||
return $w;
|
||||
} else {
|
||||
# No geo, no weather :'(
|
||||
return undef;
|
||||
}
|
||||
};
|
||||
|
||||
my $cache = CHI->new (
|
||||
driver => 'BerkeleyDB',
|
||||
root_dir => $c->{cachedir},
|
||||
namespace => __PACKAGE__,
|
||||
);
|
||||
|
||||
my $w = $cache->compute (
|
||||
$city,
|
||||
"$geo->{lat}+$geo->{lon}",
|
||||
'3 hours',
|
||||
$weatherCallBack,
|
||||
);
|
||||
@@ -139,8 +213,9 @@ sub Weather {
|
||||
|
||||
if ($w) {
|
||||
if ($w->{temperature_min} == $w->{temperature_max}) {
|
||||
$reply = sprintf ("Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.с",
|
||||
$w->{name},
|
||||
$reply = sprintf (
|
||||
"Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.с",
|
||||
$city,
|
||||
$w->{country},
|
||||
ucfirst ($w->{description}),
|
||||
$w->{wind_direction},
|
||||
@@ -151,8 +226,9 @@ sub Weather {
|
||||
$w->{pressure},
|
||||
);
|
||||
} else {
|
||||
$reply = sprintf ("Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s-%s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.ст",
|
||||
$w->{name},
|
||||
$reply = sprintf (
|
||||
"Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s-%s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.ст",
|
||||
$city,
|
||||
$w->{country},
|
||||
ucfirst ($w->{description}),
|
||||
$w->{wind_direction},
|
||||
|
||||
Reference in New Issue
Block a user