pwg.images.add & pwg.images.addChunk

Add a photo.

To avoid limitations on HTTP POST maximum size, the pwg.images.add was “splitted” into several calls to pwg.images.addChunk and then a single call to pwg.images.add.

To avoid high CPU usage on server side, the photo must be resized on sender side, at least in 2 sizes : the thumbnail and the “web resized” photo. You can optionally send a “high resolution” photo.

pwg.images.addChunk

pwg.images.addChunk adds a chunk in the “upload/buffer” directory. The uploaded chunk filename follows the following format: <original_sum>-<type>-<position>.block

Parameters

  • data : substring of the base64 encoded binary file
  • original_sum : md5sum of the original photo, used as a unique identifier, not to check the chunk upload
  • type : a value among {thumb, file, high}
  • position : the numeric position of the chunk among all chunks of the given file

Tip: 500KB is a good size for a chunk, don't go too high because you'll encounter problems related to POST maximum size, don't go too low because you'll take more time to perform the numerous requests than really sending the chunked content.

pwg.images.add

Now that thumbnail, web resized and optionnaly the high resolution chunks have been added, pwg.images.add merge the chunks, copy the produced files into their final directory, checks the produced files against their expected md5sums, register the photo in the database.

Parameters

  • file_sum : md5sum of the “web resized” photo
  • thumbnail_sum : md5sum of the thumbnail
  • original_sum : md5sum that makes the photo unique, most of the time identical to high_sum
  • categories : list of category identifiers where you want the photo to be shown. Optionnaly, you can set a rank inside the each category. Example : “19,3;16,0;134” will associate the photo to category 19 at rank 3, to category 16 at rank 0 (first position) and to category 134 with an automatic rank (last position).
  • (optional) high_sum : md5sum of the “high resolution” photo
  • (optional) name
  • (optional) author
  • (optional) date_creation : formatted as “2009-03-26”
  • (optional) comment : the description you can read just below the photo
  • (optional) tag_ids : list of tag numeric identifiers, separated with commas. Example “23,31,18” will associate the photo to tags 23, 31 and 18.
  • (optional) level : 0 (—-), 1 (Contacts), 2 (Friends), 4 (Family), 8 (Admins)

Examples

Perl

piwigo-remote.pl is included into Piwigo. You can found this script in the “tools” directory.

#!/usr/bin/perl
 
####
# Usage examples
#
# time perl piwigo_remote.pl \
#   --action=pwg.images.add \
#   --file=erwann_rocher-web.jpg \
#   --thumb=erwann_rocher-thumb.jpg \
#   --high=erwann_rocher-high.jpg \
#   --original=erwann_rocher-high.jpg \
#   --define categories=9 \
#   --chunk_size=200_000
 
use strict;
use warnings;
 
use JSON;
use LWP::UserAgent;
use Getopt::Long;
use Encode qw/is_utf8 decode/;
use POSIX qw(ceil floor);
 
my %opt = ();
GetOptions(
    \%opt,
    qw/action=s file=s thumbnail=s high=s original=s categories=s chunk_size=i define=s%/
);
 
our $ua = LWP::UserAgent->new;
$ua->cookie_jar({});
 
my %conf;
$conf{base_url} = 'http://localhost/piwigo/2.0';
$conf{response_format} = 'json';
$conf{username} = 'plg';
$conf{password} = 'plg';
$conf{chunk_size} = defined $opt{chunk_size} ? $opt{chunk_size} : 500_000;
 
my $result = undef;
my $query = undef;
 
binmode STDOUT, ":encoding(utf-8)";
 
# TODO : don't connect at each script call, use the session duration instead.
my $form = {
    method => 'pwg.session.login',
    username => $conf{username},
    password => $conf{password},
};
 
$result = $ua->post(
    $conf{base_url}.'/ws.php?format=json',
    $form
);
 
# print "\n", $ua->cookie_jar->as_string, "\n";
 
if ($opt{action} eq 'pwg.images.add') {
    use MIME::Base64 qw(encode_base64);
    use Digest::MD5::File qw/file_md5_hex/;
    use File::Slurp;
 
    $form = {};
    $form->{method} = 'pwg.images.add';
 
    my $original_sum = file_md5_hex($opt{original});
    $form->{original_sum} = $original_sum;
 
    send_chunks(
        filepath => $opt{file},
        type => 'file',
        original_sum => $original_sum,
    );
    $form->{file_sum} = file_md5_hex($opt{file});
 
    send_chunks(
        filepath => $opt{thumbnail},
        type => 'thumb',
        original_sum => $original_sum,
    );
    $form->{thumbnail_sum} = file_md5_hex($opt{thumbnail});
 
    if (defined $opt{high}) {
        send_chunks(
            filepath => $opt{high},
            type => 'high',
            original_sum => $original_sum,
        );
        $form->{high_sum} = file_md5_hex($opt{high});
    }
 
    foreach my $key (keys %{ $opt{define} }) {
        $form->{$key} = $opt{define}{$key};
    }
 
    my $response = $ua->post(
        $conf{base_url}.'/ws.php?format=json',
        $form
    );
 
    print "-" x 50, "\n";
    printf("response code    : %u\n", $response->code);
    printf("response message : %s\n", $response->message);
    print "-" x 50, "\n";
    print "\n";
 
    if ($response->is_success) {
        print "upload successful\n";
    }
    else {
        warn 'A problem has occured during upload', "\n";
        warn $response->decoded_content, "\n";
        die $response->status_line;
    }
}
 
if ($opt{action} eq 'pwg.categories.add') {
    $form = {
        method => 'pwg.categories.add',
        name => $opt{define}{name},
        parent => $opt{define}{parent},
    };
 
    my $response = $ua->post(
        $conf{base_url}.'/ws.php?format=json',
        $form
    );
 
    use Data::Dumper;
    print Dumper(from_json($response->content));
}
 
$query = pwg_ws_get_query(
    method => 'pwg.session.logout'
);
$ua->get($query);
 
sub pwg_ws_get_query {
    my %params = @_;
 
    my $query = $conf{base_url}.'/ws.php?format='.$conf{response_format};
 
    foreach my $key (keys %params) {
        $query .= '&'.$key.'='.$params{$key};
    }
 
    return $query;
}
 
sub send_chunks {
    my %params = @_;
 
    my $content = encode_base64(read_file($params{filepath}));
    my $content_length = length($content);
    my $nb_chunks = ceil($content_length / $conf{chunk_size});
 
    my $chunk_pos = 0;
    my $chunk_id = 1;
    while ($chunk_pos < $content_length) {
        my $chunk = substr(
            $content,
            $chunk_pos,
            $conf{chunk_size}
        );
        $chunk_pos += $conf{chunk_size};
 
        my $response = $ua->post(
            $conf{base_url}.'/ws.php?format=json',
            {
                method => 'pwg.images.addChunk',
                data => $chunk,
                original_sum => $params{original_sum},
                position => $chunk_id,
                type => $params{type},
            }
        );
 
        printf(
            'chunk %05u of %05u for %s "%s"'."\n",
            $chunk_id,
            $nb_chunks,
            $params{type},
            $params{filepath}
        );
        if ($response->code != 200) {
            printf("response code    : %u\n", $response->code);
            printf("response message : %s\n", $response->message);
        }
 
        $chunk_id++;
    }
}
 
Back to top
dev/webapi/pwg.images.add.txt · Last modified: 2011/09/13 15:41 (external edit)
 
 
twitter facebook google+ newsletter Donate Piwigo.org © 2002-2014 · Contact