PoorBooru/lib/SeaweedFS/Client.pm

65 lines
1.2 KiB
Perl

package SeaweedFS::Client;
use v5.16;
use strict;
use warnings;
use Carp;
use List::Util qw(sample);
use Scalar::Util qw(blessed);
use Mojo::UserAgent;
use SeaweedFS::FID;
our $VERSION = v0.0.1;
sub new
{
my ($class, $murl) = @_;
return bless {
_murl => $murl,
_ua => Mojo::UserAgent->new,
_vurls => {},
}, $class;
}
sub get
{
my ($self, $target_fid) = @_;
return $self->{_ua}->get($self->url_for($target_fid));
}
sub url_for
{
my ($self, $p) = @_;
my $fid;
if (defined(blessed $p) && $p->can("volume_id")) {
$fid = $p;
} elsif (!defined(blessed $p)) {
eval {
$fid = SeaweedFS::FID->from_string($p);
} or $fid = SeaweedFS::FID->from_bin($p);
} else {
croak "Unsupported FID type " . blessed($p);
}
my $vid = $fid->volume_id;
if (!defined($self->{_vurls}{$vid}) || $self->{_vurls}{$vid}->@* == 0) {
my $res = $self->{_ua}
->get("$self->{_murl}/dir/lookup?fileId=$fid&read=yes")
->result;
$self->{_vurls}{$vid} = [
map { $_->{publicUrl} } $res->json->{locations}->@*
];
}
my $url = sample(1, $self->{_vurls}{$vid}->@*);
return undef unless defined $url;
$url = "http://$url" if $url !~ m{^https?://};
return "$url/$fid";
}
1;