package PoorBooru; use Dancer2; use HTTP::Tiny; our $VERSION = v0.0.1; my $POORBOORU_API = setting("poorbooru_api"); sub http_tiny () { return 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", }, ); } 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"); $tokens->{uris}->{tags} = uri_for("/tags"); }; get "/" => sub { my $page = query_parameters->get("page") // 1; send_error("Invalid page number", 400) if $page !~ /^[1-9][0-9]*$/; my $res = http_tiny()->get("$POORBOORU_API/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/$_", view_uri => uri_for("/view/$_"), }, @{$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 $page !~ /^[1-9][0-9]*$/; my $http = http_tiny(); my $params = $http->www_form_urlencode({ page => $page }); my $res = $http->get("$POORBOORU_API/tags?$params"); 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 $tag_id_or_name = route_parameters->get("tag_id_or_name"); my $res = http_tiny()->get("$POORBOORU_API/tag/$tag_id_or_name"); 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/$_", view_uri => uri_for("/view/$_"), }, @{$data->{media}}; template "gallery" => { title => $data->{name}, media => \@media, }; }; get "/random" => sub { }; get "/view/:media_id" => sub { }; true;