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;