114 lines
2.7 KiB
Perl
114 lines
2.7 KiB
Perl
package Pooru::API::V0::Controller::Media;
|
|
use Mojo::Base "Mojolicious::Controller", -signatures;
|
|
|
|
use List::Util qw(uniq);
|
|
|
|
my %search_opts = Pooru::API::V0::_search_opts->%*;
|
|
|
|
sub _list_no_tags ($self, $page)
|
|
{
|
|
my $paged_media = $self->media_model->get->page($page);
|
|
|
|
return $self->render(json => {
|
|
media => $paged_media->fetchall,
|
|
pager => $paged_media->pager,
|
|
});
|
|
}
|
|
|
|
sub _list_with_tags ($self, $page, @tags)
|
|
{
|
|
my $paged_media_ids = $self->media_model->with_all_tags(@tags)
|
|
->page($page);
|
|
my @media_ids = map {$_->{media_id}} $paged_media_ids->fetchall->@*;
|
|
|
|
return $self->render(json => {
|
|
media => $self->media_model->get(@media_ids)->page($page)
|
|
->fetchall,
|
|
# Use the original pager, as the one for the media is already
|
|
# capped at the size of a single page.
|
|
pager => $paged_media_ids->pager,
|
|
});
|
|
}
|
|
|
|
sub list ($self)
|
|
{
|
|
my $v = $self->validation;
|
|
|
|
my $page = $v->optional("page")->num(1, undef)->param // 1;
|
|
return $self->render(
|
|
json => {error => "Invalid page number."},
|
|
status => 400,
|
|
) if $v->has_error;
|
|
|
|
my @tags = uniq split(" ", $v->optional("tags")->param // "");
|
|
return $self->render(
|
|
json => {error => "Invalid tags."},
|
|
status => 400,
|
|
) if $v->has_error;
|
|
|
|
return $self->render(
|
|
json => {error => "Too many tags."},
|
|
status => 400,
|
|
) if @tags > Pooru::API::V0::Model::Tags::ROWS;
|
|
|
|
my @tag_ids;
|
|
@tag_ids = map {$_->{id}} $self->tags_model
|
|
->get(display => [@tags])->fetchall->@* if @tags > 0;
|
|
|
|
return @tags == 0 ?
|
|
$self->_list_no_tags($page) :
|
|
$self->_list_with_tags($page, @tag_ids);
|
|
}
|
|
|
|
sub show ($self)
|
|
{
|
|
my $v = $self->validation;
|
|
|
|
my $page = $v->optional("page")->num(1, undef)->param // 1;
|
|
return $self->render(
|
|
json => {error => "Invalid page number."},
|
|
status => 400,
|
|
) if $v->has_error;
|
|
|
|
my $media = $self->media_model->get($self->stash("media_id"))->single;
|
|
return $self->render(
|
|
json => {error => "Media not found"},
|
|
status => 404,
|
|
) if !defined($media);
|
|
|
|
my $paged_tags = $self->tags_model
|
|
->ranked_for_media($media->{id})->page($page);
|
|
|
|
return $self->render(json => {
|
|
$media->%*,
|
|
tags => $paged_tags->fetchall,
|
|
pager => $paged_tags->pager,
|
|
});
|
|
}
|
|
|
|
sub similar ($self)
|
|
{
|
|
my $media = $self->media_model->get($self->stash("media_id"))->single;
|
|
return $self->render(
|
|
json => {error => "Media not found"},
|
|
status => 404,
|
|
) if !defined($media);
|
|
|
|
my @similar_media = $self->media_model
|
|
->similar($media->{id})->fetchall->@*;
|
|
my %media = map +(
|
|
$_->{id} => $_
|
|
), $self->media_model
|
|
->get(map {$_->{media_id}} @similar_media)->fetchall->@*;
|
|
|
|
foreach my $sm (@similar_media) {
|
|
$sm = {
|
|
score => $sm->{score},
|
|
$media{$sm->{media_id}}->%*,
|
|
}
|
|
}
|
|
|
|
return $self->render(json => {media => [@similar_media]});
|
|
}
|
|
|
|
1;
|