copy from DokuWiki

Pierrick Le Gall
2023-05-04 18:16:43 +02:00
parent 662645568a
commit 0325a9c7d2
+228
@@ -0,0 +1,228 @@
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
- *original_sum* : md5sum that makes the photo unique
- *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) *original_filename*
- (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)
- (optional) *check_uniqueness* : check if file already exists (based
on filename or md5sum, see $conf\['uniqueness_mode'\] in
include/config_default.inc.php)
- (optional) *image_id* : give an image_id if you want to update an
existing photo
- (deprecated) *high_sum*
- (deprecated) *thumbnail_sum*
## Examples
### Perl
piwigo-remote.pl is included into Piwigo. You can found this script in
the "tools" directory.
``` perl
#!/usr/bin/perl
####
# Usage examples
#
# time perl piwigo_remote.pl \
# --file=erwann_rocher-web.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 categories=s chunk_size=i define=s%/
);
our $ua = LWP::UserAgent->new;
$ua->cookie_jar({});
my %conf;
$conf{base_url} = 'http://localhost/piwigo/dev/branches/2.7';
$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
);
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{file});
$form->{original_sum} = $original_sum;
send_chunks(
filepath => $opt{file},
type => 'file',
original_sum => $original_sum,
);
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;
}
$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 = @_;
use MIME::Base64 qw(encode_base64);
use File::Slurp;
my $content = 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 => encode_base64($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++;
}
}
```