Catmandu-MediaHaven
view release on metacpan or search on metacpan
lib/Catmandu/MediaHaven.pm view on Meta::CPAN
package Catmandu::MediaHaven;
=head1 NAME
Catmandu::MediaHaven - Tools to communicate with the Zeticon MediaHaven server
=head1 SYNOPSIS
use Catmandu::MediaHaven;
my $mh = Catmandu::MediaHaven->new(
url => '...' ,
username => '...' ,
password => '...');
my $result = $mh->search('nature', start => 0 , num => 100);
die "search failed" unless defined($result);
for my $res (@{$result->{mediaDataList}}) {
my $id = $res->{fragmentId};
my $date = $res->{data};
print "$id $date\n";
}
my $record = $mh->record('q2136s817');
my $date = $record->{date};
print "q2136s817 $date\n";
$mh->export($id, sub {
my $data = shift;
print $data;
});
=head1 DESCRIPTION
The L<Catmandu::MediaHaven> module is a low end interface to the MediaHaven
REST api. See also: https://archief.viaa.be/mediahaven-rest-api
=head1 METHODS
=head2 new(url => ... , username => ... , password => ...)
Create a new connection to the MediaHaven server.
=cut
use Moo;
use HTTP::Request::Common;
use LWP::Simple;
use URI::Escape;
use JSON;
use LWP;
use Carp;
use Catmandu;
use Cache::LRU;
use REST::Client;
our $VERSION = '0.08';
with 'Catmandu::Logger';
has 'url' => (is => 'ro' , required => 1);
has 'username' => (is => 'ro' , required => 1);
has 'password' => (is => 'ro' , required => 1);
has 'record_query' => (is => 'ro' , default => sub { "q=%%2B(MediaObjectFragmentId:%s)"; });
has id_fixer => (is => 'ro' , init_arg => 'record_id_fix', coerce => sub {Catmandu->fixer($_[0])},);
has 'sleep' => (is => 'ro' , default => sub { 1 });
has 'cache' => (is => 'lazy');
has 'cache_size' => (is => 'ro' , default => '1000');
sub _build_cache {
my $self = shift;
return Cache::LRU->new(size => $self->cache_size);
}
=head2 search($query, start => ... , num => ...)
lib/Catmandu/MediaHaven.pm view on Meta::CPAN
=head2 record($id)
Retrieve one record from the MediaHaven server based on an identifier. Returns
a HASH of results.
=cut
sub record {
my ($self,$id) = @_;
croak "need an id" unless defined($id);
if (my $hit = $self->cache->get($id)) {
return $hit;
}
my $query = sprintf $self->record_query , $id;
$self->log->info("retrieve query: $query");
my $res = $self->_rest_get($query);
if (exists $res->{code}) {
$self->log->error("retrieve query '$query' failed: " . $res->{message});
return undef;
}
if ($res->{mediaDataList}) {
my $hit = $res->{mediaDataList}->[0];
if ($self->id_fixer) {
return $self->id_fixer->fix($hit);
}
else {
return $hit;
}
}
else {
return undef;
}
}
=head2 edit($id,$field,@values)
Edit the metadata of a record
=cut
sub edit {
my ($self,$id,$field,@values) = @_;
croak "need an id and $field" unless defined($id) && defined($field);
$self->log->info("edit record $id");
my $record = $self->record($id);
unless ($record) {
$self->log->error("no such record $id");
return undef;
}
my $fragmentId = $record->{fragmentId};
my @param;
for (@values) {
push @param , 'value' , $_;
}
my $res = $self->_rest_post("$fragmentId/$field", @param);
return $res;
}
=head2 export($id, $callback)
Export the binary content of a record from the MediaHaven server. The callback
will retrieve a stream of data when the download is available,
=cut
sub export {
my ($self,$id,$callback) = @_;
croak "need an id and callback" unless defined($id) && defined($callback);
$self->log->info("export record $id");
my $record = $self->record($id);
unless ($record) {
$self->log->error("no such record $id");
return undef;
}
my $mediaObjectId = $record->{mediaObjectId};
return undef unless $mediaObjectId;
my $media_url = sprintf "%s/%s/export" , $self->_rest_base , $mediaObjectId;
$self->log->info("posting $media_url");
my ($export_job,$next) = $self->_post_json($media_url);
return undef unless $export_job;
my $downloadUrl;
while (1) {
my $exportId = $export_job->[0]->{exportId};
my $status = $export_job->[0]->{status};
$self->log->debug("exportId = $exportId ; status = $status");
last if $status =~ /^(failed|cancelled)$/;
$downloadUrl = $export_job->[0]->{downloadUrl};
if ($downloadUrl =~ /^htt/) {
last;
}
$self->log->debug("sleep " . $self->sleep);
sleep $self->sleep;
$export_job = $self->_get_json($next);
}
my $rest_url = $self->_rest_base($downloadUrl);
lib/Catmandu/MediaHaven.pm view on Meta::CPAN
my $client = REST::Client->new();
$client->GET($url);
my $json = $client->responseContent();
decode_json $json;
}
sub _post_json {
my ($self,$url,$body) = @_;
$self->log->debug($url);
my $client = REST::Client->new();
if ($body) {
my $response = $client->getUseragent->request(POST $url , $body , Content_Type => 'form-data');
if ($response->is_success) {
return { ok => 1};
}
else {
my $json = $response->decoded_content;
return decode_json $json;
}
}
else {
$client->POST($url);
my $json = $client->responseContent();
my $location = $self->_rest_base( $client->responseHeader('Location') );
my $perl = decode_json $json;
wantarray ? ($perl,$location) : $perl;
}
}
sub _rest_base {
my ($self,$url) = @_;
my $authen = sprintf "%s:%s" , uri_escape($self->username) , uri_escape($self->password);
my $media_url = $url // $self->url;
$media_url =~ s{https://}{};
$media_url = 'https://' . $authen . '@' . $media_url;
$media_url;
}
sub _rest_get {
my ($self,@param) = @_;
my $media_url = $self->_rest_base . '?';
$media_url .= join("&",@param);
$self->_get_json($media_url);
}
sub _rest_post {
my ($self,$fragment,@param) = @_;
my $media_url = $self->_rest_base .
'/' .
$fragment;
$self->_post_json($media_url,\@param);
}
=head1 MODULES
L<Catmandu::Importer::MediaHaven>
L<Catmandu::Store::File::MediaHaven>
L<Catmandu::Store::File::MediaHaven::Bag>
L<Catmandu::Store::File::MediaHaven::Index>
=head1 AUTHOR
=over
=item * Patrick Hochstenbach, C<< <patrick.hochstenbach at ugent.be> >>
=back
=head1 LICENSE AND COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the terms
of either: the GNU General Public License as published by the Free Software Foundation;
or the Artistic License.
See L<http://dev.perl.org/licenses/> for more information.
=cut
1;
( run in 1.205 second using v1.01-cache-2.11-cpan-364913b4093 )