Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added new /reversedependencies API endpoints
Added 2 new endpoints:

* /reverse_dependencies/dist/DISTRIBUTION
moved query from WEB

* /reverse_dependencies/module/MODULE
copied (& later will remove) current /release/requires endpoint

Added a new controller Controller/ReverseDependencies.pm to
later replace the current Controller/Search/ReverseDependencies.pm
(will be removed with all supporting code once WEB is set to
point to new endpoints)
  • Loading branch information
mickeyn committed Jun 15, 2017
1 parent 544c64b commit 094b9e1
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 44 deletions.
206 changes: 162 additions & 44 deletions lib/MetaCPAN/Document/Release.pm
Expand Up @@ -551,50 +551,6 @@ sub get_files {
return { files => [ map { $_->{_source} } @{ $ret->{hits}{hits} } ] };
}

sub requires {
my ( $self, $module, $page, $page_size, $sort ) = @_;
$page //= 1;
$page_size //= 20;
$sort //= { date => 'desc' };

my $query = {
query => {
filtered => {
query => { 'match_all' => {} },
filter => {
and => [
{ term => { 'status' => 'latest' } },
{ term => { 'authorized' => 1 } },
{
term => {
'dependency.module' => $module
}
}
]
}
}
}
};

my $ret = $self->es->search(
index => $self->index->name,
type => 'release',
body => {
query => $query,
from => $page * $page_size - $page_size,
size => $page_size,
sort => [$sort],
}
);
return {} unless $ret->{hits}{total};

return +{
data => [ map { $_->{_source} } @{ $ret->{hits}{hits} } ],
total => $ret->{hits}{total},
took => $ret->{took}
};
}

sub _activity_filters {
my ( $self, $params, $start ) = @_;
my ( $author, $distribution, $module, $new_dists )
Expand Down Expand Up @@ -795,5 +751,167 @@ sub top_uploaders {
};
}

sub requires {
my ( $self, $module, $page, $page_size, $sort ) = @_;
$page //= 1;
$page_size //= 20;
$sort //= { date => 'desc' };

my $query = {
query => {
filtered => {
query => { 'match_all' => {} },
filter => {
and => [
{ term => { 'status' => 'latest' } },
{ term => { 'authorized' => 1 } },
{
term => {
'dependency.module' => $module
}
}
]
}
}
}
};

my $ret = $self->es->search(
index => $self->index->name,
type => 'release',
body => {
query => $query,
from => $page * $page_size - $page_size,
size => $page_size,
sort => [$sort],
}
);
return {} unless $ret->{hits}{total};

return +{
data => [ map { $_->{_source} } @{ $ret->{hits}{hits} } ],
total => $ret->{hits}{total},
took => $ret->{took}
};
}

sub reverse_dependencies {
my ( $self, $distribution, $page, $page_size, $sort ) = @_;

# get the latest release of given distribution
my $release = $self->_get_latest_release($distribution) || return;

# get (authorized/indexed) modules provided by the release
my $modules = $self->_get_provided_modules($release) || return;

# get releases depended on those modules
my $depended
= $self->_get_depended_releases( $modules, $page, $page_size, $sort )
|| return;

my $data = [ map [ @{$_}{qw( name author date )} ], @{$depended} ];
single_valued_arrayref_to_scalar($data);
return +{ data => $data };
}

sub _get_latest_release {
my ( $self, $distribution ) = @_;

my $release = $self->es->search(
index => $self->index->name,
type => 'release',
body => {
query => {
bool => {
must => [
{ term => { distribution => $distribution } },
{ term => { status => 'latest' } },
{ term => { authorized => 1 } },
]
},
},
fields => [qw< name author >],
},
);
return unless $release->{hits}{total};

my ($release_info) = map { $_->{fields} } @{ $release->{hits}{hits} };
single_valued_arrayref_to_scalar($release_info);

return +{
name => $release_info->{name},
author => $release_info->{author},
};
}

sub _get_provided_modules {
my ( $self, $release ) = @_;

my $provided_modules = $self->es->search(
index => $self->index->name,
type => 'file',
body => {
query => {
bool => {
must => [
{ term => { 'release' => $release->{name} } },
{ term => { 'author' => $release->{author} } },
{ term => { 'module.authorized' => 1 } },
{ term => { 'module.indexed' => 1 } },
]
}
},
size => 999,
}
);
return unless $provided_modules->{hits}{total};

return [
map { $_->{name} }
grep { $_->{indexed} && $_->{authorized} }
map { @{ $_->{_source}{module} } }
@{ $provided_modules->{hits}{hits} }
];
}

sub _get_depended_releases {
my ( $self, $modules, $page, $page_size, $sort ) = @_;
$sort //= { date => 'desc' };
$page //= 1;
$page_size //= 50;

# because 'terms' doesn't work properly
my $filter_modules = {
bool => {
should => [
map +{ term => { 'dependency.module' => $_ } },
@{$modules}
]
}
};

my $depended = $self->es->search(
index => $self->index->name,
type => 'release',
body => {
query => {
bool => {
must => [
$filter_modules,
{ term => { status => 'latest' } },
{ term => { authorized => 1 } },
]
}
},
size => $page_size,
from => $page * $page_size - $page_size,
sort => $sort,
}
);
return unless $depended->{hits}{total};

return [ map { $_->{_source} } @{ $depended->{hits}{hits} } ];
}

__PACKAGE__->meta->make_immutable;
1;
1 change: 1 addition & 0 deletions lib/MetaCPAN/Server/Controller/Release.pm
Expand Up @@ -67,6 +67,7 @@ sub files : Path('files') : Args(1) {
$c->stash($data);
}

# TODO: remove after deployed in Controller::ReverseDependencies
sub requires : Path('requires') : Args(1) {
my ( $self, $c, $module ) = @_;
my @params = @{ $c->req->params }{qw< page page_size sort >};
Expand Down
29 changes: 29 additions & 0 deletions lib/MetaCPAN/Server/Controller/ReverseDependencies.pm
@@ -0,0 +1,29 @@
package MetaCPAN::Server::Controller::ReverseDependencies;

use strict;
use warnings;

use Moose;

BEGIN { extends 'MetaCPAN::Server::Controller' }

__PACKAGE__->config( namespace => 'reverse_dependencies' );

with 'MetaCPAN::Server::Role::JSONP';

sub dist : Path('dist') : Args(1) {
my ( $self, $c, $dist ) = @_;
my $data = $c->model('CPAN::Release')->reverse_dependencies($dist);
$c->detach('/not_found') unless $data;
$c->stash($data);
}

sub module : Path('module') : Args(1) {
my ( $self, $c, $module ) = @_;
my @params = @{ $c->req->params }{qw< page page_size sort >};
my $data = $c->model('CPAN::Release')->raw->requires( $module, @params );
return unless $data;
$c->stash($data);
}

1;

0 comments on commit 094b9e1

Please sign in to comment.