source: extensions/pLoader/trunk/src/Uploader/PWG/WebServices.pm @ 4097

Last change on this file since 4097 was 4097, checked in by ronosman, 15 years ago

Bug 1070 fixed : don't send empty tag_ids string.

  • Property svn:eol-style set to LF
File size: 12.3 KB
Line 
1# +-----------------------------------------------------------------------+
2# | pLoader - a Perl photo uploader for Piwigo                            |
3# +-----------------------------------------------------------------------+
4# | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
5# +-----------------------------------------------------------------------+
6# | This program is free software; you can redistribute it and/or modify  |
7# | it under the terms of the GNU General Public License as published by  |
8# | the Free Software Foundation                                          |
9# |                                                                       |
10# | This program is distributed in the hope that it will be useful, but   |
11# | WITHOUT ANY WARRANTY; without even the implied warranty of            |
12# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
13# | General Public License for more details.                              |
14# |                                                                       |
15# | You should have received a copy of the GNU General Public License     |
16# | along with this program; if not, write to the Free Software           |
17# | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
18# | USA.                                                                  |
19# +-----------------------------------------------------------------------+
20package Uploader::PWG::WebServices;
21 
22use strict;
23use warnings;
24use MIME::Base64 qw(encode_base64); 
25use JSON;
26use LWP::UserAgent;
27use Data::Dumper;
28use Digest::MD5::File qw/file_md5_hex md5_hex/;
29use File::Slurp;
30use Encode qw/encode decode is_utf8/;
31use POSIX qw(ceil floor);
32use base qw/
33           Uploader::Object
34           Class::Accessor::Fast
35           /;
36
37__PACKAGE__->mk_accessors( 
38    qw/
39           uagent
40           urlbase
41           username
42           password
43           qry_list_categories
44           qry_add_categories
45           qry_list_tags
46           items
47           tags
48           categories
49           site_high_file
50           site_resized_file
51           site_thumb_file
52           site_image_name
53           site_tags
54           rank
55           site_author
56           site_comment
57           site_img_date_creation
58           uagent_response
59           login_result
60           action_result
61           upload_high
62           chunk_size
63      / 
64);
65
66$|=1;
67
68sub Init {
69    my ( $self ) = @_ ;
70 
71    $self->uagent(
72        LWP::UserAgent->new
73    );
74   
75   
76    $self->uagent->cookie_jar({});     
77
78    $self->urlbase(
79        $self->{site_url}
80    );
81   
82    $self->username(
83        $self->{site_username}
84    );
85   
86    $self->password(
87        $self->{site_password}
88    );
89   
90    $self->chunk_size(
91        $self->{chunk_size}
92    );
93
94   
95    $self->uagent->default_headers->authorization_basic(
96        $self->{http_username}||$self->username, 
97        $self->{http_password}||$self->password
98    );
99   
100   
101    $self->qry_list_categories( sprintf
102        "%s/ws.php?format=json&method=%s&recursive=%s",
103        $self->urlbase,
104#        'pwg.categories.getAdminList',
105        'pwg.categories.getList',
106        'true',
107    );
108
109    $self->qry_list_tags( sprintf
110        "%s/ws.php?format=json&method=%s",
111        $self->urlbase,
112        'pwg.tags.getAdminList',
113    );
114
115
116    my $form = {
117        method => 'pwg.session.login',
118        username => $self->username,
119        password => $self->password,
120    };
121 
122    $self->uagent_response(
123        $self->uagent->post(
124            $self->urlbase.'/ws.php?format=json',
125            $form
126        )
127    );
128   
129    my $hresult = {} ;
130
131    if($self->uagent_response->is_success){
132        eval {
133            $hresult = from_json(
134                $self->uagent_response->content
135            );
136        };
137    }
138    else{
139        $hresult = {
140            'message' => $self->uagent_response->message,
141            'stat'    => 'fail',
142        };
143    }
144
145    $self->login_result(
146        $hresult
147    );
148
149}
150
151sub GetCategories {
152    my ( $self ) = @_;
153
154    my $result;
155    eval {
156        $result = $self->uagent->get(
157            $self->qry_list_categories
158        );
159    };
160
161    if($@){
162        printf("An error occured in query execution %s\n%s",
163            $self->qry_list_categories,
164            $@,
165        );     
166    }
167    my $hresult;
168   
169    eval {
170        $hresult = from_json(
171            $result->content
172        );
173    };
174   
175    $hresult ||= {};
176
177    my $categories = $hresult->{result}{categories};
178
179    $categories;       
180}
181
182sub GetTags {
183    my ( $self ) = @_;
184
185    my $result;
186    eval {
187        $result = $self->uagent->get(
188            $self->qry_list_tags
189        );
190    };
191
192    if($@){
193        printf("An error occured in query execution %s\n%s",
194            $self->qry_list_tags,
195            $@,
196        );     
197    }
198    my $hresult;
199   
200    eval {
201        $hresult = from_json(
202            $result->content
203        );
204    };
205   
206    $hresult ||= {};
207
208    $hresult->{result}{tags};
209}
210
211sub AddTags {
212    my ( $self, $name ) = @_;
213
214    my $form = {
215        method            => 'pwg.tags.add',
216        name              => $name,
217       
218    };
219
220    my $result = $self->uagent->post(
221        $self->urlbase.'/ws.php?format=json',
222        $form
223    );
224
225    my $content = {};
226        eval {
227            $content = from_json(
228                $result->content
229            );
230        };
231
232    return ( $result->is_success, $result->status_line, $content );
233       
234} 
235
236
237sub UploadImage {
238    my ( $self, $yield_callback ) = @_;
239
240    my $file_sum;
241
242    eval {
243        $file_sum = file_md5_hex(
244            encode('iso-8859-1', $self->site_resized_file)
245        );
246    };
247 
248
249    my $thumbnail_sum = file_md5_hex(
250        encode('iso-8859-1', $self->site_thumb_file),
251    );
252
253    my $original_sum = file_md5_hex(
254        encode('iso-8859-1', $self->site_high_file)
255    );
256
257    my $form = {
258        method            => 'pwg.images.exist',
259        md5sum_list       => $original_sum,
260    };
261
262    my $result = $self->uagent->post(
263        $self->urlbase.'/ws.php?format=json',
264        $form
265    );
266
267    my $hresult = {};
268        eval {
269            $hresult = from_json(
270                $result->{_content}
271            );
272        };
273
274    my $site_image_name = is_utf8($self->site_image_name) ? 
275                                  $self->site_image_name : 
276                                  encode('utf8', $self->site_image_name);
277
278    my $image_id = $hresult->{result}{$original_sum};
279    my $status = 0;
280    my $status_line = "An error has occured during upload.";
281    my $content = {};
282    while(1){
283        if(!defined($image_id)){
284               
285            my $resized_params = {
286                filepath => encode('iso-8859-1', $self->site_resized_file),
287                type => 'file',
288                original_sum => $original_sum,
289                yield_callback => $yield_callback,
290            };
291   
292            $self->send_chunks(
293                $resized_params
294            );
295
296            $yield_callback->() if 'CODE' eq ref($yield_callback);
297            $status_line = $resized_params->{message};
298            last if !$resized_params->{ok};
299         
300            my $thumb_params = {
301                filepath => encode('iso-8859-1', $self->site_thumb_file),
302                type => 'thumb',
303                original_sum => $original_sum,         
304                yield_callback => $yield_callback,
305            };
306   
307            $self->send_chunks(
308                $thumb_params
309            );
310
311            $yield_callback->() if 'CODE' eq ref($yield_callback);
312            $status_line = $thumb_params->{message};
313            last if !$thumb_params->{ok};
314
315       
316            $form = {
317                method            => 'pwg.images.add',
318                original_sum      => $original_sum,
319                file_sum          => $file_sum,
320                thumbnail_sum     => $thumbnail_sum,
321                categories        => $self->categories,
322                name              => $site_image_name,
323                rank              => $self->rank,
324                author            => $self->site_author,
325                comment           => $self->site_comment,
326                date_creation     => $self->site_img_date_creation,
327                tag_ids           => $self->site_tags,
328               
329            };
330            my $high_params = {
331                filepath => encode('iso-8859-1', $self->site_high_file),
332                type => 'high',
333                original_sum => $original_sum,
334                yield_callback => $yield_callback,
335            };
336   
337            if($self->upload_high){
338                $form->{high_sum} = $original_sum;
339   
340                $self->send_chunks(
341                    $high_params
342                );
343                $yield_callback->() if 'CODE' eq ref($yield_callback);
344
345                $status_line = $high_params->{message};
346                last if !$high_params->{ok};
347   
348            }
349        }
350        else {
351            $form = {
352                method            => 'pwg.images.setInfo',
353                image_id          => $image_id,
354                categories        => $self->categories,
355                name              => $site_image_name,
356                rank              => $self->rank,
357                author            => $self->site_author,
358                comment           => $self->site_comment,
359                date_creation     => $self->site_img_date_creation,
360                tag_ids           => $self->site_tags,
361            };
362            $yield_callback->() if 'CODE' eq ref($yield_callback);
363        }
364
365        delete $form->{tag_ids} unless defined $self->site_tags;
366        delete $form->{tag_ids} if '' eq $self->site_tags;
367
368        $result = $self->uagent->post(
369            $self->urlbase.'/ws.php?format=json',
370            $form
371        );
372
373        eval {
374            $content = from_json(
375                $result->content
376            );
377        };
378
379   
380        $status = $result->is_success;
381        $status_line = $result->status_line; 
382
383        last;
384    }
385   
386    return ( $status,  $status_line, $content);
387}
388 
389
390sub AddCategories{
391    my ( $self, $name, $parentid ) = @_;
392
393    my $form = {
394        method            => 'pwg.categories.add',
395        name              => $name,
396        parent            => $parentid,
397       
398    };
399
400    my $result = $self->uagent->post(
401        $self->urlbase.'/ws.php?format=json',
402        $form
403    );
404
405    my $content = {};
406        eval {
407            $content = from_json(
408                $result->content
409            );
410        };
411
412    return ( $result->is_success, $result->status_line, $content );
413       
414}
415
416sub SetInfoCategories{
417    my ( $self, $name, $comment, $parentid ) = @_;
418
419    my $form = {
420        method            => 'pwg.categories.setInfo',
421        name              => $name,
422        comment           => $comment,
423        category_id       => $parentid,
424       
425    };
426
427    my $result = $self->uagent->post(
428        $self->urlbase.'/ws.php?format=json',
429        $form
430    );
431
432    my $content = {};
433        eval {
434            $content = from_json(
435                $result->content
436            );
437        };
438
439    return ( $result->is_success, $result->status_line, $content );
440       
441}
442
443
444sub send_chunks {
445    my ( $self, $params ) = @_;
446
447    my $content = read_file(
448        $params->{filepath},
449        binmode => ':raw',
450    );
451
452    my $content_length = length($content);
453    my $nb_chunks = ceil($content_length / $self->chunk_size);
454
455    my $chunk_pos = 0;
456    my $chunk_id = 1;
457    while ($chunk_pos < $content_length) {
458        my $chunk = substr(
459            $content,
460            $chunk_pos,
461            $self->chunk_size
462        );
463        $chunk_pos += $self->chunk_size;
464
465        my $response = $self->uagent->post(
466            $self->urlbase.'/ws.php?format=json',
467            {
468                method       => 'pwg.images.addChunk',
469                data         => encode_base64($chunk),
470                original_sum => $params->{original_sum},
471                position     => $chunk_id,
472                type         => $params->{type},
473            }
474        );
475        $params->{yield_callback}->() if 'CODE' eq ref($params->{yield_callback});
476        $params->{ok} = 1;
477        if ($response->code != 200) {
478            printf("response code    : %u\n", $response->code);
479            printf("response message : %s\n", $response->message);
480            $params->{ok} = 0;
481            $params->{message} = $response->message;
482            $params->{code} = $response->code;
483            last;
484        }
485
486        $chunk_id++;
487    }
488}
489
490 
4911;
492   
Note: See TracBrowser for help on using the repository browser.