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

Last change on this file since 4121 was 4121, checked in by ronosman, 14 years ago

Bug 1213 fixed. Accented characters in file and path names make pLoader Linux crash.

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