source: trunk/tools/piwigo_remote.pl @ 4347

Last change on this file since 4347 was 4347, checked in by plg, 14 years ago

merge r4344 from branch 2.0 to trunk

feature 1051: new API method pwg.images.checkFiles. This method will be useful
before asking for an update on photo files.

Enhancement in code factorization.

  • Property svn:eol-style set to LF
File size: 8.5 KB
Line 
1#!/usr/bin/perl
2
3####
4# Usage examples
5#
6# time perl piwigo_remote.pl \
7#   --action=pwg.images.add \
8#   --file=erwann_rocher-web.jpg \
9#   --thumb=erwann_rocher-thumb.jpg \
10#   --high=erwann_rocher-high.jpg \
11#   --original=erwann_rocher-high.jpg \
12#   --define categories=9 \
13#   --chunk_size=200_000
14
15use strict;
16use warnings;
17
18use JSON;
19use LWP::UserAgent;
20# LWP::Debug::level('+');
21use Getopt::Long;
22use Encode qw/is_utf8 decode/;
23use POSIX qw(ceil floor);
24
25my %opt = ();
26GetOptions(
27    \%opt,
28    qw/
29          action=s
30          file=s
31          thumbnail=s
32          high=s
33          original=s
34          categories=s
35          chunk_size=i
36          base_url=s
37          username=s
38          password=s
39          define=s%
40      /
41);
42
43our $ua = LWP::UserAgent->new;
44$ua->agent('Mozilla/piwigo_remote.pl 1.25');
45$ua->cookie_jar({});
46
47my %conf;
48$conf{response_format} = 'json';
49$conf{limit} = 10;
50
51my %conf_default = (
52    base_url => 'http://localhost/piwigo/2.0',
53    username => 'plg',
54    password => 'plg',
55    chunk_size => 500_000,
56);
57foreach my $conf_key (keys %conf_default) {
58    $conf{$conf_key} = defined $opt{$conf_key} ? $opt{$conf_key} : $conf_default{$conf_key}
59}
60
61$ua->default_headers->authorization_basic(
62    $conf{username},
63    $conf{password}
64);
65
66my $result = undef;
67my $query = undef;
68
69binmode STDOUT, ":encoding(utf-8)";
70
71# TODO : don't connect at each script call, use the session duration instead.
72my $form = {
73    method => 'pwg.session.login',
74    username => $conf{username},
75    password => $conf{password},
76};
77
78$result = $ua->post(
79    $conf{base_url}.'/ws.php?format=json',
80    $form
81);
82
83# print "\n", $ua->cookie_jar->as_string, "\n";
84
85if ($opt{action} eq 'pwg.images.add') {
86    use MIME::Base64 qw(encode_base64);
87    use Digest::MD5::File qw/file_md5_hex/;
88
89    $form = {};
90    $form->{method} = 'pwg.images.add';
91
92    my $original_sum = file_md5_hex($opt{original});
93    $form->{original_sum} = $original_sum;
94
95    send_chunks(
96        filepath => $opt{file},
97        type => 'file',
98        original_sum => $original_sum,
99    );
100    $form->{file_sum} = file_md5_hex($opt{file});
101
102    send_chunks(
103        filepath => $opt{thumbnail},
104        type => 'thumb',
105        original_sum => $original_sum,
106    );
107    $form->{thumbnail_sum} = file_md5_hex($opt{thumbnail});
108
109    if (defined $opt{high}) {
110        send_chunks(
111            filepath => $opt{high},
112            type => 'high',
113            original_sum => $original_sum,
114        );
115        $form->{high_sum} = file_md5_hex($opt{high});
116    }
117
118    foreach my $key (keys %{ $opt{define} }) {
119        $form->{$key} = $opt{define}{$key};
120    }
121
122    my $response = $ua->post(
123        $conf{base_url}.'/ws.php?format=json',
124        $form
125    );
126
127    print "-" x 50, "\n";
128    printf("response code    : %u\n", $response->code);
129    printf("response message : %s\n", $response->message);
130    print "-" x 50, "\n";
131    print "\n";
132
133#     use Data::Dumper;
134#     print Dumper($response->content);
135#     print Dumper(from_json($response->content));
136
137    if ($response->is_success) {
138        print "upload successful\n";
139    }
140    else {
141        print Dumper($response);
142        warn 'A problem has occured during upload', "\n";
143        warn $response->decoded_content, "\n";
144        die $response->status_line;
145    }
146}
147
148if ($opt{action} eq 'pwg.tags.list') {
149    use Text::ASCIITable;
150
151    $query = pwg_ws_get_query(
152        method => 'pwg.tags.getList',
153        sort_by_counter => 'true',
154    );
155
156    $result = $ua->get($query);
157    my $tag_result = from_json($result->content);
158    my $t = Text::ASCIITable->new({ headingText => 'Tags' });
159    $t->setCols('id','counter','name');
160
161    my $tag_number = 1;
162    foreach my $tag_href (@{ $tag_result->{result}{tags} }) {
163        $t->addRow(
164            $tag_href->{id},
165            $tag_href->{counter},
166            $tag_href->{name}
167        );
168
169        last if $tag_number++ >= $conf{limit};
170    }
171    print $t;
172}
173
174if ($opt{action} eq 'pwg.tags.getAdminList') {
175    $query = pwg_ws_get_query(
176        method => 'pwg.tags.getAdminList'
177    );
178
179    $result = $ua->get($query);
180    print Dumper($result);
181    my $tags = from_json($result->content)->{result}{tags};
182
183    foreach my $tag (@{$tags}) {
184        # print join(',', keys %{$tag}), "\n"; exit();
185        printf(
186            '{%u} %s ',
187            $tag->{id},
188            $tag->{name}
189        );
190    }
191
192    print "\n";
193}
194
195if ($opt{action} eq 'pwg.categories.add') {
196    $form = {
197        method => 'pwg.categories.add',
198        name => $opt{define}{name},
199        parent => $opt{define}{parent},
200    };
201
202    my $response = $ua->post(
203        $conf{base_url}.'/ws.php?format=json',
204        $form
205    );
206
207    use Data::Dumper;
208    print Dumper(from_json($response->content));
209}
210
211if ($opt{action} eq 'pwg.tags.add') {
212    $form = {
213        method => 'pwg.tags.add',
214        name => $opt{define}{name},
215    };
216
217    my $response = $ua->post(
218        $conf{base_url}.'/ws.php?format=json',
219        $form
220    );
221
222    use Data::Dumper;
223    print Dumper(from_json($response->content));
224}
225
226if ($opt{action} eq 'pwg.images.exist') {
227    $form = {
228        method => $opt{action},
229    };
230
231    foreach my $key (keys %{ $opt{define} }) {
232        $form->{$key} = $opt{define}{$key};
233    }
234
235    my $response = $ua->post(
236        $conf{base_url}.'/ws.php?format=json',
237        $form
238    );
239
240    use Data::Dumper;
241    print Dumper(from_json($response->content)->{result});
242    # print Dumper($response);
243}
244
245if ($opt{action} eq 'pwg.images.checkFiles') {
246    use Digest::MD5::File qw/file_md5_hex/;
247
248    $form = {};
249    $form->{method} = $opt{action};
250
251    foreach my $type (qw/thumbnail file high/) {
252        if (defined $opt{$type}) {
253            $form->{$type.'_sum'} = file_md5_hex($opt{$type});
254        }
255    }
256
257    foreach my $key (keys %{ $opt{define} }) {
258        $form->{$key} = $opt{define}{$key};
259    }
260
261    my $response = $ua->post(
262        $conf{base_url}.'/ws.php?format=json',
263        $form
264    );
265
266    print "-" x 50, "\n";
267    printf("response code    : %u\n", $response->code);
268    printf("response message : %s\n", $response->message);
269    print "-" x 50, "\n";
270    print "\n";
271
272    use Data::Dumper;
273    print Dumper(from_json($response->content));
274}
275
276if ($opt{action} eq 'pwg.images.setInfo' or $opt{action} eq 'pwg.categories.setInfo') {
277    $form = {
278        method => $opt{action},
279    };
280
281    foreach my $key (keys %{ $opt{define} }) {
282        $form->{$key} = $opt{define}{$key};
283    }
284
285    my $response = $ua->post(
286        $conf{base_url}.'/ws.php?format=json',
287        $form
288    );
289
290    use Data::Dumper;
291    # print Dumper(from_json($response->content)->{result});
292    print Dumper($response);
293}
294
295if ($opt{action} eq 'pwg.categories.getList') {
296    $form = {
297        method => $opt{action},
298    };
299
300    foreach my $key (keys %{ $opt{define} }) {
301        $form->{$key} = $opt{define}{$key};
302    }
303
304    my $response = $ua->post(
305        $conf{base_url}.'/ws.php?format=json',
306        $form
307    );
308
309    use Data::Dumper;
310    print Dumper($response->content);
311    print Dumper(from_json($response->content)->{result});
312    print Dumper($response);
313}
314
315
316$query = pwg_ws_get_query(
317    method => 'pwg.session.logout'
318);
319$ua->get($query);
320
321sub pwg_ws_get_query {
322    my %params = @_;
323
324    my $query = $conf{base_url}.'/ws.php?format='.$conf{response_format};
325
326    foreach my $key (keys %params) {
327        $query .= '&'.$key.'='.$params{$key};
328    }
329
330    return $query;
331}
332
333sub send_chunks {
334    my %params = @_;
335
336    use File::Slurp;
337
338    my $content = read_file($params{filepath});
339    my $content_length = length($content);
340    my $nb_chunks = ceil($content_length / $conf{chunk_size});
341
342    my $chunk_pos = 0;
343    my $chunk_id = 1;
344    while ($chunk_pos < $content_length) {
345        my $chunk = substr(
346            $content,
347            $chunk_pos,
348            $conf{chunk_size}
349        );
350        $chunk_pos += $conf{chunk_size};
351
352        my $response = $ua->post(
353            $conf{base_url}.'/ws.php?format=json',
354            {
355                method => 'pwg.images.addChunk',
356                data => encode_base64($chunk),
357                original_sum => $params{original_sum},
358                position => $chunk_id,
359                type => $params{type},
360            }
361        );
362
363        printf(
364            'chunk %05u of %05u for %s "%s"'."\n",
365            $chunk_id,
366            $nb_chunks,
367            $params{type},
368            $params{filepath}
369        );
370        if ($response->code != 200) {
371            printf("response code    : %u\n", $response->code);
372            printf("response message : %s\n", $response->message);
373        }
374
375        $chunk_id++;
376    }
377}
Note: See TracBrowser for help on using the repository browser.