Skip to content

Commit

Permalink
extend find_download_url to be able to query dists rather than modules
Browse files Browse the repository at this point in the history
  • Loading branch information
haarg committed Apr 25, 2024
1 parent 3dc4f0f commit 59aba64
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 59 deletions.
129 changes: 71 additions & 58 deletions lib/MetaCPAN/Query/Release.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ cpanm Foo~<2
cpanm --dev Foo~<2
=> status: -backpan, module.version_numified: lt: 2, sort_by: status,version_numified,date
$release->find_download_url( 'Foo', { version => $version, dev => 0|1 });
$release->find_download_url( 'module', 'Foo', { version => $version, dev => 0|1 });
Sorting:
Expand All @@ -1029,68 +1029,86 @@ Sorting:
=cut

sub find_download_url {
my ( $self, $module, $args ) = @_;
my ( $self, $type, $module, $args ) = @_;
$args ||= {};

my $dev = $args->{dev};
my $version = $args->{version};
my $explicit_version = $version && $version =~ /==/;

my @filters;

die 'type must be module or dist'
unless $type eq 'module' || $type eq 'dist';
my $module_filter = $type eq 'module';

if ( !$explicit_version ) {
push @filters, { not => { term => { status => 'backpan' } } };
if ( !$dev ) {
push @filters, { term => { maturity => 'released' } };
}
}

my $version_filters = $self->_version_filters($version);
my $prefix = $module_filter ? 'module.' : '';

my $version_filters
= $self->_version_filters( $version, $prefix . 'version_numified' );

my $entity_filter = {
bool => {
must => [
{ term => { $prefix . 'authorized' => 1 } },
{ term => { $prefix . 'indexed' => 1 } },
{ term => { $prefix . 'name' => $module } },
(
exists $version_filters->{must}
? @{ $version_filters->{must} }
: ()
)
],
(
exists $version_filters->{must_not}
? ( must_not => [ $version_filters->{must_not} ] )
: ()
)
}
};

# filters to be applied to the nested modules
my $module_f = {
nested => {
path => 'module',
inner_hits => { _source => 'version' },
filter => {
bool => {
must => [
{ term => { 'module.authorized' => 1 } },
{ term => { 'module.indexed' => 1 } },
{ term => { 'module.name' => $module } },
(
exists $version_filters->{must}
? @{ $version_filters->{must} }
: ()
)
],
(
exists $version_filters->{must_not}
? ( must_not => [ $version_filters->{must_not} ] )
: ()
)
}
if ($module_filter) {
push @filters,
{
nested => {
path => 'module',
inner_hits => { _source => 'version' },
filter => $entity_filter,
}
}
};
};
}
else {
push @filters, $entity_filter;
}

my $filter
= @filters
? { bool => { must => [ @filters, $module_f ] } }
: $module_f;
? { bool => { must => \@filters } }
: $filters[0];

# sort by score, then version desc, then date desc
my @sort = (
'_score',
{
'module.version_numified' => {
mode => 'max',
order => 'desc',
nested_path => 'module',
nested_filter => $module_f->{nested}{filter}
}
},
{ date => { order => 'desc' } }
);
my $version_sort
= $module_filter
? {
'module.version_numified' => {
mode => 'max',
order => 'desc',
nested_path => 'module',
nested_filter => $entity_filter,
}
}
: { version_numified => { order => 'desc' } }

my @sort
= ( '_score', $version_sort, { date => { order => 'desc' } } );

my $query;

Expand Down Expand Up @@ -1120,16 +1138,16 @@ sub find_download_url {
}

my $body = {
query => $query,
size => 1,
sort => \@sort,
_source => [ 'release', 'download_url', 'date', 'status' ],
query => $query,
size => 1,
sort => \@sort,
_source => [ 'release', 'download_url', 'date', 'status' ],
search_type => 'dfs_query_then_fetch',
};

my $ret = $self->es->search(
index => $self->index_name,
type => 'file',
type => $module_filter ? 'file' : 'release',
body => $body,
);

Expand Down Expand Up @@ -1163,15 +1181,15 @@ sub find_download_url {
}

sub _version_filters {
my ( $self, $version ) = @_;
my ( $self, $version, $field ) = @_;

return () unless $version;

if ( $version =~ s/^==\s*// ) {
return +{
must => [ {
term => {
'module.version_numified' => $self->_numify($version)
$field => $self->_numify($version)
}
} ]
};
Expand All @@ -1191,18 +1209,14 @@ sub _version_filters {

if ( keys %range ) {
$filters{must}
= [ { range => { 'module.version_numified' => \%range } } ];
= [ { range => { $field => \%range } } ];
}

if (@exclusion) {
$filters{must_not} = [];
push @{ $filters{must_not} }, map {
+{
term => {
'module.version_numified' => $self->_numify($_)
}
}
} @exclusion;
push @{ $filters{must_not} },
map { +{ term => { $field => $self->_numify($_) } } }
@exclusion;
}

return \%filters;
Expand All @@ -1211,8 +1225,7 @@ sub _version_filters {
return +{
must => [ {
range => {
'module.version_numified' =>
{ 'gte' => $self->_numify($version) }
$field => { 'gte' => $self->_numify($version) }
},
} ]
};
Expand Down
4 changes: 3 additions & 1 deletion lib/MetaCPAN/Server/Controller/Search/DownloadURL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ has '+type' => ( default => 'file' );

sub get : Local : Path('/download_url') : Args(1) {
my ( $self, $c, $module ) = @_;
my $type = 'module';
my $data
= $self->model($c)->find_download_url( $module, $c->req->params );
= $self->model($c)
->find_download_url( $type, $module, $c->req->params );
return $c->detach( '/not_found', [] ) unless $data;
$c->stash($data);
}
Expand Down

0 comments on commit 59aba64

Please sign in to comment.