From f96e74725d8bc35c60290086db02c95e7fdde958 Mon Sep 17 00:00:00 2001 From: eleksir Date: Sat, 19 Feb 2022 15:37:13 +0300 Subject: [PATCH] More critic! --- .perlcriticrc | 34 ++++++++++++++++++++++ bin/aleesa-webapp | 35 +++++++++++----------- bin/flickr_init.pl | 2 +- cpanfile | 6 +++- lib/Conf.pm | 24 ++++++++++------ lib/WebApp.pm | 24 ++++++++-------- lib/WebApp/Client.pm | 44 ++++++++++++++-------------- lib/WebApp/Client/API/Flickr.pm | 51 ++++++++++++++++----------------- 8 files changed, 134 insertions(+), 86 deletions(-) diff --git a/.perlcriticrc b/.perlcriticrc index 1f9bb32..f090094 100644 --- a/.perlcriticrc +++ b/.perlcriticrc @@ -1,4 +1,15 @@ #!/usr/bin/env perlcritic +# Задействованные модули критика: +# +# Perl::Critic::More +# Perl::Critic::Pulp +# Perl::Critic::TooMuchCode +# Perl::Critic::Lax +# Perl::Critic::CognitiveComplexity +# Perl::Critic::Policy::CompileTime +# Perl::Critic::Policy::ProhibitImplicitImport +# Perl::Critic::Policy::Dynamic::NoIndirect + severity = 5 verbose = 8 @@ -94,3 +105,26 @@ lib_sections = NAME | VERSION | DESCRIPTION | AUTHOR | LICENSE AND COPYRIGHT # Have to use it, so fuckoff [-Variables::ProhibitPackageVars] + +[-Miscellanea::ProhibitUnrestrictedNoCritic] + +[-Editor::RequireEmacsFileVariables] + +[-CodeLayout::RequireASCII] + +[-TooMuchCode::ProhibitDuplicateLiteral] + +[-ValuesAndExpressions::RequireConstantOnLeftSideOfEquality] + +[-Lax::RequireConstantOnLeftSideOfEquality::ExceptEq] + +[-TooMuchCode::ProhibitUnnecessaryUTF8Pragma] + +[-ErrorHandling::RequireUseOfExceptions] + +[-Lax::ProhibitEmptyQuotes::ExceptAsFallback] + +[-ValuesAndExpressions::RestrictLongStrings] + +[-TooMuchCode::ProhibitLargeBlock] +# read my lips: fuck off diff --git a/bin/aleesa-webapp b/bin/aleesa-webapp index b24fe58..6058454 100755 --- a/bin/aleesa-webapp +++ b/bin/aleesa-webapp @@ -1,6 +1,6 @@ #!/usr/bin/perl -use 5.018; +use 5.018; ## no critic (ProhibitImplicitImport) use strict; use warnings; use utf8; @@ -29,9 +29,10 @@ no Cwd; use Cwd::utf8 qw (chdir abs_path); use File::Basename qw (basename dirname); use File::Path qw (make_path); +use File::Spec (); use Log::Any qw ($log); -use Log::Any::Adapter; -use Log::Any::For::Std; +use Log::Any::Adapter (); +use Log::Any::For::Std (); use POSIX qw (setgid setuid setsid); use Conf qw (LoadConf); @@ -69,8 +70,8 @@ if ($UID == 0) { make_path ( $piddir, { uid => $uid, - group => $gid - } + group => $gid, + }, ); } @@ -81,8 +82,8 @@ if ($UID == 0) { make_path ( $logdir, { uid => $uid, - group => $gid - } + group => $gid, + }, ) or die "Unable to create $logdir: $OS_ERROR\n"; } } @@ -102,14 +103,14 @@ if (defined $logfile) { # verbosity paticulary for CHI. Log::Any::Adapter->set ( { - category => 'CHI::Driver' + category => 'CHI::Driver', }, 'File', $logfile, - log_level => 'warn' + log_level => 'warn', ); } else { - Log::Any::Adapter->set ('File', '/dev/null'); + Log::Any::Adapter->set ('File', File::Spec->devnull); } # по-умолчанию, демонизируемся, если явно не указано, что этого делать не надо @@ -125,7 +126,7 @@ my $apath = abs_path $PROGRAM_NAME; unless (defined $apath) { $log->fatal ("[FATAL] Unable to get abs_path: $OS_ERROR\n"); exit 1; -}; +} my $pidfile = sprintf '%s/%s.pid', $piddir, basename $apath; $log->info ("[INFO] Creating pidfile at $pidfile"); @@ -151,7 +152,7 @@ $PROGRAM_NAME = abs_path $PROGRAM_NAME; ## no critic (Variables::Re # run bot, at last RunWebApp (); -if (-f $pidfile) { +if (-e $pidfile) { unlink $pidfile; } @@ -159,11 +160,11 @@ exit 0; sub daemonize { __fork (); - POSIX::setsid (); - open STDIN, '<', '/dev/null'; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) + setsid (); + open STDIN, '<', File::Spec->devnull; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) # we handle STDOUT && STDERR via Log::Any::For::Std, so do not close them explicitly - #open STDOUT, '>', '/dev/null'; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) - #open STDERR, '>', '/dev/null'; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) + #open STDOUT, '>', File::Spec->devnull; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) + #open STDERR, '>', File::Spec->devnull; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) __fork (); umask 0; return; @@ -187,7 +188,7 @@ sub __fork { sub __signal_handler { $log->info ("[INFO] Caught a signal $OS_ERROR"); - if (-f $pidfile) { + if (-e $pidfile) { unlink $pidfile; } diff --git a/bin/flickr_init.pl b/bin/flickr_init.pl index d54e409..de141d0 100644 --- a/bin/flickr_init.pl +++ b/bin/flickr_init.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -use 5.018; +use 5.018; ## no critic (ProhibitImplicitImport) use strict; use warnings; use utf8; diff --git a/cpanfile b/cpanfile index 155bc83..1ec8242 100644 --- a/cpanfile +++ b/cpanfile @@ -1,3 +1,4 @@ +## no critic requires 'Carp', '==1.50'; requires 'CHI', '==0.61'; requires 'CHI::Driver::BerkeleyDB', '==0.05'; @@ -8,8 +9,9 @@ requires 'Digest::HMAC_SHA1', '==1.04'; requires 'Encode', '==3.16'; requires 'English', '0'; requires 'EV', '==4.33'; -requires 'File::Basename', '0'; +requires 'File::Basename', '==2.85'; requires 'File::Path', '==2.18'; +requires 'File::Spec', '==3.75'; requires 'HTML::TokeParser', '==3.76'; requires 'IO::Socket::SSL', '==2.073'; requires 'JSON', '==4.04'; @@ -22,6 +24,8 @@ requires 'Math::Random::Secure', '==0.080001'; requires 'MIME::Base64', '==3.16'; requires 'Mojolicious', '==9.22'; requires 'Mojo::IOLoop::Signal', '==0.003'; +# Чтобы заткнуть Mojo::UserAgent::Cached +requires 'Mojo::Log', '0'; requires 'Mojo::Redis', '==3.27'; requires 'Mojo::UserAgent', '0'; requires 'Mojo::UserAgent::Cached', '==1.18'; diff --git a/lib/Conf.pm b/lib/Conf.pm index 1154f0e..9c34f06 100644 --- a/lib/Conf.pm +++ b/lib/Conf.pm @@ -1,14 +1,13 @@ -package Conf; -# Загружает конфиг +package BotLib::Conf; +# Загружает конфиг файл -use 5.018; +use 5.018; ## no critic (ProhibitImplicitImport) use strict; use warnings; use utf8; use open qw (:std :utf8); use English qw ( -no_match_vars ); -use Encode qw (encode); -use JSON::XS; +use JSON::XS (); use version; our $VERSION = qw (1.0); use Exporter qw (import); @@ -16,17 +15,26 @@ our @EXPORT_OK = qw (LoadConf); sub LoadConf { my $c = 'data/config.json'; - open my $CH, '<', $c or die "[FATAL] No conf at $c: $OS_ERROR\n"; - my $json; + my $CH; + + unless (open $CH, '<', $c) { + die "[FATAL] No conf at $c: $OS_ERROR\n"; + } + my $len = (stat $c) [7]; + my $json; my $readlen = read $CH, $json, $len; - $json = encode 'UTF-8', $json; unless ($readlen) { close $CH; ## no critic (InputOutput::RequireCheckedSyscalls die "[FATAL] Unable to read $c: $OS_ERROR\n"; } + if ($readlen != $len) { + close $CH; ## no critic (InputOutput::RequireCheckedSyscalls + die "[FATAL] File $c is $len bytes on disk, but we read only $readlen bytes\n"; + } + close $CH; ## no critic (InputOutput::RequireCheckedSyscalls my $j = JSON::XS->new->utf8->relaxed; return $j->decode ($json); diff --git a/lib/WebApp.pm b/lib/WebApp.pm index 395f2c0..53844e6 100644 --- a/lib/WebApp.pm +++ b/lib/WebApp.pm @@ -1,19 +1,19 @@ package WebApp; # Общие модули - синтаксис, кодировки итд -use 5.018; +use 5.018; ## no critic (ProhibitImplicitImport) use strict; use warnings; use utf8; use open qw (:std :utf8); # Модули для работы приложения -use Data::Dumper; +use Data::Dumper qw (Dumper); use Log::Any qw ($log); use Math::Random::Secure qw (irand); -use Mojo::Redis; -use Mojo::IOLoop; -use Mojo::IOLoop::Signal; +use Mojo::Redis (); +use Mojo::IOLoop (); +use Mojo::IOLoop::Signal (); # Плагины web-клиентов use Conf qw (LoadConf); @@ -183,7 +183,7 @@ my $parse_message = sub { $log->debug ("[DEBUG] Sending message to channel $send_to " . Dumper ($answer)); $self->json ($send_to)->notify ( - $send_to => $answer + $send_to => $answer, ); } @@ -194,7 +194,7 @@ my $__signal_handler = sub { my ($self, $name) = @_; $log->info ("[INFO] Caught a signal $name"); - if (defined $main::pidfile && -f $main::pidfile) { + if (defined $main::pidfile && -e $main::pidfile) { unlink $main::pidfile; } @@ -207,7 +207,7 @@ sub RunWebApp { $log->info ("[INFO] Connecting to $c->{server}, $c->{port}"); my $redis = Mojo::Redis->new ( - sprintf 'redis://%s:%s/1', $c->{server}, $c->{port} + sprintf 'redis://%s:%s/1', $c->{server}, $c->{port}, ); $log->info ('[INFO] Registering connection-event callback'); @@ -224,11 +224,11 @@ sub RunWebApp { my ($conn, $error) = @_; $log->error ("[ERROR] Redis connection error: $error"); return; - } + }, ); return; - } + }, ); my $pubsub = $redis->pubsub; @@ -239,13 +239,13 @@ sub RunWebApp { $log->debug ("[DEBUG] Subscribing to $channel"); $sub->{$channel} = $pubsub->json ($channel)->listen ( - $channel => sub { $parse_message->(@_); } + $channel => sub { $parse_message->(@_); }, ); } Mojo::IOLoop::Signal->on ( TERM => $__signal_handler, - INT => $__signal_handler + INT => $__signal_handler, ); do { Mojo::IOLoop->start } until Mojo::IOLoop->is_running; diff --git a/lib/WebApp/Client.pm b/lib/WebApp/Client.pm index 3c1cab8..cf48d5c 100644 --- a/lib/WebApp/Client.pm +++ b/lib/WebApp/Client.pm @@ -1,6 +1,6 @@ package WebApp::Client; -use 5.018; +use 5.018; ## no critic (ProhibitImplicitImport) use strict; use warnings; use utf8; @@ -8,19 +8,21 @@ use open qw (:std :utf8); use English qw ( -no_match_vars ); use Carp qw (carp cluck); -use CHI; -use CHI::Driver::BerkeleyDB; -use DateTime; -use Encode; -use HTML::TokeParser; -use JSON::XS; +use CHI (); +use CHI::Driver::BerkeleyDB (); +use DateTime (); +use Encode qw (decode); +use File::Spec (); +use HTML::TokeParser (); +use JSON::XS (); use Log::Any qw ($log); use Math::Random::Secure qw (irand); -use Mojo::UserAgent; -use Mojo::UserAgent::Cached; +use Mojo::Log (); # Чтобы заткнуть Mojo::UserAgent::Cached +use Mojo::UserAgent (); +use Mojo::UserAgent::Cached (); use Mojo::Util qw (trim); use POSIX qw (strftime); -use URI::URL; +use URI::URL qw (url); use Conf qw (LoadConf); use WebApp::Client::API::Flickr qw (FlickrByTags); @@ -210,7 +212,7 @@ sub Drink { day => $mday, hour => 0, minute => 0, - second => 0 + second => 0, )->add (days => 1)->strftime ('%s'); if ((substr $offset, 0, 1) eq '+') { @@ -228,10 +230,10 @@ sub Drink { 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')); + $ua->logger (Mojo::Log->new (path => File::Spec->devnull, level => 'error')); my $useragent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36'; if ($#useragents > 0) { @@ -513,7 +515,7 @@ sub Xkcd { my $ua = Mojo::UserAgent->new->connect_timeout (5)->max_redirects (0); my $location; my $status = 400; - my $c = 0; + my $counter = 0; do { my $r = $ua->get ('https://xkcd.ru/random/')->result; @@ -529,7 +531,7 @@ sub Xkcd { $r = $ua->head ($location)->result; } - $c++; + $counter++; $status = $r->code; } while ($c < 3 || $status >= 404); @@ -572,7 +574,7 @@ sub Weather { $w->{temperature_min}, $w->{temperature_feelslike}, $w->{humidity}, - $w->{pressure} + $w->{pressure}, ); } elsif ($w->{temperature_min} < 0 && $w->{temperature_max} <= 0) { $reply = sprintf ( @@ -586,7 +588,7 @@ sub Weather { $w->{temperature_min}, $w->{temperature_feelslike}, $w->{humidity}, - $w->{pressure} + $w->{pressure}, ); } else { $reply = sprintf ( @@ -600,7 +602,7 @@ sub Weather { $w->{temperature_max}, $w->{temperature_feelslike}, $w->{humidity}, - $w->{pressure} + $w->{pressure}, ); } } else { @@ -631,10 +633,10 @@ sub __weather { 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')); + $ua->logger (Mojo::Log->new (path => File::Spec->devnull, 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) { @@ -653,7 +655,7 @@ sub __weather { unless ($fc) { $log->warn ("[WARN] openweathermap returns corrupted json: $EVAL_ERROR"); return undef; - }; + } } else { $log->warn (sprintf '[WARN] Server return status %s with message: %s', $r->code, $r->message); return undef; diff --git a/lib/WebApp/Client/API/Flickr.pm b/lib/WebApp/Client/API/Flickr.pm index 6eadc65..7dd525a 100644 --- a/lib/WebApp/Client/API/Flickr.pm +++ b/lib/WebApp/Client/API/Flickr.pm @@ -1,24 +1,23 @@ package WebApp::Client::API::Flickr; -use 5.018; +use 5.018; ## no critic (ProhibitImplicitImport) use strict; use warnings; use utf8; use open qw (:std :utf8); use English qw ( -no_match_vars ); -use Carp qw (cluck); -use CHI; -use CHI::Driver::BerkeleyDB; -use Digest::HMAC_SHA1 qw (hmac_sha1); +use CHI (); +use CHI::Driver::BerkeleyDB (); +use Digest::HMAC_SHA1 (); use Log::Any qw ($log); use Math::Random::Secure qw (irand); -use MIME::Base64; -use Mojo::UserAgent; +use MIME::Base64 qw (encode_base64); +use Mojo::UserAgent (); use URI::Encode::XS qw (uri_encode); use Conf qw (LoadConf); -use Data::Dumper; +use Data::Dumper qw (Dumper); use version; our $VERSION = qw (1.0); use Exporter qw (import); @@ -107,7 +106,7 @@ sub flickrRequestToken { my $oauth_signature = flickerSignReq ( type => 'request_token', oauth_timestamp => $oauth_timestamp, - oauth_nonce => $oauth_nonce + oauth_nonce => $oauth_nonce, ); my $url = $flickr_request_token_url . sprintf ( @@ -116,7 +115,7 @@ sub flickrRequestToken { $oauth_timestamp, $flickr_consumer_key, uri_encode ($oauth_signature), - uri_encode ($flickr_callback_url) + uri_encode ($flickr_callback_url), ); my $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -147,7 +146,7 @@ sub flickrAccessToken { oauth_nonce => $oauth_nonce, oauth_token => $flickr_request_token, oauth_token_secret => $flickr_request_token_secret, - oauth_verifier => $flickr_verifier + oauth_verifier => $flickr_verifier, ); my $url = $flickr_access_token_url . sprintf ( @@ -157,7 +156,7 @@ sub flickrAccessToken { $flickr_verifier, $flickr_consumer_key, $flickr_request_token, - uri_encode ($oauth_signature) + uri_encode ($oauth_signature), ); my $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -211,7 +210,7 @@ sub flickrTestLogin { oauth_token => $flickr_access_token, oauth_token_secret => $flickr_access_token_secret, oauth_signature_method => 'HMAC-SHA1', - oauth_version => '1.0' + oauth_version => '1.0', ); my $url = $flickr_api_url . sprintf ( @@ -220,7 +219,7 @@ sub flickrTestLogin { $flickr_consumer_key, $oauth_timestamp, $flickr_access_token, - uri_encode ($oauth_signature) + uri_encode ($oauth_signature), ); my $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -267,7 +266,7 @@ sub flickrSearchByText { oauth_token => $flickr_access_token, oauth_token_secret => $flickr_access_token_secret, oauth_signature_method => 'HMAC-SHA1', - oauth_version => '1.0' + oauth_version => '1.0', ); my $url = $flickr_api_url . sprintf ( @@ -277,7 +276,7 @@ sub flickrSearchByText { $oauth_timestamp, $flickr_access_token, uri_encode ($oauth_signature), - uri_encode ($text) + uri_encode ($text), ); my $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -309,7 +308,7 @@ sub flickrSearchByText { oauth_token => $flickr_access_token, oauth_token_secret => $flickr_access_token_secret, oauth_signature_method => 'HMAC-SHA1', - oauth_version => '1.0' + oauth_version => '1.0', ); $url = $flickr_api_url . sprintf ( @@ -320,7 +319,7 @@ sub flickrSearchByText { $flickr_access_token, uri_encode ($oauth_signature), $page, - uri_encode ($text) + uri_encode ($text), ); $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -375,7 +374,7 @@ sub flickrSearchByTags { oauth_token => $flickr_access_token, oauth_token_secret => $flickr_access_token_secret, oauth_signature_method => 'HMAC-SHA1', - oauth_version => '1.0' + oauth_version => '1.0', ); my $url = $flickr_api_url . sprintf ( @@ -385,7 +384,7 @@ sub flickrSearchByTags { $oauth_timestamp, $flickr_access_token, uri_encode ($oauth_signature), - uri_encode ($tags) + uri_encode ($tags), ); my $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -417,7 +416,7 @@ sub flickrSearchByTags { oauth_token => $flickr_access_token, oauth_token_secret => $flickr_access_token_secret, oauth_signature_method => 'HMAC-SHA1', - oauth_version => '1.0' + oauth_version => '1.0', ); $url = $flickr_api_url . sprintf ( @@ -428,7 +427,7 @@ sub flickrSearchByTags { $flickr_access_token, uri_encode ($oauth_signature), $page, - uri_encode ($tags) + uri_encode ($tags), ); $ua = Mojo::UserAgent->new->connect_timeout (5); @@ -463,7 +462,7 @@ sub FlickrInit { my $cache = CHI->new ( driver => 'BerkeleyDB', root_dir => $cachedir, - namespace => __PACKAGE__ + namespace => __PACKAGE__, ); if (defined $flickr_verifier && $flickr_verifier) { @@ -516,7 +515,7 @@ sub FlickrTestLogin { my $cache = CHI->new ( driver => 'BerkeleyDB', root_dir => $cachedir, - namespace => __PACKAGE__ + namespace => __PACKAGE__, ); my $flickr_access_token = $cache->get ('flickr_access_token'); @@ -535,7 +534,7 @@ sub FlickrByTags { my $cache = CHI->new ( driver => 'BerkeleyDB', root_dir => $cachedir, - namespace => __PACKAGE__ + namespace => __PACKAGE__, ); my $flickr_access_token = $cache->get ('flickr_access_token'); @@ -568,7 +567,7 @@ sub FlickrByText { my $cache = CHI->new ( driver => 'BerkeleyDB', root_dir => $cachedir, - namespace => __PACKAGE__ + namespace => __PACKAGE__, ); my $flickr_access_token = $cache->get ('flickr_access_token');