$MetaCPAN::Client::Request::VERSION
=
'2.004000'
;
has
_clientinfo
=> (
is
=>
'ro'
,
isa
=> HashRef,
lazy
=> 1,
builder
=>
'_build_clientinfo'
,
);
has
domain
=> (
is
=>
'ro'
,
default
=>
sub
{
$ENV
{METACPAN_DOMAIN} and
return
$ENV
{METACPAN_DOMAIN};
$_
[0]->_clientinfo->{production}{domain};
},
);
has
base_url
=> (
is
=>
'ro'
,
lazy
=> 1,
default
=>
sub
{
$ENV
{METACPAN_DOMAIN} and
return
$ENV
{METACPAN_DOMAIN};
$_
[0]->_clientinfo->{production}{url};
},
);
has
_user_ua
=> (
init_arg
=>
'ua'
,
is
=>
'ro'
,
predicate
=>
'_has_user_ua'
,
);
has
ua
=> (
init_arg
=>
undef
,
is
=>
'ro'
,
lazy
=> 1,
builder
=>
'_build_ua'
,
);
has
ua_args
=> (
is
=>
'ro'
,
default
=>
sub
{
[
agent
=>
'MetaCPAN::Client/'
.(
$MetaCPAN::Client::VERSION
||
'xx'
) ]
},
);
has
_is_agg
=> (
is
=>
'ro'
,
default
=> 0,
writer
=>
'_set_is_agg'
);
sub
BUILDARGS {
my
(
$self
,
%args
) =
@_
;
$args
{domain} and
$args
{base_url} =
$args
{domain};
return
\
%args
;
}
sub
_build_ua {
my
$self
=
shift
;
if
(
$self
->_has_user_ua ) {
my
$ua
=
$self
->_user_ua;
croak
"cannot use given ua (must support 'get' and 'post' methods)"
unless
$ua
->can(
"get"
) and
$ua
->can(
"post"
);
return
$self
->_user_ua;
}
return
HTTP::Tiny->new( @{
$self
->ua_args } );
}
sub
_build_clientinfo {
my
$self
=
shift
;
my
$info
;
eval
{
$info
= decode_json(
$info
->{content} );
is_hashref(
$info
) and
exists
$info
->{production} or
die
;
1;
}
or
$info
= +{
production
=> {
}
};
return
$info
;
}
sub
fetch {
my
$self
=
shift
;
my
$url
=
shift
or croak
'fetch must be called with a URL parameter'
;
my
$params
=
shift
|| {};
my
$req_url
=
sprintf
'%s/%s'
,
$self
->base_url,
$url
;
my
$ua
=
$self
->ua;
my
$result
=
keys
%{
$params
}
?
$ua
->post(
$req_url
, {
content
=> encode_json
$params
} )
:
$ua
->get(
$req_url
);
return
$self
->_decode_result(
$result
,
$req_url
);
}
sub
ssearch {
my
$self
=
shift
;
my
$type
=
shift
;
my
$args
=
shift
;
my
$params
=
shift
;
my
$scroller
= MetaCPAN::Client::Scroll->new(
ua
=>
$self
->ua,
size
=> 500,
base_url
=>
$self
->base_url,
type
=>
$type
,
body
=>
$self
->_build_body(
$args
,
$params
),
);
return
$scroller
;
}
sub
_decode_result {
my
$self
=
shift
;
my
$result
=
shift
;
my
$url
=
shift
or croak
'Second argument of a URL must be provided'
;
is_hashref(
$result
)
or croak
'First argument must be hashref'
;
my
$success
=
$result
->{
'success'
};
defined
$success
or croak
'Missing success in return value'
;
$success
or croak
"Failed to fetch '$url': "
.
$result
->{
'reason'
};
my
$content
=
$result
->{
'content'
}
or croak
'Missing content in return value'
;
$url
=~ m|/pod/| and
return
$content
;
$url
=~ m|/source/| and
return
$content
;
my
$decoded_result
;
eval
{
$decoded_result
= decode_json
$content
;
1;
} or
do
{
croak
"Couldn't decode '$content': $@"
;
};
return
$decoded_result
;
}
sub
_build_body {
my
$self
=
shift
;
my
$args
=
shift
;
my
$params
=
shift
;
my
$query
=
$args
->{__MATCH_ALL__}
? {
match_all
=> {} }
: _build_query_rec(
$args
);
return
+{
query
=>
$query
,
_read_filters(
$params
),
$self
->_read_aggregations(
$params
)
};
}
my
%key2es
= (
all
=>
'must'
,
either
=>
'should'
,
not
=>
'must_not'
,
);
sub
_read_aggregations {
my
$self
=
shift
;
my
$params
=
shift
;
my
$aggregations
=
delete
$params
->{aggregations};
ref
(
$aggregations
) or
return
();
$self
->_set_is_agg(1);
return
(
aggregations
=>
$aggregations
);
}
sub
_read_filters {
my
$params
=
shift
;
my
$filter
=
delete
$params
->{es_filter};
ref
(
$filter
) or
return
();
return
(
filter
=>
$filter
);
}
sub
_build_query_rec {
my
$args
=
shift
;
is_hashref(
$args
) or croak
'query args must be a hash'
;
my
%query
= ();
my
$basic_element
= 1;
KEY:
for
my
$k
(
qw/ all either not /
) {
my
$v
=
delete
$args
->{
$k
} ||
next
KEY;
is_hashref(
$v
) and
$v
= [
$v
];
is_arrayref(
$v
) or croak
"invalid value for key $k"
;
undef
$basic_element
;
$query
{
'bool'
}{
$key2es
{
$k
} } =
[
map
+( _build_query_rec(
$_
) ),
@$v
];
$k
eq
'either'
and
$query
{
'bool'
}{
'minimum_should_match'
} = 1;
}
$basic_element
and
%query
= %{ _build_query_element(
$args
) };
return
\
%query
;
}
sub
_build_query_element {
my
$args
=
shift
;
scalar
keys
%{
$args
} == 1
or croak
'Wrong number of keys in query element'
;
my
(
$key
) =
keys
%{
$args
};
my
$val
=
$args
->{
$key
};
!
ref
(
$val
) and
$val
=~ /[\w\*]/
or croak
'Wrong type of query arguments'
;
my
$wildcard
=
$val
=~ /[*?]/;
my
$qtype
=
$wildcard
?
'wildcard'
:
'term'
;
return
+{
$qtype
=>
$args
};
}
1;