Net-API-Nominatim
view release on metacpan or search on metacpan
lib/Net/API/Nominatim.pm view on Meta::CPAN
use HTTP::CookieJar::LWP;
use HTTP::Cookies;
use HTTP::Request;
use IO::Socket::UNIX qw/SOCK_STREAM SOMAXCONN/;
use Hash::Merge;
use Cookies::Roundtrip qw/lwpuseragent_load_cookies/;
use Storable qw/dclone/;
use Data::Roundtrip qw/perl2dump json2perl no-unicode-escape-permanently/;
use Net::API::Nominatim::Model::Address;
my $__DEFAULT_USERAGENT_STRING = 'Net::API::Nominatim Perl Client v'.$VERSION.' by bliako@cpan.org (thank you OSM)';
sub new {
my $class = $_[0];
my $params = $_[1] // {};
my $parent = ( caller(1) )[3] || "N/A";
my $whoami = ( caller(0) )[3];
# we are deleting items from user-specified params HASH_REF
# we must clone it BUT there is a problem with objects (e.g. the logger)
# we do not want to clone them but Clone::clone creates new objects
# and Storable::dclone complains, so fo.
#my $params = Storable::dclone($_params);
my $self = {
'_private' => {
'log' => {
'logger-object' => undef,
},
'lwpuseragent' => {
'lwpuseragent-object' => undef,
'cookies-object' => undef,
},
},
'options' => {
'server' => {
# we need one of 'url' or 'unix-socket'
# on init a 'method' will be created holding 'url' or 'unix-socket'
# do not set any
#'url' => 'https://nominatim.openstreetmap.org',
# fullpath to local unix socket:
#'unix-socket' => 'unix-socket-path', # let the user set it
},
'lwpuseragent' => {
'cookies-filename' => undef,
# Nominatim's terms of usage requires a unique UA string to identify the client:
# we also force this if the user specifies a ready-made UA object
# sorry, I hate to interfere on user-specified objects
'useragent-string' => $__DEFAULT_USERAGENT_STRING,
},
'debug' => {
'verbosity' => 1,
'cleanup' => 0,
},
'log' => {
'logger-file' => undef,
},
}
};
bless $self => $class;
if( exists($params->{'verbosity'}) && defined($params->{'verbosity'}) ){
$self->{'options'}->{'verbosity'} = $params->{'verbosity'}
}
my $verbosity = $self->verbosity();
# WARNING: we are deleting items from user-supplie $params here, so we clone it
# do we have a logger specified in params?
if( exists($params->{'log'}->{'logger-file'}) && defined($params->{'log'}->{'logger-file'}) ){
my $adir = File::Basename::dirname($params->{'log'}->{'logger-file'});
if( ! -d $adir ){ make_path($adir); if( ! -d $adir ){ print STDERR "${whoami} (via $parent), line ".__LINE__." : error, logfile directory '$adir' is not a dir or failed to be created.\n"; return undef } }
$self->{'_private'}->{'log'}->{'logger-object'} = Mojo::Log->new(path => $params->{'log'}->{'logger-file'});
delete $params->{'log'}->{'logger-file'};
} elsif( exists($params->{'log'}->{'logger-object'}) && defined($params->{'log'}->{'logger-object'}) ){
$self->{'_private'}->{'log'}->{'logger-object'} = $params->{'log'}->{'logger-object'};
delete $params->{'log'}->{'logger-object'};
} elsif( exists($self->{'options'}->{'log'}) && exists($self->{'options'}->{'logger-file'}) && defined($self->{'options'}->{'logger-file'}) ){
my $adir = File::Basename::dirname($self->{'options'}->{'logger-file'});
if( ! -d $adir ){ make_path($adir); if( ! -d $adir ){ print STDERR "${whoami} (via $parent), line ".__LINE__." : error, logfile directory '$adir' is not a dir or failed to be created.\n"; return undef } }
$self->{'_private'}->{'log'}->{'logger-object'} = Mojo::Log->new(path => $self->{'options'}->{'logger-file'});
delete $self->{'options'}->{'log'};
} else { $self->{'_private'}->{'log'}->{'logger-object'} = Mojo::Log->new() }
# Now we have a logger
my $log = $self->log();
# any objects in params must be migrated now!
if( exists($params->{'lwpuseragent'}->{'cookies-object'}) && defined($params->{'lwpuseragent'}->{'cookies-object'}) ){
# NOTE: the cookiejar we pass will be cloned and will not have the same pointer
$self->{'_private'}->{'lwpuseragent'}->{'cookies-object'} = $params->{'lwpuseragent'}->{'cookies-object'};
}
if( exists($params->{'lwpuseragent'}->{'lwpuseragent-object'}) && defined($params->{'lwpuseragent'}->{'lwpuseragent-object'}) ){
$self->{'_private'}->{'lwpuseragent'}->{'lwpuseragent-object'} = $params->{'lwpuseragent'}->{'lwpuseragent-object'};
}
# and add more user-specified params into our self
# right is our params, left the options
my $hm = Hash::Merge->new('RIGHT_PRECEDENT');
$hm->add_behavior_spec({
'SCALAR' => {
# left is scalar (above), right is one of these, what to do?:
# we are only interested in SCALAR/SCALAR, ie left+right
# can not be different types
'SCALAR' => sub { defined($_[1]) ? $_[1] : $_[0] },
'ARRAY' => sub { if( defined($_[1]) ){ perl2dump($_[0])." and right: ".perl2dump($_[1])."unexpected type SCALAR/ARRAY" } else { $_[0] = $_[1] } },
'HASH' => sub { if( defined($_[1]) ){ perl2dump($_[0])." and right: ".perl2dump($_[1])."unexpected type SCALAR/HASH" } else { $_[0] = $_[1] } },
},
'ARRAY' => {
# left is array (above), right is one of these, what to do?:
'SCALAR' => sub { if( defined($_[1]) ){ perl2dump($_[0])." and right: ".perl2dump($_[1])."unexpected type ARRAY/SCALAR" } else { $_[0] = $_[1] } },
'ARRAY' => sub { [ defined($_[1]) ? @{ $_[1] } : @{ $_[0] } ] },
'HASH' => sub { if( defined($_[1]) ){ perl2dump($_[0])." and right: ".perl2dump($_[1])."unexpected type ARRAY/HASH" } else { $_[0] = $_[1] } },
},
'HASH' => {
# left is hash (above), right is one of these, what to do?:
'SCALAR' => sub { if( defined($_[1]) ){ perl2dump($_[0])." and right: ".perl2dump($_[1])."unexpected type HASH/SCALAR" } else { $_[0] = $_[1] } },
'ARRAY' => sub { if( defined($_[1]) ){ perl2dump($_[0])." and right: ".perl2dump($_[1])."unexpected type HASH/ARRAY" } else { $_[0] = $_[1] } },
'HASH' => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
},
( run in 0.445 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )