source: trunk/tools/piwigo_remote.pl @ 23121

Last change on this file since 23121 was 21070, checked in by plg, 12 years ago

bug 2852 fixed: ability to use HTML markup in album description for pwg.categories.add

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