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

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

Feature 1055 added : preparation of high definition images ( HD ).

  • Property svn:eol-style set to LF
File size: 13.5 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 File::Spec;
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           sum_high_file
64           sum_resized_file
65           sum_thumb_file
66           sum_original_file
67      / 
68);
69
70$|=1;
71
72sub Init {
73    my ( $self, $version ) = @_ ;
74 
75    $self->uagent(
76        LWP::UserAgent->new(
77            agent => sprintf("Mozilla/pLoader %s", $version)       
78        )
79    );
80   
81    $self->uagent->cookie_jar({});     
82
83    $self->urlbase(
84        $self->{site_url}
85    );
86   
87    $self->username(
88        $self->{site_username}
89    );
90   
91    $self->password(
92        $self->{site_password}
93    );
94   
95    $self->chunk_size(
96        $self->{chunk_size}
97    );
98
99   
100    $self->uagent->default_headers->authorization_basic(
101        $self->{http_username}||$self->username, 
102        $self->{http_password}||$self->password
103    );
104   
105   
106    $self->qry_list_categories( sprintf
107        "%s/ws.php?format=json&method=%s&recursive=%s",
108        $self->urlbase,
109#        'pwg.categories.getAdminList',
110        'pwg.categories.getList',
111        'true',
112    );
113
114    $self->qry_list_tags( sprintf
115        "%s/ws.php?format=json&method=%s",
116        $self->urlbase,
117        'pwg.tags.getAdminList',
118    );
119
120
121    my $form = {
122        method => 'pwg.session.login',
123        username => $self->username,
124        password => $self->password,
125    };
126 
127    $self->uagent_response(
128        $self->uagent->post(
129            $self->urlbase.'/ws.php?format=json',
130            $form
131        )
132    );
133   
134    my $hresult = {} ;
135
136    if($self->uagent_response->is_success){
137        eval {
138            $hresult = from_json(
139                $self->uagent_response->content
140            );
141        };
142    }
143    else{
144        $hresult = {
145            'message' => $self->uagent_response->message,
146            'stat'    => 'fail',
147        };
148    }
149
150    $self->login_result(
151        $hresult
152    );
153
154}
155
156sub GetCategories {
157    my ( $self ) = @_;
158
159    my $result;
160    eval {
161        $result = $self->uagent->get(
162            $self->qry_list_categories
163        );
164    };
165
166    if($@){
167        printf("An error occured in query execution %s\n%s",
168            $self->qry_list_categories,
169            $@,
170        );     
171    }
172    my $hresult;
173   
174    eval {
175        $hresult = from_json(
176            $result->content
177        );
178    };
179   
180    $hresult ||= {};
181
182    my $categories = $hresult->{result}{categories};
183
184    $categories;       
185}
186
187sub GetTags {
188    my ( $self ) = @_;
189
190    my $result;
191    eval {
192        $result = $self->uagent->get(
193            $self->qry_list_tags
194        );
195    };
196
197    if($@){
198        printf("An error occured in query execution %s\n%s",
199            $self->qry_list_tags,
200            $@,
201        );     
202    }
203    my $hresult;
204   
205    eval {
206        $hresult = from_json(
207            $result->content
208        );
209    };
210   
211    $hresult ||= {};
212
213    $hresult->{result}{tags};
214}
215
216sub AddTags {
217    my ( $self, $name ) = @_;
218
219    my $form = {
220        method            => 'pwg.tags.add',
221        name              => $name,
222       
223    };
224
225    my $result = $self->uagent->post(
226        $self->urlbase.'/ws.php?format=json',
227        $form
228    );
229
230    my $content = {};
231        eval {
232            $content = from_json(
233                $result->content
234            );
235        };
236
237    return ( $result->is_success, $result->status_line, $content );
238       
239} 
240
241
242sub UploadImage {
243    my ( $self, $progress ) = @_;
244
245    $self->sum_resized_file(
246        $self->_checksum(
247            $self->site_resized_file,
248            $progress
249        )
250    );
251
252    $self->sum_thumb_file(
253        $self->_checksum(
254            $self->site_thumb_file,
255            $progress
256        )
257    );
258 
259    $self->sum_high_file(
260        $self->_checksum(
261            $self->site_high_file,
262            $progress
263        )
264    );
265    # is the same in pLoader but may be different
266    $self->sum_original_file(
267        $self->sum_high_file
268    );
269
270
271    my $site_image_name = $self->site_image_name; 
272
273    my $image_id = $self->_exists($self->sum_original_file);;
274    my $status = 0;
275    my $status_line = "An error has occured during upload.";
276    my $content = {};
277    my $doubleCheck;
278    my $form;
279    while(1){
280        if(!defined($image_id)){
281               
282            my $resized_params = $self->_send_chunks('file', $progress);
283            $status_line = $resized_params->{message};
284            last if !$resized_params->{ok};
285         
286            my $thumb_params = $self->_send_chunks('thumb', $progress);
287            $status_line = $thumb_params->{message};
288            last if !$thumb_params->{ok};
289       
290            $form = {
291                method            => 'pwg.images.add',
292                original_sum      => $self->sum_original_file,
293                file_sum          => $self->sum_resized_file,
294                thumbnail_sum     => $self->sum_thumb_file,
295                categories        => $self->categories,
296                name              => $site_image_name,
297                rank              => $self->rank,
298                author            => $self->site_author,
299                comment           => $self->site_comment,
300                date_creation     => $self->site_img_date_creation,
301                tag_ids           => $self->site_tags,
302               
303            };
304   
305            if($self->upload_high){
306                my $high_params = $self->_send_chunks('high', $progress);
307                $status_line = $high_params->{message};
308                last if !$high_params->{ok};
309                                # high is a HD resized copy of original
310                                $form->{high_sum} = $self->sum_high_file;
311            }
312            $doubleCheck = 1;
313        }
314        else {
315            $form = {
316                method            => 'pwg.images.setInfo',
317                image_id          => $image_id,
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            $progress->{yield}->();
327        }
328
329        delete $form->{tag_ids} unless defined $self->site_tags;
330        delete $form->{tag_ids} if '' eq $self->site_tags;
331
332        $progress->{yield}->();
333        my $result = $self->uagent->post(
334            $self->urlbase.'/ws.php?format=json',
335            $form
336        );
337        eval {
338            $content = from_json(
339                $result->content
340            );
341        };
342
343   
344        $status = $result->is_success;
345        $status_line = $result->status_line; 
346
347        if($doubleCheck){
348            $content->{stat} = 'fail' if !$self->_exists($self->sum_original_file); 
349        }
350
351        last;
352    }
353   
354    return ( $status,  $status_line, $content);
355}
356
357sub _exists {
358    my ( $self, $md5_sum ) = @_;
359
360    my $form = {
361        method            => 'pwg.images.exist',
362        md5sum_list       => $md5_sum,
363    };
364
365    my $result = $self->uagent->post(
366        $self->urlbase.'/ws.php?format=json',
367        $form
368    );
369
370    my $hresult = {};
371    eval {
372        $hresult = from_json(
373            $result->{_content}
374        );
375    };
376    my $id;
377    $id = $hresult->{result}{$self->sum_original_file} if 'ok' eq $hresult->{stat};
378   
379    $id;
380} 
381
382sub _checksum {
383    my ( $self, $file, $progress ) = @_;
384    my $file_sum;
385
386    my $yield = $progress->{yield};
387
388    $yield->();
389    $progress->{msg_details}->(
390        sprintf(
391            "%s : %s", 
392            $progress->{checksum_msg}, 
393            $file
394        )
395    );
396    eval {
397        $file_sum = file_md5_hex(
398            $file
399        );
400    };
401    $yield->();
402
403    $file_sum;
404}
405
406sub _send_chunks {
407    my ( $self, $type, $progress ) = @_;
408
409    my $msg = {
410        thumb=>'thumbnail_msg',
411        file=>'resized_msg',
412        high=>'highdef_msg',
413    };
414
415    my $filepath = {
416        thumb=>$self->site_thumb_file,
417        file=>$self->site_resized_file,
418        high=>$self->site_high_file,
419    };
420
421    $progress->{current_msg} = $progress->{$msg->{$type}};
422    $progress->{yield}->();
423
424    my $params = {
425         filepath      => $filepath->{$type},
426         type          => $type,
427         original_sum  => $self->sum_original_file,
428    };
429
430    $self->send_chunks(
431       $params,
432       $progress,
433    );
434    $progress->{yield}->();
435
436    $params;
437}
438
439sub AddCategories{
440    my ( $self, $name, $parentid ) = @_;
441
442    my $form = {
443        method            => 'pwg.categories.add',
444        name              => $name,
445        parent            => $parentid,
446       
447    };
448
449    my $result = $self->uagent->post(
450        $self->urlbase.'/ws.php?format=json',
451        $form
452    );
453
454    my $content = {};
455        eval {
456            $content = from_json(
457                $result->content
458            );
459        };
460
461    return ( $result->is_success, $result->status_line, $content );
462       
463}
464
465sub SetInfoCategories{
466    my ( $self, $name, $comment, $parentid ) = @_;
467
468    my $form = {
469        method            => 'pwg.categories.setInfo',
470        name              => $name,
471        comment           => $comment,
472        category_id       => $parentid,
473       
474    };
475
476    my $result = $self->uagent->post(
477        $self->urlbase.'/ws.php?format=json',
478        $form
479    );
480
481    my $content = {};
482        eval {
483            $content = from_json(
484                $result->content
485            );
486        };
487
488    return ( $result->is_success, $result->status_line, $content );
489       
490}
491
492
493sub send_chunks {
494    my ( $self, $params, $progress ) = @_;
495
496    my $yield = $progress->{yield};
497    my ( $vol, $dir, $filename ) = File::Spec->splitpath($params->{filepath});
498
499    $yield->();
500    $progress->{bar}->(0);
501    $yield->();
502    $progress->{msg_details}->(
503        sprintf(
504            "%s : %s", 
505            $progress->{current_msg}, 
506            $filename
507        )
508    );
509
510
511    $yield->();
512    my $content = read_file(
513        $params->{filepath},
514        binmode => ':raw',
515    );
516    $yield->();
517
518    my $content_length = length($content);
519    my $nb_chunks = ceil($content_length / $self->chunk_size);
520
521    my $chunk_pos = 0;
522    my $chunk_id = 1;
523
524
525    while ($chunk_pos < $content_length) {
526
527        my $chunk = substr(
528            $content,
529            $chunk_pos,
530            $self->chunk_size
531        );
532        $chunk_pos += $self->chunk_size;
533        my $response = $self->uagent->post(
534            $self->urlbase.'/ws.php?format=json',
535            {
536                method       => 'pwg.images.addChunk',
537                data         => encode_base64($chunk),
538                original_sum => $params->{original_sum},
539                position     => $chunk_id,
540                type         => $params->{type},
541            }
542        );
543        $yield->();
544        $progress->{bar}->(100*($chunk_pos/$content_length));
545        $progress->{msg_details}->(
546            sprintf(
547                "%s : %s", 
548                $progress->{current_msg}, 
549                $filename
550            )
551        );
552        $params->{ok} = 1;
553        if ($response->code != 200) {
554            printf("response code    : %u\n", $response->code);
555            printf("response message : %s\n", $response->message);
556            $params->{ok} = 0;
557            $params->{message} = $response->message;
558            $params->{code} = $response->code;
559            last;
560        }
561
562        $chunk_id++;
563    }
564}
565
566 
5671;
568   
Note: See TracBrowser for help on using the repository browser.