Pooru/lib/Pooru/API/V0/Controller/Media.pm

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;