170 lines
4.2 KiB
Perl
170 lines
4.2 KiB
Perl
package PoorBooru;
|
|
use v5.32;
|
|
use Dancer2;
|
|
use HTTP::Tiny;
|
|
|
|
|
|
our $VERSION = v0.0.1;
|
|
|
|
my $POORBOORU_API = setting("poorbooru_api");
|
|
|
|
|
|
sub validate_page_number ($) { $_[0] =~ /^[1-9][0-9]*$/ }
|
|
|
|
sub api_request ($$;%)
|
|
{
|
|
my ($method, $path, $params_hashref) = @_;
|
|
|
|
my $http = HTTP::Tiny->new(
|
|
timeout => 15,
|
|
verify_SSL => true,
|
|
agent => setting("appname") . " backend " .
|
|
version::->parse($VERSION)->normal,
|
|
|
|
default_headers => {
|
|
"Accept" => "application/json",
|
|
"Content-Type" => "application/json",
|
|
},
|
|
);
|
|
my $params = $http->www_form_urlencode($params_hashref // {});
|
|
|
|
return $http->request($method, "$POORBOORU_API$path" .
|
|
($params ne "" ? "?$params" : ""));
|
|
}
|
|
|
|
sub api_get ($;%) { api_request("GET", shift, @_) }
|
|
|
|
sub nav_pager ($$)
|
|
{
|
|
my ($p, $uri) = @_;
|
|
|
|
my (%pager, %res);
|
|
%pager = %$p;
|
|
$res{first} = $pager{first} != $pager{cur} ?
|
|
uri_for($uri, { page => $pager{first} }) : undef;
|
|
$res{prev} = defined($pager{prev}) && $pager{prev} != $pager{first} ?
|
|
uri_for($uri, { page => $pager{prev} }) : undef;
|
|
$res{cur} = $pager{cur};
|
|
$res{next} = defined($pager{next}) && $pager{next} != $pager{last} ?
|
|
uri_for($uri, { page => $pager{next} }) : undef;
|
|
$res{last} = $pager{last} != $pager{cur} ?
|
|
uri_for($uri, { page => $pager{last} }) : undef;
|
|
|
|
return \%res;
|
|
}
|
|
|
|
|
|
hook before_template_render => sub {
|
|
my $tokens = shift;
|
|
|
|
$tokens->{uris}->{root} = uri_for("/");
|
|
$tokens->{uris}->{login} = uri_for("/login");
|
|
$tokens->{uris}->{logout} = uri_for("/logout");
|
|
$tokens->{uris}->{random} = uri_for("/random/media");
|
|
$tokens->{uris}->{tags} = uri_for("/tags");
|
|
};
|
|
|
|
get "/" => sub {
|
|
my $page = query_parameters->get("page") // 1;
|
|
send_error("Invalid page number", 400) if !validate_page_number($page);
|
|
|
|
my $res = api_get("/media", { page => $page });
|
|
send_error("API error", 500) if !$res->{success};
|
|
|
|
my $data = decode_json($res->{content});
|
|
my @media = map +{
|
|
# XXX point to a cache
|
|
image_src => "$POORBOORU_API/download/$_",
|
|
media_uri => uri_for("/media/$_"),
|
|
}, @{$data->{media}};
|
|
|
|
template "gallery" => {
|
|
title => "PoorBooru",
|
|
media => \@media,
|
|
pager => nav_pager($data->{pager}, "/"),
|
|
};
|
|
};
|
|
|
|
get "/tags" => sub {
|
|
my $page = query_parameters->get("page") // 1;
|
|
send_error("Invalid page number", 400) if !validate_page_number($page);
|
|
|
|
my $res = api_get("/tags", { page => $page });
|
|
send_error("API error", 500) if !$res->{success};
|
|
|
|
my $data = decode_json($res->{content});
|
|
my @tags = map +{
|
|
name => $_->{name},
|
|
count => $_->{count},
|
|
uri => uri_for("/tag/$_->{name}"),
|
|
}, @{$data->{tags}};
|
|
|
|
template "tags" => {
|
|
title => "Tags",
|
|
tags => \@tags,
|
|
pager => nav_pager($data->{pager}, "/tags"),
|
|
};
|
|
};
|
|
|
|
get "/tag/:tag_id_or_name" => sub {
|
|
my $page = query_parameters->get("page") // 1;
|
|
send_error("Invalid page number", 400) if !validate_page_number($page);
|
|
|
|
my $tag_id_or_name = route_parameters->get("tag_id_or_name");
|
|
|
|
my $res = api_get("/tag/$tag_id_or_name", { page => $page });
|
|
send_error("API error", 500) if !$res->{success};
|
|
|
|
my $data = decode_json($res->{content});
|
|
my @media = map +{
|
|
# XXX point to a cache
|
|
image_src => "$POORBOORU_API/download/$_",
|
|
media_uri => uri_for("/media/$_"),
|
|
}, @{$data->{media}};
|
|
|
|
template "gallery" => {
|
|
title => $data->{name},
|
|
media => \@media,
|
|
pager => nav_pager($data->{pager}, "/tag/$tag_id_or_name"),
|
|
};
|
|
};
|
|
|
|
get "/media/:media_id" => sub {
|
|
my $media_id = route_parameters->get("media_id");
|
|
|
|
my $res = api_get("/media/$media_id");
|
|
send_error("API error", 500) if !$res->{success};
|
|
|
|
my $data = decode_json($res->{content});
|
|
|
|
template "media" => {
|
|
no_title => 1,
|
|
title => $data->{id},
|
|
image_src => "$POORBOORU_API/download/$data->{id}",
|
|
media_id => $data->{id},
|
|
media_filename => $data->{filename},
|
|
media_size => $data->{size},
|
|
media_tags => [],
|
|
};
|
|
};
|
|
|
|
get "/random/media" => sub {
|
|
my $res = api_get("/random/media");
|
|
send_error("API error", 500) if !$res->{success};
|
|
|
|
my $data = decode_json($res->{content});
|
|
# XXX body content.
|
|
redirect "/media/$data->{id}";
|
|
};
|
|
|
|
get "/random/tag" => sub {
|
|
my $res = api_get("/random/tag");
|
|
send_error("API error", 500) if !$res->{success};
|
|
|
|
my $data = decode_json($res->{content});
|
|
# XXX body content.
|
|
redirect "/tag/$data->{id}";
|
|
};
|
|
|
|
true;
|