Replace HTTP::Tiny with Mojo::UserAgent and Mojo::UserAgent::Cached
This commit is contained in:
5
cpanfile
5
cpanfile
@@ -1,5 +1,8 @@
|
|||||||
requires 'Carp';
|
requires 'Carp';
|
||||||
|
requires 'CHI';
|
||||||
|
requires 'CHI::Driver::BerkeleyDB';
|
||||||
requires 'Cwd::utf8';
|
requires 'Cwd::utf8';
|
||||||
|
requires 'DateTime';
|
||||||
requires 'DB_File';
|
requires 'DB_File';
|
||||||
requires 'SQLite_File';
|
requires 'SQLite_File';
|
||||||
requires 'Digest::HMAC_SHA1';
|
requires 'Digest::HMAC_SHA1';
|
||||||
@@ -10,7 +13,6 @@ requires 'File::Basename';
|
|||||||
requires 'File::Path';
|
requires 'File::Path';
|
||||||
requires 'Hailo';
|
requires 'Hailo';
|
||||||
requires 'HTML::TokeParser';
|
requires 'HTML::TokeParser';
|
||||||
requires 'HTTP::Tiny';
|
|
||||||
requires 'IO::Socket::SSL';
|
requires 'IO::Socket::SSL';
|
||||||
requires 'JSON';
|
requires 'JSON';
|
||||||
requires 'JSON::XS';
|
requires 'JSON::XS';
|
||||||
@@ -23,6 +25,7 @@ requires 'Math::Random::Secure';
|
|||||||
requires 'Mojo::Base';
|
requires 'Mojo::Base';
|
||||||
requires 'Mojo::IOLoop';
|
requires 'Mojo::IOLoop';
|
||||||
requires 'Mojo::UserAgent';
|
requires 'Mojo::UserAgent';
|
||||||
|
requires 'Mojo::UserAgent::Cached';
|
||||||
requires 'Text::Fuzzy';
|
requires 'Text::Fuzzy';
|
||||||
requires 'URI::Encode::XS';
|
requires 'URI::Encode::XS';
|
||||||
requires 'URI::URL';
|
requires 'URI::URL';
|
||||||
|
|||||||
14
lib/buni.pm
14
lib/buni.pm
@@ -7,8 +7,8 @@ use utf8;
|
|||||||
use open qw (:std :utf8);
|
use open qw (:std :utf8);
|
||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Carp qw (cluck);
|
use Carp qw (cluck);
|
||||||
use HTTP::Tiny;
|
|
||||||
use HTML::TokeParser;
|
use HTML::TokeParser;
|
||||||
|
use Mojo::UserAgent;
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
@@ -19,18 +19,18 @@ sub buni {
|
|||||||
my $ret = 'Нету Buni';
|
my $ret = 'Нету Buni';
|
||||||
|
|
||||||
for (1..3) {
|
for (1..3) {
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$r = $http->get ('http://www.bunicomic.com/?random&nocache=1');
|
$r = $ua->get ('http://www.bunicomic.com/?random&nocache=1')->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $p = HTML::TokeParser->new(\$r->{content});
|
my $p = HTML::TokeParser->new(\$r->body);
|
||||||
my @a;
|
my @a;
|
||||||
|
|
||||||
# additional {} required in order "last" to work properly :)
|
# additional {} required in order "last" to work properly :)
|
||||||
@@ -47,7 +47,7 @@ sub buni {
|
|||||||
} while ($#{$a[0]} > 1);
|
} while ($#{$a[0]} > 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|||||||
58
lib/drink.pm
58
lib/drink.pm
@@ -5,11 +5,16 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use utf8;
|
use utf8;
|
||||||
use open qw (:std :utf8);
|
use open qw (:std :utf8);
|
||||||
|
use CHI;
|
||||||
|
use CHI::Driver::BerkeleyDB;
|
||||||
|
use DateTime;
|
||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Encode;
|
use Encode;
|
||||||
use Carp qw (cluck);
|
use Carp qw (cluck);
|
||||||
use HTTP::Tiny;
|
|
||||||
use HTML::TokeParser;
|
use HTML::TokeParser;
|
||||||
|
use Mojo::Log;
|
||||||
|
use Mojo::UserAgent::Cached;
|
||||||
|
use POSIX qw (strftime);
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
@@ -23,19 +28,56 @@ sub drink {
|
|||||||
my ($dayNum, $monthNum) = (localtime ())[3, 4];
|
my ($dayNum, $monthNum) = (localtime ())[3, 4];
|
||||||
my $url = sprintf 'https://kakoysegodnyaprazdnik.ru/baza/%s/%s', $MONTH[$monthNum], $dayNum;
|
my $url = sprintf 'https://kakoysegodnyaprazdnik.ru/baza/%s/%s', $MONTH[$monthNum], $dayNum;
|
||||||
|
|
||||||
for (1..3) {
|
# Those POSIX assholes just forgot to add unix timestamps without TZ offset, so...
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my ($mday, $mon, $year) = (gmtime ())[3, 4, 5];
|
||||||
$r = $http->get ($url, {'Accept-Charset' => 'utf-8', 'Accept-Language' => 'ru-RU'});
|
my $offset = strftime ('%z', gmtime ());
|
||||||
|
my $offsetMinutes = (substr $offset, -2) * 60;
|
||||||
|
my $offsetHours = (substr $offset, 1, 2) * 60 * 60;
|
||||||
|
my $offsetSign;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ((substr $offset, 0, 1) eq '+') {
|
||||||
|
$offsetSign = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $expirationDate = DateTime->new (
|
||||||
|
year => $year + 1900,
|
||||||
|
month => $mon + 1,
|
||||||
|
day => $mday,
|
||||||
|
hour => 0,
|
||||||
|
minute => 0,
|
||||||
|
second => 0
|
||||||
|
)->add (days => 1)->strftime ('%s');
|
||||||
|
|
||||||
|
if ((substr $offset, 0, 1) eq '+') {
|
||||||
|
$expirationDate = $expirationDate - $offsetHours - $offsetMinutes;
|
||||||
|
} else {
|
||||||
|
$expirationDate = $expirationDate + $offsetHours + $offsetMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (1..3) {
|
||||||
|
my $ua = Mojo::UserAgent::Cached->new->connect_timeout (3);
|
||||||
|
$ua->cache_agent(
|
||||||
|
CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => 'data/cache',
|
||||||
|
namespace => __PACKAGE__,
|
||||||
|
expires_at => $expirationDate,
|
||||||
|
expires_on_backend => 1,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
# just to make Mojo::UserAgent::Cached happy
|
||||||
|
$ua->logger (Mojo::Log->new (path => '/dev/null', level => 'error'));
|
||||||
|
$r = $ua->get ($url => {'Accept-Language' => 'ru-RU', 'Accept-Charset' => 'utf-8'})->result;
|
||||||
|
|
||||||
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $p = HTML::TokeParser->new(\$r->{content});
|
my $p = HTML::TokeParser->new(\$r->body);
|
||||||
my @a;
|
my @a;
|
||||||
my @holyday;
|
my @holyday;
|
||||||
|
|
||||||
@@ -58,7 +100,7 @@ sub drink {
|
|||||||
$ret = join "\n", @holyday;
|
$ret = join "\n", @holyday;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|||||||
103
lib/flickr.pm
103
lib/flickr.pm
@@ -9,10 +9,9 @@ use English qw ( -no_match_vars );
|
|||||||
use Carp qw (cluck);
|
use Carp qw (cluck);
|
||||||
use Digest::HMAC_SHA1 qw (hmac_sha1);
|
use Digest::HMAC_SHA1 qw (hmac_sha1);
|
||||||
use File::Path qw (make_path);
|
use File::Path qw (make_path);
|
||||||
use JSON::XS;
|
|
||||||
use HTTP::Tiny;
|
|
||||||
use Math::Random::Secure qw (irand);
|
use Math::Random::Secure qw (irand);
|
||||||
use MIME::Base64;
|
use MIME::Base64;
|
||||||
|
use Mojo::UserAgent;
|
||||||
use SQLite_File;
|
use SQLite_File;
|
||||||
use URI::Encode::XS qw (uri_encode);
|
use URI::Encode::XS qw (uri_encode);
|
||||||
|
|
||||||
@@ -120,15 +119,15 @@ sub flickrRequestToken {
|
|||||||
uri_encode ($flickr_callback_url)
|
uri_encode ($flickr_callback_url)
|
||||||
);
|
);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
my $r = $http->get ($url);
|
my $r = $ua->get ($url)->result;
|
||||||
my %params;
|
my %params;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
# they ignore format=json, so...
|
# they ignore format=json, so...
|
||||||
%params = map {split /=/} split /&/, $r->{content};
|
%params = map {split /=/} split /&/, $r->body;
|
||||||
} else {
|
} else {
|
||||||
say "Something bad returns from flickr api: $r->{status} $r->{content}"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
say "Something bad returns from flickr api: $r->code $r->message"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
}
|
}
|
||||||
|
|
||||||
return %params;
|
return %params;
|
||||||
@@ -161,15 +160,15 @@ sub flickrAccessToken {
|
|||||||
uri_encode ($oauth_signature)
|
uri_encode ($oauth_signature)
|
||||||
);
|
);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
my $r = $http->get ($url);
|
my $r = $ua->get ($url)->result;
|
||||||
my %params;
|
my %params;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
# they ignore format=json
|
# they ignore format=json
|
||||||
%params = map {split /=/} split /&/, $r->{content};
|
%params = map {split /=/} split /&/, $r->body;
|
||||||
} else {
|
} else {
|
||||||
say "Something bad returns from flickr api: $r->{status} $r->{content}"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
say "Something bad returns from flickr api: $r->code $r->message"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
}
|
}
|
||||||
|
|
||||||
return %params;
|
return %params;
|
||||||
@@ -183,13 +182,13 @@ sub flickrAuthorization {
|
|||||||
$flickr_request_token,
|
$flickr_request_token,
|
||||||
);
|
);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
my $r = $http->get ($url);
|
my $r = $ua->get ($url)->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
return $r->{url};
|
return $r->url;
|
||||||
} else {
|
} else {
|
||||||
say "Something went wrong: $r->{status} $r->{content}"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
say "Something went wrong: $r->code $r->message"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,24 +223,23 @@ sub flickrTestLogin {
|
|||||||
uri_encode ($oauth_signature)
|
uri_encode ($oauth_signature)
|
||||||
);
|
);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
my $r = $http->get ($url);
|
my $r = $ua->get ($url)->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $response = eval {
|
my $response = eval {
|
||||||
my $j = JSON::XS->new->utf8->relaxed;
|
return $r->json;
|
||||||
return $j->decode ($r->{content});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (defined $response) {
|
if (defined $response) {
|
||||||
say Dumper $response; ## no critic (InputOutput::RequireCheckedSyscalls)
|
say Dumper $response; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
say "Flickr api returns incorrect json: $r->{content}"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
say "Flickr api returns incorrect json: $r->message"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
say "HTTP status code not 200: $r->{status}, $r>{contenr}"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
say "HTTP status code not 200: $r->code, $r->message"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,13 +280,12 @@ sub flickrSearchByText {
|
|||||||
uri_encode ($text)
|
uri_encode ($text)
|
||||||
);
|
);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
my $r = $http->get ($url);
|
my $r = $ua->get ($url)->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $response = eval {
|
my $response = eval {
|
||||||
my $j = JSON::XS->new->utf8->relaxed;
|
return $r->json;
|
||||||
return $j->decode ($r->{content});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (defined $response) {
|
if (defined $response) {
|
||||||
@@ -326,31 +323,31 @@ sub flickrSearchByText {
|
|||||||
uri_encode ($text)
|
uri_encode ($text)
|
||||||
);
|
);
|
||||||
|
|
||||||
$http = HTTP::Tiny->new (timeout => 5);
|
$ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
$r = $http->get ($url);
|
$r = $ua->get ($url)->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
|
||||||
|
if ($r->is_success) {
|
||||||
$response = eval {
|
$response = eval {
|
||||||
my $j = JSON::XS->new->utf8->relaxed;
|
return $r->json;
|
||||||
return $j->decode ($r->{content});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (defined $response) {
|
if (defined $response) {
|
||||||
return $response;
|
return $response;
|
||||||
} else {
|
} else {
|
||||||
cluck "Flickr api returns incorrect json: $r->{content}";
|
cluck "Flickr api returns incorrect json: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "Flickr api returns incorrect json: $r->{content}";
|
cluck "Flickr api returns incorrect json: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "Flickr api returns incorrect json: $r->{content}";
|
cluck "Flickr api returns incorrect json: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "HTTP status code not 200: $r->{status}, $r->{content}";
|
cluck "HTTP status code not 200: $r->code, $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,13 +388,12 @@ sub flickrSearchByTags {
|
|||||||
uri_encode ($tags)
|
uri_encode ($tags)
|
||||||
);
|
);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
my $r = $http->get ($url);
|
my $r = $ua->get ($url)->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $response = eval {
|
my $response = eval {
|
||||||
my $j = JSON::XS->new->utf8->relaxed;
|
return $r->json;
|
||||||
return $j->decode ($r->{content});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (defined $response) {
|
if (defined $response) {
|
||||||
@@ -435,31 +431,30 @@ sub flickrSearchByTags {
|
|||||||
uri_encode ($tags)
|
uri_encode ($tags)
|
||||||
);
|
);
|
||||||
|
|
||||||
$http = HTTP::Tiny->new (timeout => 5);
|
$ua = Mojo::UserAgent->new->connect_timeout (5);
|
||||||
$r = $http->get ($url);
|
$r = $ua->get ($url)->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
$response = eval {
|
$response = eval {
|
||||||
my $j = JSON::XS->new->utf8->relaxed;
|
return $r->json;
|
||||||
return $j->decode ($r->{content});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (defined $response) {
|
if (defined $response) {
|
||||||
return $response;
|
return $response;
|
||||||
} else {
|
} else {
|
||||||
cluck "Flickr api returns incorrect json: $r->{content}";
|
cluck "Flickr api returns incorrect json: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "Flickr api returns incorrect json: $r->{content}";
|
cluck "Flickr api returns incorrect json: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "Flickr api returns incorrect json: $r->{content}";
|
cluck "Flickr api returns incorrect json: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "HTTP status code not 200: $r->{status}, $r>{contenr}";
|
cluck "HTTP status code not 200: $r->code, $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -484,8 +479,8 @@ sub flickr_init {
|
|||||||
my $flickr_request_token_secret = $secret{flickr_request_token_secret};
|
my $flickr_request_token_secret = $secret{flickr_request_token_secret};
|
||||||
|
|
||||||
unless (defined $flickr_request_token || defined $flickr_request_token_secret) {
|
unless (defined $flickr_request_token || defined $flickr_request_token_secret) {
|
||||||
say "Looks like there is no request token or request token secret in $backingfile";
|
say "Looks like there is no request token or request token secret in $backingfile"; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
say "Please remove verifier settings from config.json and run this script again";
|
say 'Please remove verifier settings from config.json and run this script again'; ## no critic (InputOutput::RequireCheckedSyscalls)
|
||||||
untie %secret;
|
untie %secret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
51
lib/image.pm
51
lib/image.pm
@@ -8,9 +8,8 @@ use open qw (:std :utf8);
|
|||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Carp qw (cluck);
|
use Carp qw (cluck);
|
||||||
use File::Path qw (make_path);
|
use File::Path qw (make_path);
|
||||||
use JSON::XS;
|
|
||||||
use HTTP::Tiny;
|
|
||||||
use Math::Random::Secure qw (irand);
|
use Math::Random::Secure qw (irand);
|
||||||
|
use Mojo::UserAgent;
|
||||||
use SQLite_File;
|
use SQLite_File;
|
||||||
use conf qw (loadConf);
|
use conf qw (loadConf);
|
||||||
use flickr qw (flickr_by_tags);
|
use flickr qw (flickr_by_tags);
|
||||||
@@ -29,19 +28,19 @@ sub kitty {
|
|||||||
my $ret = 'Нету кошечек, все разбежались.';
|
my $ret = 'Нету кошечек, все разбежались.';
|
||||||
|
|
||||||
for (1..3) {
|
for (1..3) {
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$r = $http->get ('https://api.thecatapi.com/v1/images/search');
|
$r = $ua->get ('https://api.thecatapi.com/v1/images/search')->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $jcat = eval {
|
my $jcat = eval {
|
||||||
decode_json ($r->{content})
|
return $r->json;
|
||||||
};
|
};
|
||||||
|
|
||||||
unless (defined $jcat) {
|
unless (defined $jcat) {
|
||||||
@@ -53,7 +52,7 @@ sub kitty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
@@ -64,19 +63,19 @@ sub fox {
|
|||||||
my $ret = 'Нету лисичек, все разбежались.';
|
my $ret = 'Нету лисичек, все разбежались.';
|
||||||
|
|
||||||
for (1..3) {
|
for (1..3) {
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$r = $http->get ('https://randomfox.ca/floof/');
|
$r = $ua->get ('https://randomfox.ca/floof/')->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $jfox = eval {
|
my $jfox = eval {
|
||||||
decode_json ($r->{content})
|
return $r->json;
|
||||||
};
|
};
|
||||||
|
|
||||||
unless (defined $jfox) {
|
unless (defined $jfox) {
|
||||||
@@ -88,7 +87,7 @@ sub fox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
@@ -99,19 +98,19 @@ sub oboobs {
|
|||||||
my $ret = 'Нету cисичек, все разбежались.';
|
my $ret = 'Нету cисичек, все разбежались.';
|
||||||
|
|
||||||
for (1..3) {
|
for (1..3) {
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$r = $http->get ('http://api.oboobs.ru/boobs/0/1/random');
|
$r = $ua->get ('http://api.oboobs.ru/boobs/0/1/random')->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $joboobs = eval {
|
my $joboobs = eval {
|
||||||
decode_json ($r->{content})
|
return $r->json;
|
||||||
};
|
};
|
||||||
|
|
||||||
unless (defined $joboobs) {
|
unless (defined $joboobs) {
|
||||||
@@ -123,7 +122,7 @@ sub oboobs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
@@ -134,19 +133,19 @@ sub obutts {
|
|||||||
my $ret = 'Нету попок, все разбежались.';
|
my $ret = 'Нету попок, все разбежались.';
|
||||||
|
|
||||||
for (1..3) {
|
for (1..3) {
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$r = $http->get ('http://api.obutts.ru/butts/0/1/random');
|
$r = $ua->get ('http://api.obutts.ru/butts/0/1/random')->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $jobutts = eval {
|
my $jobutts = eval {
|
||||||
decode_json ($r->{content})
|
return $r->json;
|
||||||
};
|
};
|
||||||
|
|
||||||
unless (defined $jobutts) {
|
unless (defined $jobutts) {
|
||||||
@@ -158,7 +157,7 @@ sub obutts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|||||||
44
lib/imgur.pm
44
lib/imgur.pm
@@ -8,9 +8,8 @@ use open qw (:std :utf8);
|
|||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Carp qw (cluck);
|
use Carp qw (cluck);
|
||||||
use File::Path qw (make_path);
|
use File::Path qw (make_path);
|
||||||
use JSON::XS;
|
|
||||||
use HTTP::Tiny;
|
|
||||||
use Math::Random::Secure qw (irand);
|
use Math::Random::Secure qw (irand);
|
||||||
|
use Mojo::UserAgent;
|
||||||
use SQLite_File;
|
use SQLite_File;
|
||||||
use conf qw (loadConf);
|
use conf qw (loadConf);
|
||||||
|
|
||||||
@@ -30,7 +29,6 @@ sub imgur {
|
|||||||
|
|
||||||
my $refresh_url = 'https://api.imgur.com/oauth2/token';
|
my $refresh_url = 'https://api.imgur.com/oauth2/token';
|
||||||
my $search_url = 'https://api.imgur.com/3/gallery/search/';
|
my $search_url = 'https://api.imgur.com/3/gallery/search/';
|
||||||
my $http = HTTP::Tiny->new (timeout => 5);
|
|
||||||
|
|
||||||
# load all tokens from api secrets db
|
# load all tokens from api secrets db
|
||||||
my $backingfile = sprintf '%s/secrets.sqlite', $dir;
|
my $backingfile = sprintf '%s/secrets.sqlite', $dir;
|
||||||
@@ -62,20 +60,13 @@ sub imgur {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# query api
|
# query api
|
||||||
my $r = $http->get (
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$search_url . $tag,
|
my $r = $ua->get ($search_url . $tag => {Authorization => "Bearer $imgur_access_token"})->result;
|
||||||
{
|
|
||||||
headers => {
|
|
||||||
Authorization => "Bearer $imgur_access_token"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
# looks like we need to refresh token
|
# looks like we need to refresh token
|
||||||
if (($r->{status} == 401) || ($r->{status} == 403)) {
|
if (($r->code == 401) || ($r->code == 403)) {
|
||||||
$r = $http->post_form (
|
$ua->post (
|
||||||
$refresh_url,
|
$refresh_url => form {
|
||||||
{
|
|
||||||
refresh_token => $imgur_refresh_token,
|
refresh_token => $imgur_refresh_token,
|
||||||
client_id => $imgur_client_id,
|
client_id => $imgur_client_id,
|
||||||
clinent_secret => $imgur_client_secret,
|
clinent_secret => $imgur_client_secret,
|
||||||
@@ -83,13 +74,13 @@ sub imgur {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
unless ($r->{success}) {
|
unless ($r->is_success) {
|
||||||
cluck "Unable to refresh imgur token, please re-authorise app! or imgur experiencing api outage: $r->{status} $r->{content}";
|
cluck "Unable to refresh imgur token, please re-authorise app! or imgur experiencing api outage: $r->code $r->message";
|
||||||
untie %secret;
|
untie %secret;
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $refresh = eval { decode_json $r->{content} };
|
my $refresh = eval { return $r->json; };
|
||||||
|
|
||||||
if (defined $refresh) {
|
if (defined $refresh) {
|
||||||
$imgur_refresh_token = $refresh->{refresh_token};
|
$imgur_refresh_token = $refresh->{refresh_token};
|
||||||
@@ -103,20 +94,13 @@ sub imgur {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# query api again
|
# query api again
|
||||||
$r = $http->get (
|
$r = $ua->get ($search_url . $tag => {Authorization => "Bearer $imgur_access_token"})->result;
|
||||||
$search_url . $tag,
|
|
||||||
{
|
|
||||||
headers => {
|
|
||||||
Authorization => "Bearer $imgur_access_token"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
untie %secret;
|
untie %secret;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $searchResult = eval { decode_json ($r->{content}) };
|
my $searchResult = eval { return $r->json; };
|
||||||
my @urls;
|
my @urls;
|
||||||
|
|
||||||
if (defined $searchResult) {
|
if (defined $searchResult) {
|
||||||
@@ -148,7 +132,7 @@ sub imgur {
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "Unable to get results from imgur api: $r->{content}";
|
cluck "Unable to get results from imgur api: $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -156,7 +140,7 @@ sub imgur {
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cluck "Unable to get results from imgur api: $r->{status}, $r->{content}";
|
cluck "Unable to get results from imgur api: $r->code, $r->message";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use utf8;
|
|||||||
use open qw (:std :utf8);
|
use open qw (:std :utf8);
|
||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Carp qw (cluck);
|
use Carp qw (cluck);
|
||||||
use HTTP::Tiny;
|
|
||||||
use HTML::TokeParser;
|
use HTML::TokeParser;
|
||||||
use Math::Random::Secure qw (irand);
|
use Math::Random::Secure qw (irand);
|
||||||
|
use Mojo::UserAgent;
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
@@ -21,18 +21,18 @@ sub monkeyuser {
|
|||||||
my @link;
|
my @link;
|
||||||
|
|
||||||
for (1..3) {
|
for (1..3) {
|
||||||
my $http = HTTP::Tiny->new (timeout => 3);
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
$r = $http->get ('https://www.monkeyuser.com/toc/');
|
$r = $ua->get ('https://www.monkeyuser.com/toc/')->result;
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep 2;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($r->{success}) {
|
if ($r->is_success) {
|
||||||
my $p = HTML::TokeParser->new(\$r->{content});
|
my $p = HTML::TokeParser->new(\$r->body);
|
||||||
my @a;
|
my @a;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|||||||
102
lib/weather.pm
102
lib/weather.pm
@@ -7,11 +7,13 @@ use utf8;
|
|||||||
use open qw (:std :utf8);
|
use open qw (:std :utf8);
|
||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Carp qw (carp cluck);
|
use Carp qw (carp cluck);
|
||||||
|
use CHI;
|
||||||
|
use CHI::Driver::BerkeleyDB;
|
||||||
use DB_File;
|
use DB_File;
|
||||||
use Digest::MD5 qw (md5_base64);
|
use Digest::MD5 qw (md5_base64);
|
||||||
use File::Path qw (make_path);
|
use File::Path qw (make_path);
|
||||||
use HTTP::Tiny;
|
use Mojo::Log;
|
||||||
use JSON::XS;
|
use Mojo::UserAgent::Cached;
|
||||||
use conf qw (loadConf);
|
use conf qw (loadConf);
|
||||||
use util qw (trim urlencode);
|
use util qw (trim urlencode);
|
||||||
|
|
||||||
@@ -71,77 +73,53 @@ sub weather {
|
|||||||
sub __weather {
|
sub __weather {
|
||||||
my $city = shift;
|
my $city = shift;
|
||||||
$city = urlencode $city;
|
$city = urlencode $city;
|
||||||
my $id = md5_base64 $city;
|
|
||||||
my $appid = $c->{openweathermap}->{appid};
|
my $appid = $c->{openweathermap}->{appid};
|
||||||
my $cachedir = $c->{openweathermap}->{cachedir};
|
my $cachedir = $c->{openweathermap}->{cachedir};
|
||||||
my $cachetimefile = $cachedir . '/openweathermap.Id-Timestamp.db';
|
|
||||||
my $cachedatafile = $cachedir . '/openweathermap.Id-Data.db';
|
|
||||||
my $now = time ();
|
my $now = time ();
|
||||||
my $fc;
|
my $fc;
|
||||||
my $w;
|
my $w;
|
||||||
|
|
||||||
unless (-d $cachedir) {
|
my $r;
|
||||||
make_path ($cachedir) || do {
|
|
||||||
cluck "[ERROR] Unable to create $cachedir: $OS_ERROR";
|
# try 3 times and giveup
|
||||||
return;
|
for (1..3) {
|
||||||
|
my $ua = Mojo::UserAgent::Cached->new;
|
||||||
|
$ua->local_dir ($cachedir);
|
||||||
|
$ua->cache_agent(
|
||||||
|
CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__,
|
||||||
|
expires_in => '3 hours',
|
||||||
|
expires_on_backend => 1,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
# just to make Mojo::UserAgent::Cached happy
|
||||||
|
$ua->logger (Mojo::Log->new (path => '/dev/null', level => 'error'));
|
||||||
|
$r = $ua->get (sprintf ('http://api.openweathermap.org/data/2.5/weather?q=%s&lang=ru&APPID=%s', $city, $appid))->result;
|
||||||
|
|
||||||
|
if ($r->is_success) {
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
# all 3 times can give error, so check it here
|
||||||
|
if ($r->is_success) {
|
||||||
|
$fc = eval {
|
||||||
|
return $r->json;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
# attach to cache data
|
unless ($fc) {
|
||||||
tie my %cachetime, 'DB_File', $cachetimefile or do {
|
cluck "[WARN] openweathermap returns corrupted json: $EVAL_ERROR";
|
||||||
carp "[ERROR] Something nasty happen when cachetime ties to its data: $OS_ERROR";
|
|
||||||
return undef;
|
|
||||||
};
|
|
||||||
|
|
||||||
tie my %cachedata, 'DB_File', $cachedatafile or do {
|
|
||||||
carp "[ERROR] Something nasty happen when cachedata ties to its data: $OS_ERROR";
|
|
||||||
return undef;
|
|
||||||
};
|
|
||||||
|
|
||||||
# lookup cache
|
|
||||||
if (defined ($cachetime{$id}) && ($now - $cachetime{$id}) < 10800) {
|
|
||||||
$fc = decode_json $cachedata{$id};
|
|
||||||
} else {
|
|
||||||
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/data/2.5/weather?q=%s&lang=ru&APPID=%s', $city, $appid));
|
|
||||||
|
|
||||||
if ($r->{success}) {
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
# all 3 times can give error, so check it here
|
|
||||||
if ($r->{success}) {
|
|
||||||
$fc = eval {
|
|
||||||
decode_json $r->{content};
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($EVAL_ERROR) {
|
|
||||||
cluck "[WARN] openweathermap returns corrupted json: $EVAL_ERROR";
|
|
||||||
untie %cachetime;
|
|
||||||
untie %cachedata;
|
|
||||||
return undef;
|
|
||||||
};
|
|
||||||
|
|
||||||
$cachetime{$id} = $now;
|
|
||||||
$cachedata{$id} = encode_json $fc;
|
|
||||||
} else {
|
|
||||||
cluck sprintf 'Server return status %s with message: %s', $r->{status}, $r->{reason};
|
|
||||||
untie %cachetime;
|
|
||||||
untie %cachedata;
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
};
|
||||||
|
} else {
|
||||||
|
cluck sprintf 'Server return status %s with message: %s', $r->code, $r->message;
|
||||||
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
untie %cachetime;
|
|
||||||
untie %cachedata;
|
|
||||||
|
|
||||||
# TODO: check all of this for existence
|
# TODO: check all of this for existence
|
||||||
$w->{'name'} = $fc->{name};
|
$w->{'name'} = $fc->{name};
|
||||||
$w->{'state'} = $fc->{state};
|
$w->{'state'} = $fc->{state};
|
||||||
|
|||||||
15
lib/xkcd.pm
15
lib/xkcd.pm
@@ -5,18 +5,23 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use utf8;
|
use utf8;
|
||||||
use open qw (:std :utf8);
|
use open qw (:std :utf8);
|
||||||
use HTTP::Tiny;
|
use Mojo::UserAgent;
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
our @EXPORT_OK = qw (xkcd);
|
our @EXPORT_OK = qw (xkcd);
|
||||||
|
|
||||||
sub xkcd {
|
sub xkcd {
|
||||||
my $http = HTTP::Tiny->new (timeout => 5, max_redirect => 0);
|
my $ua = Mojo::UserAgent->new->connect_timeout (5)->max_redirects (0);
|
||||||
my $r = $http->get ('https://xkcd.ru/random/');
|
my $r = $ua->get ('https://xkcd.ru/random/')->result;
|
||||||
|
|
||||||
if (defined $r->{headers} && defined $r->{headers}->{location} && $r->{headers}->{location} ne '') {
|
if (
|
||||||
return sprintf '[xkcd.ru](https://xkcd.ru/i/%s_v1.png)', substr ($r->{headers}->{location}, 1, -1);
|
defined $r->content &&
|
||||||
|
defined $r->content->headers &&
|
||||||
|
defined $r->content->headers->location &&
|
||||||
|
$r->content->headers->location ne ''
|
||||||
|
) {
|
||||||
|
return sprintf '[xkcd.ru](https://xkcd.ru/i/%s_v1.png)', substr ($r->content->headers->location, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Комикс-стрип нарисовать не так-то просто :(';
|
return 'Комикс-стрип нарисовать не так-то просто :(';
|
||||||
|
|||||||
Reference in New Issue
Block a user