source: extensions/pLoader/trunk/src/Uploader/ImageList.pm @ 4585

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

Bug fixed : wrong file name when uploading HD copy of original

  • Property svn:eol-style set to LF
File size: 34.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::ImageList;
21use strict;
22use Carp;
23use base qw/Uploader::Object/;
24use Image::ExifTool qw(:Public);
25use Image::Magick;
26use File::Spec;
27use Uploader::Image;
28use Data::Dumper;
29use Storable;
30use Digest::MD5::File qw/file_md5_hex md5_hex/;
31use Wx::Locale qw/:default/;
32use Wx;
33
34# this class implements a collection of image files with associated data
35$|=1;
36__PACKAGE__->mk_accessors( 
37    qw/
38                thumb_size
39                preview_ratio
40                categories
41                type
42                filter
43                blur
44                quality
45                resize_w
46                resize_h
47                hd_filter
48                hd_blur
49                hd_quality
50                hd_w
51                hd_h
52                hd_interlace
53                prefix
54                author
55                count
56                new_files
57                storable_file
58                wx_thumb_size
59                current_image
60                images
61                image_selection
62                exif_metadata
63                wx_thumb_imglist
64                wx_thumb_dir
65                site_resized_dir
66                site_thumb_dir
67                userdata_dir
68                progress_msg
69                last_error_msg
70                default_photo_name
71                default_photo_name_method
72                default_name_prefix
73                SetNewFilesViewerRefreshCallback
74                SetNewFilesProgressCallback
75                SetNewFilesDisplayEndInfoCallback
76                YieldCallback
77                UploadImagesViewerCallback
78                progress_thumbnail_refresh
79                progress_msg_details_refresh
80                progress_msg_refresh
81                progressbar_refresh
82                progress_endinfo_refresh
83                RescaleCallback
84                ResizeCallback
85                upload_rejects
86                pwg
87                upload_high
88                upload_hd
89                remove_uploaded_from_selection
90                wx_quality
91                th_quality
92                auto_rotate
93                interlace
94                create_resized
95                use_exif_preview
96                image_sums
97                upload_image_sums
98                sums
99                version
100                imagelist_version
101                uploaded_images
102                watermark_activate
103                watermark_activate_pwg_high
104                watermark_text
105                watermark_text_size
106                watermark_position
107                watermark_y
108                watermark_x
109                watermark_color
110                gravity
111                rgbcolor
112                upload_msg
113                upload_selection_count
114                upload_uploaded_count
115                upload_rejected_count
116                upload_last_error
117                upload_error_content
118                upload_begin_time
119                upload_end_time
120                upload_duration
121                upload_file
122                upload_name
123                ReuploadCallback
124                reupload_action_files
125                reupload_action_properties
126                reupload_action_properties_m
127                reupload_not_ask
128                display_mode
129     /
130);
131
132
133sub Init {
134    my ( $self ) = @_;
135   
136    $self->uploaded_images([]);
137    $self->gravity(
138        { 
139            'Top'          => 'North',
140            'Left'         => 'West',
141            'Right'        => 'East',
142            'Bottom'       => 'South',
143            'Top left'     => 'NorthWest',
144            'Top right'    => 'NorthEast',
145            'Bottom left'  => 'SouthWest',
146            'Bottom right' => 'SouthEast',
147            'Center'       => 'Center',
148       }   
149    );   
150
151    $self->rgbcolor(
152        {
153            "White" => '#FFFFFF',
154            "Black" => '#000000',
155        }   
156    );
157   
158}
159
160sub _set_exif_tag {
161    my ( $self, $file, $tag, $newValue ) = @_; 
162
163  my $options = {};
164  # Create a new Image::ExifTool object
165  my $exifTool = new Image::ExifTool;
166
167  # Extract meta information from an image
168  $exifTool->ExtractInfo($file, $options);
169
170  # Set a new value for a tag
171  $exifTool->SetNewValue($tag, $newValue);
172
173  # Write new meta information to a file
174  $exifTool->WriteInfo($file);
175
176}
177
178
179sub _set_current_image_filepaths {
180    my ( $self ) = @_;
181
182    my $filename = sprintf(
183        "%s.%s",
184        $self->current_image->file_sum,
185        $self->type,
186    );
187
188
189    $self->current_image->wx_thumb_file( 
190        File::Spec->catfile(
191            $self->wx_thumb_dir,
192            $filename
193        )
194    );
195
196    $self->current_image->site_thumb_file( 
197        File::Spec->catfile(
198            $self->site_thumb_dir,
199            $filename
200        )
201    );
202
203}
204
205
206sub SetCurrentImage {
207    my ( $self, $indx ) = @_;   
208
209    $self->current_image(
210        $indx != -1 ? $self->GetImage($indx) : Uploader::Image->new()
211    );
212}
213
214
215sub SetNewFiles {
216    my ( $self, $files ) = @_;
217
218    $self->new_files( $files );
219
220    # if some files have been previously selected
221    my $i = scalar @{$self->sums};
222    #printf("SetNewFiles %s\n", $i);
223    my $count = 0;
224    $self->count($count);
225    my $errors = 0;
226
227    map {
228        my $info = $self->_read_exif_metatdata($_->{ANSIPathName});
229        my $is_new_image = $self->_add_image($_, $info, $i);   
230        $self->SetCurrentImage($i);
231        $self->_set_current_image_filepaths();
232
233        if($is_new_image){
234            #my $use_wx_resize = $self->_create_gui_preview($info);
235            $self->_create_gui_thumbnail();
236
237            # ok
238            if(!$@){
239                $self->progress_msg(gettext("Selection thumbnail created for %s"));
240            }
241            else {
242                $self->progress_msg("An error has occured when processing %s\n$@");
243                # remove from list
244                splice @{$self->sums}, $i, 1;
245                $errors++;
246            }
247       
248            $self->SetNewFilesProgressCallback->();
249        }
250        $i++;
251        $count++;
252        $self->count($count);
253        $self->SetNewFilesViewerRefreshCallback->();
254    }
255    @{$files};
256    $self->SetNewFilesDisplayEndInfoCallback->(
257        sprintf(
258            "%s : %s\n\n%s : %s",
259            gettext("photos added to the selection"),
260            $self->count,
261            gettext("errors"),
262            $errors,
263           
264        )
265    );
266   
267    $self->Store;
268   
269}
270
271sub _read_exif_metatdata {
272    my ( $self, $file ) = @_;
273   
274    # read exif metadata
275    my $info;
276    eval {
277        $info = ImageInfo( $file );
278    };
279    $info = {} if($@);
280   
281    $info;
282}
283
284# key is file path
285sub _add_image {
286    my ( $self, $file, $info, $i ) = @_;       
287
288    my $is_new_image;
289
290    # for legacy imagelist that do not have image_sums property
291    $self->image_sums(
292        {}
293    ) if !$self->image_sums;
294
295    my $sum = file_md5_hex($file->{ANSIPathName});
296
297    my $image;
298    if ( !exists $self->image_sums->{$sum} ){
299        #print "_add_image ", Dumper $file, "\n";
300        # append to image list
301        $image = Uploader::Image->new(
302        {
303                file              => $file->{ANSIPathName},
304                file_sum          => $sum,
305                site_name         => $self->_default_photo_name($file->{PathName}, $info, $i),
306                site_author       => $self->author,
307                exif_metadata     => $self->_select_exif_data($info),
308                add_rank          => $i,
309                site_categories   => [],
310                site_tags         => [],
311                site_high_file    => $file->{ANSIPathName},
312            }
313        );
314
315        $self->image_sums->{$sum} = $image ;
316        $is_new_image = 1;
317    } else {
318        $image = $self->image_sums->{$sum};
319    }
320
321       
322    $self->sums->[$i] = $sum ;
323
324    $is_new_image;
325}
326
327
328sub _default_photo_name {
329    my ( $self, $file, $info, $i ) = @_;
330   
331   
332    my $name;
333    my $create_date = $info->{CreateDate};
334    my $ext;
335    my ( $vol, $path, $filename ) = File::Spec->splitpath($file);
336    ( $filename, $ext ) = split /\.\w+$/, $filename;
337   
338    my ( $yyyy, $mm, $dd, $hh, $mi, $ss ) = split /[:\s]/, $create_date ;
339 
340    my $chrono = join('', $yyyy, $mm, $dd);
341    if('Prefix' eq $self->default_photo_name){
342        $name = $self->default_name_prefix
343    }
344    elsif('File name' eq $self->default_photo_name){
345        $name = $filename
346    }
347    elsif('File path and name' eq $self->default_photo_name){
348        $name = sprintf(
349            "%s", 
350            File::Spec->catfile($path, $filename), 
351        )       
352    }   
353    elsif('Prefix + rank number' eq $self->default_photo_name){
354        $name = sprintf(
355            "%s%s", 
356            $self->default_name_prefix, 
357            1+$i,
358        )       
359    }   
360    elsif('Rank number + prefix' eq $self->default_photo_name){
361        $name = sprintf(
362            "%s%s", 
363            1+$i,
364            $self->default_name_prefix, 
365        )       
366    }   
367    elsif('Prefix + create date chrono' eq $self->default_photo_name){
368        $name = sprintf(
369            "%s%s", 
370            $self->default_name_prefix, 
371            $chrono,
372        )       
373    }   
374    elsif('Create date chrono + prefix' eq $self->default_photo_name){
375        $name = sprintf(
376            "%s%s", 
377            $chrono,
378            $self->default_name_prefix, 
379        )       
380    }
381
382    $name;
383}
384
385
386sub _create_gui_thumbnail {
387    my ( $self ) = @_;
388
389     eval {
390        printf("create gui thumbnail\n");
391        # use the preview image to create a gui display thumbnail
392        if(!$self->CreateGUIThumbnail())
393        {
394            print "CreateGUIThumbnail failed, use callback\n";
395            $self->ResizeCallback->(
396                $self->current_image->file,
397                $self->current_image->wx_thumb_file,
398                $self->type,
399                $self->wx_thumb_size,
400                $self->wx_thumb_size,
401                $self->wx_quality,
402            );
403               
404        }
405     };
406}
407
408sub RemoveImageSelection {
409    my ( $self ) = @_;
410   
411    return if (! scalar @{$self->sums} );
412    return if (! defined $self->image_selection );
413   
414    $self->_remove_image_list($self->image_selection);
415    # clear image selection
416    $self->image_selection([]);
417}
418
419sub _remove_image_list {
420    my ( $self, $list ) = @_;
421
422    # higher first, to keep same indexes during remove
423    my @images = reverse @$list;     
424    map {
425        $self->DeleteImage($_);
426        splice @{$self->sums}, $_, 1 ;
427        $self->wx_thumb_imglist->Remove($_);
428        shift @images;
429    }
430    @images;
431}
432
433sub RemoveImage {
434    my ( $self, $index ) = @_;
435
436    return if (! defined $self->image_selection );
437    return if (! defined $index );
438       
439    $self->DeleteImage($index);
440    splice @{$self->sums}, $index, 1 ;
441    $self->wx_thumb_imglist->Remove($index);
442       
443}
444
445# used for display in GUI. has to fit a square box ( wxImageList )
446sub CreateGUIThumbnail {
447    my ( $self ) = @_;
448
449#    return 1 if( -e $self->current_image->wx_thumb_file );
450    my $rval = 0;
451    print "CreateGUIThumbnail ", $self->current_image->wx_thumb_file, "\n";
452    my $image = new Image::Magick;
453
454    my $size = $self->wx_thumb_size||100;
455
456    my $status = $image->Set(size=>sprintf("%sx%s", 2*$size, 2*$size));
457    warn "$status" if $status ;
458
459    $status = $image->ReadImage(
460        $self->current_image->file
461    );
462    warn "$status" if $status;
463    return $rval if $status;
464
465    $self->current_image->width(
466        $image->Get('width')
467    );
468    $self->current_image->height(
469        $image->Get('height')
470    );
471
472
473        # maximize size and keep aspect ratio
474    $status = $image->Thumbnail(
475        geometry=>sprintf("%s%s>", $size*$size, '@')
476    );
477    # to get adjusted to a square box
478    #$status = $image->Thumbnail(
479    #    geometry=>sprintf("%sx%s%s", $size, $size, '^')
480    #);
481    warn "$status" if $status;
482    return $rval if $status;
483
484#    causes strange behaviour with i18n -> yellow borders when local is other than EN
485#    $status = $image->Set(background=>"white");
486#    warn "$status" if $status ;
487
488    $status = $image->Set(Gravity=>"Center");
489    warn "$status" if $status ;
490
491    $image->Extent(
492        geometry=>sprintf("%sx%s", $size, $size),
493        gravity=>'center',
494    );
495       
496    $image->Set(
497        quality=>$self->wx_quality||90
498    );
499
500    $status = $image->Strip();
501    warn "$status" if $status ;
502
503    # exif from original image
504    my $orientation = $self->current_image->exif_metadata->{Orientation};
505   
506    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
507    if( $orientation =~ m/Rotate (\d+)/ ){
508        printf(
509            "Rotate %s\n",
510            $1
511        );
512   
513        $image->Rotate( degrees=>$1 ) if $self->auto_rotate;   
514    }
515   
516
517    $image->Write(
518        sprintf(
519            "%s:%s",
520            $self->type,
521            $self->current_image->wx_thumb_file,
522        )
523    );
524
525    undef $image;
526   
527    $rval = 1;
528   
529    return $rval;
530}
531
532
533
534
535sub CreateResized {
536    my ( $self ) = @_;
537   
538    my $rval = 1 ;
539    #return $rval if( -e $self->current_image->site_resized_file );
540
541    printf(
542        "Create resized %s\n",
543        $self->current_image->file,
544    );     
545
546    my $image = new Image::Magick;
547
548    my $status = $image->ReadImage(
549        $self->current_image->file
550    );
551    warn "$status" if $status ;
552    return 0 if $status;
553
554    my $w = $image->Get('width');
555    my $h = $image->Get('height');
556       
557    # should calculate the aspect ratio
558    my $resize_w = $self->resize_w;
559    my $resize_h = $self->resize_h;
560       
561    if( $w < $h ){
562        my $resize_w_ = $resize_w;
563        $resize_w = $resize_h;
564        $resize_h = $resize_w_;
565    }
566    #printf("resize with blur value %s\n", $self->blur);
567    $status = $image->Resize(
568        geometry => sprintf("%sx%s>", $resize_w, $resize_h), 
569        filter => sprintf("%s", $self->filter), 
570        blur => $self->blur
571    );
572    warn "$status" if $status ;
573    return 0 if $status;
574
575    $status = $image->Set(Gravity=>"Center");
576    warn "$status" if $status ;
577
578    # exif from original image
579    my $orientation = $self->current_image->exif_metadata->{Orientation};
580   
581    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
582    if( $orientation =~ m/Rotate (\d+)/ ){
583        printf(
584            "Rotate %s\n",
585            $1
586        );
587   
588        $image->Rotate( degrees=>$1 ); 
589    }
590
591    #printf("resize with quality value %s\n", $self->quality);
592    $status = $image->Set(quality=>$self->quality);
593    warn "$status" if $status ;
594
595    $status = $image->Set(interlace=>$self->interlace);
596    warn "$status" if $status ;
597
598    $image->Write(
599        sprintf(
600            "%s:%s",
601            $self->type,
602            $self->current_image->site_resized_file,
603        )
604    );
605    warn "$status" if $status ;
606    return 0 if $status;
607   
608    undef $image;
609
610   
611    $rval = 0 if $status;
612
613    return $rval;
614}
615
616sub CreateThumbnail {
617    my ( $self ) = @_;
618   
619    #return 1 if( -e $self->current_image->site_thumb_file );
620   
621    my $rval = 1;
622
623    my $image = new Image::Magick;
624
625    my $status = $image->ReadImage(
626        $self->current_image->site_resized_file
627    );
628    warn "$status" if $status ;
629
630   
631    $status = $image->Resize(
632        geometry => sprintf(
633                                "%sx%s>", 
634                                $self->thumb_size, 
635                                $self->thumb_size
636                           ),
637    );
638    warn "$status" if $status ;
639
640    $status = $image->Set(Gravity=>"Center");
641    warn "$status" if $status ;
642
643    $status = $image->Set(quality=>$self->th_quality);
644    warn "$status" if $status ;
645
646    $status = $image->Strip();
647    warn "$status" if $status ;
648
649
650    $image->Write(
651        sprintf(
652            "%s:%s",
653            $self->type,
654            $self->current_image->site_thumb_file,
655        )
656    );
657   
658    undef $image;
659
660
661    $rval = 0 if $status;
662
663    return $rval;
664}
665
666
667
668sub _select_exif_data {
669    my ( $self, $exif ) = @_;
670
671    return {
672        map {
673            $_ => $exif->{$_},
674        }
675        qw/
676            CreateDate
677            ImageWidth
678            ImageHeight
679            Orientation
680            DateTimeOriginal
681            ISO
682            ExposureTime
683            ApertureValue
684            FocalLength
685            Lens
686            Exposure
687            Make
688            Model
689        /
690    };   
691}
692
693sub Store {
694    my ( $self ) = @_;
695   
696    my $data = $self->get_storable(
697        [ 
698            qw/
699                images
700                thumb_size
701                preview_ratio
702                type
703                filter
704                blur
705                quality
706                wx_quality
707                th_quality
708                prefix
709                author
710                count
711                resize_w
712                resize_h
713                hd_filter
714                hd_blur
715                hd_quality
716                hd_w
717                hd_h
718                                hd_interlace
719                new_files
720                storable_file
721                wx_thumb_size
722                current_image
723                exif_metadata
724                wx_thumb_dir
725                site_resized_dir
726                site_thumb_dir
727                userdata_dir
728                progress_msg
729                default_photo_name
730                default_name_prefix
731                upload_high
732                                upload_hd
733                remove_uploaded_from_selection
734                auto_rotate
735                interlace
736                create_resized
737                use_exif_preview
738                image_sums
739                sums
740                version
741                imagelist_version
742                watermark_activate
743                watermark_activate_pwg_high
744                watermark_text
745                watermark_text_size
746                watermark_position
747                watermark_y
748                watermark_x
749                watermark_color
750                                reupload_action_files
751                                reupload_action_properties
752                                reupload_action_properties_m
753                                display_mode
754            /
755        ] 
756   
757    );
758    eval {
759        store $data, $self->storable_file;
760    };
761    if($@){
762        print $@, "\n"; 
763    }
764}
765
766
767
768sub UploadSelection {
769    my ( $self ) = @_; 
770
771    my $viewer_callback = $self->UploadImagesViewerCallback ;
772
773    $self->image_selection([]) if !defined $self->image_selection;
774    $self->upload_rejects(
775        []
776    );
777
778    $self->count(
779        1
780    );
781
782    $self->upload_uploaded_count(0);
783    $self->upload_rejected_count(0);
784    $self->upload_begin_time(time);
785    $self->upload_selection_count(scalar @{$self->image_selection});
786        # for re-upload management
787    $self->upload_image_sums( [
788                map { $self->GetImage($_)->file_sum }
789                    @{$self->image_selection}
790            ] 
791        );
792
793        # check if already exist on server
794        my $uploaded = $self->pwg->IsAlreadyUploaded($self->upload_image_sums);
795        my @already_uploaded = grep { $_ } values %$uploaded ; 
796        $self->ReuploadCallback->() if ( scalar @already_uploaded and !$self->reupload_not_ask );
797
798       
799    foreach(@{$self->image_selection}) {
800        # current image object         
801        $self->current_image(
802            $self->GetImage($_)
803        ); 
804        # prepare resized, high, thumbnail
805                # if not already uploaded
806        $self->_set_site_resized_file();
807        $self-> _set_site_high_file ();
808        # photo metadata
809        $self->_upload_selection_prepare() if (!$uploaded->{$self->current_image->file_sum} or $self->reupload_action_files);
810        $self->_prepare_upload_properties();           
811
812        # transfert resized, high, thumbnail to site
813        my $status = $self->_upload_selection_transfert();
814        # log operations
815        $self->_upload_selection_log($status);
816        $self->count(
817            1+$self->count
818        );
819    }
820
821    if($self->remove_uploaded_from_selection){
822        $self->_remove_image_list($self->uploaded_images);
823        $viewer_callback->();
824    }
825
826    $self->_upload_selection_final_log();
827}
828
829sub _upload_selection_prepare {
830    my ( $self ) = @_;
831
832    $self->progress_thumbnail_refresh->();
833    # PREPARE
834    $self->_set_upload_msg(gettext("Preparing resized image for"));
835    $self->_upload_progress();
836    #printf("resized %s\n", $self->create_resized);
837    if( $self->create_resized ){
838        $self->_create_site_resized_file();
839        $self->_set_upload_msg(gettext("Resized image done for"));
840        $self->_upload_progress();
841    }
842    # the original is at the right size, no need to create a resize
843    else {
844        #printf("original no resized %s\n", $self->create_resized);
845        $self->current_image->site_resized_file(
846            $self->current_image->file,
847        );
848    }
849
850        my $decode = {
851        'No' => 0,
852            'Yes, use HD resized of the original photo' => 'HD',
853            'Yes, use a copy of the original photo' => 'ORIGINAL',
854    }; 
855    #printf("upload HD %s\n", $self->upload_hd);
856        $self->upload_high(
857            $decode->{$self->upload_hd}
858        );
859    #printf("upload High %s\n", $self->upload_high);
860       
861    # if upload high, rotate a copy of original file
862    if($self->upload_high){
863        $self->CreateHigh();
864        $self->_set_upload_msg(gettext("HD image done for"));
865        $self->_upload_progress();
866    }
867
868    eval {
869        $self->CreateThumbnail();
870    };
871    $self->_set_upload_msg(gettext("Thumbnail image done for"));
872    $self->_upload_progress();
873
874
875}
876
877sub _upload_progress {
878    my ( $self, $value ) = @_;
879
880    eval {
881        $self->progress_msg_refresh->(
882            $self->upload_msg
883        );
884        # set current image thumbnail
885        # update upload progress dialog
886        #$self->progressbar_refresh->($value);
887    };
888    # user cancelled : dialog box is destroyed
889    croak gettext("Upload cancelled"), " .", $@ if $@ ;
890
891
892}
893
894sub _set_upload_msg {
895    my ( $self, $msg, $errmsg ) = @_;
896
897    $self->upload_msg(
898        sprintf(
899            "%s : %s - %s\n\n%s %s %s %s\n%s",
900            $msg,
901            $self->upload_file,
902            $self->upload_name,
903            gettext("Photo"),
904            $self->count,
905            gettext("on"),
906            $self->upload_selection_count,
907            $errmsg
908        )
909    );
910}
911
912sub _upload_selection_transfert {
913    my ( $self ) = @_;
914
915    $self->_set_upload_msg(gettext("Uploading"));
916    $self->_upload_progress(0);
917
918    # UPLOAD
919    my ( $status, $status_msg, $content ) = $self->pwg->UploadImage(
920        { 
921            yield=>$self->YieldCallback, 
922            bar=>$self->progressbar_refresh, 
923            msg=>$self->progress_msg_refresh,
924            msg_details=>$self->progress_msg_details_refresh,
925            resized_msg=>gettext("Uploading resized"),
926            thumbnail_msg=>gettext("Uploading thumbnail"),
927            highdef_msg=>gettext("Uploading high definition"),
928            checksum_msg=>gettext("Checksum for"),
929            original_sum=>$self->current_image->file_sum,
930        } 
931    );
932    my $ok = 0;
933    # HTTP REQUEST OK
934    if ( $status ){
935        # PIWIGO RESULT ( HTTP may be ok while Piwigo is not )
936        $ok = 'fail' eq $content->{stat} ? 0 : 1;
937    }
938    else{
939        Wx::LogMessage(
940            "%s %s : %s",
941            gettext("Communication error with"),
942            $self->pwg->site_url,
943            $status_msg,
944        );
945    }
946    $self->upload_last_error(
947        $status_msg
948    );
949
950    $self->upload_error_content(
951        $content
952    );
953
954    $ok;
955}
956
957sub _upload_selection_log {
958    my ( $self, $ok ) = @_;
959
960    if($ok){
961        $self->_set_upload_msg(gettext("Uploaded"));
962        $self->_upload_progress(0);
963        push @{$self->uploaded_images}, $_;
964        $self->upload_uploaded_count(
965            1+$self->upload_uploaded_count       
966        );
967    } else {
968        $self->_set_upload_msg(gettext("An error has occured"), Dumper($self->upload_error_content));
969        $self->upload_rejected_count(
970            1+$self->upload_rejected_count
971        );
972    }   
973       
974}
975
976sub _upload_selection_final_log {
977    my ( $self ) = @_;
978
979    $self->upload_end_time(time);
980    $self->upload_duration(
981        $self->upload_end_time - $self->upload_begin_time
982    );
983
984    $self->progress_endinfo_refresh->(
985        sprintf(
986            "%s : %s\n\n%s : %s\n\n%s : %s\n\n\n%s : %s %s",
987            gettext("images processed"),
988            $self->count - 1,
989            gettext("images uploaded"),
990            $self->upload_uploaded_count,
991            gettext("images in errors and not uploaded"),
992            $self->upload_rejected_count,
993            gettext("Duration"),
994            $self->upload_duration,
995            gettext("seconds"),
996        )
997    );
998}
999
1000sub _set_site_resized_file {
1001    my ( $self ) = @_;
1002
1003    my ( $vol, $dir, $file ) = File::Spec->splitpath(
1004        $self->current_image->file
1005    );
1006
1007    $self->upload_file(
1008        $file
1009    );
1010       
1011    $self->upload_name(
1012        $self->current_image->site_name
1013    );
1014    my $filename = $self->current_image->file_sum ;
1015
1016    # lately defined to make sure we have the last global properties ( resize_w, resize_h )
1017    $self->current_image->site_resized_file( 
1018        File::Spec->catfile(
1019            $self->site_resized_dir,
1020            sprintf(
1021                "%s_%sx%s.%s",
1022                $filename,
1023                $self->resize_w,
1024                $self->resize_h,
1025                $self->type,
1026            )
1027        )
1028    );
1029    #printf("_set_site_resized_file %s\n", $self->current_image->site_resized_file);
1030}
1031
1032sub _create_site_resized_file {
1033    my ( $self ) = @_;
1034
1035    eval {
1036        if(!$self->CreateResized()){
1037            $self->__create_resized_fallback();
1038        };
1039
1040        $self->_set_exif_tag(
1041            $self->current_image->site_resized_file,
1042            'Orientation',
1043            'Horizontal (normal)',
1044        ) if $self->auto_rotate;
1045
1046        $self->CreateWatermark(
1047            $self->watermark_text,
1048            $self->watermark_text_size,
1049            $self->watermark_position,
1050            $self->watermark_x,
1051            $self->watermark_y,
1052            $self->watermark_color,
1053            $self->current_image->site_resized_file
1054        ) if $self->watermark_activate;
1055    }
1056}
1057
1058sub _create_resized_fallback {
1059    my ( $self ) = @_;
1060    # use wx builtin rescale if IM fails
1061    #printf("CreateResized failed %s. Use ResizeCallback\n", $@);
1062    # use method provided by the caller
1063    # source, target, type, ratio, width, $height
1064    $self->ResizeCallback->(
1065        $self->current_image->file,
1066        $self->current_image->site_resized_file,
1067        $self->type,
1068        undef,
1069        $self->resize_w,
1070        $self->resize_h,
1071        $self->quality,
1072    );
1073               
1074    $self->RotateImage(
1075        $self->current_image->site_resized_file,
1076    ) if $self->auto_rotate;
1077}
1078
1079# if we need to rotate
1080sub CreateHigh {
1081    my ( $self ) = @_;
1082
1083    #printf("CreateHigh %s\n", $self->upload_high);
1084    my $bModifyOriginal;
1085    my $bRotate;
1086    my $bAddWatermark;
1087        my $bResize;
1088    my $orientation = $self->current_image->exif_metadata->{Orientation};
1089        my $degrees;
1090   
1091    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
1092    if( $self->auto_rotate and $orientation =~ m/Rotate (\d+)/ ){
1093        $bModifyOriginal = 1;
1094        $bRotate = 1;
1095                $degrees = $1;
1096    }
1097
1098    if( $self->watermark_activate_pwg_high ){
1099        $bModifyOriginal = 1;
1100        $bAddWatermark = 1;
1101    }
1102       
1103        # HD resize
1104        if('HD' eq $self->upload_high){
1105        $bModifyOriginal = 1;
1106        $bResize = 1;
1107        }
1108
1109    if($bModifyOriginal){
1110
1111        my $image = Image::Magick->new();
1112        # we read original
1113        my $status = $image->Read(
1114            $self->current_image->file
1115        );
1116        warn "$status ", $self->current_image->file, "\n" if $status ;
1117        return 0 if $status;
1118        if($bResize){
1119            $status = $image->Resize(
1120                geometry => sprintf("%sx%s>", $self->hd_w, $self->hd_h), 
1121                filter => sprintf("%s", $self->hd_filter), 
1122                blur => $self->hd_blur
1123            );
1124            warn "$status" if $status ;
1125            return 0 if $status;
1126        }
1127       
1128        #printf("resize with quality value %s\n", $self->quality);
1129        $status = $image->Set(quality=>$self->quality);
1130        warn "$status" if $status ;
1131
1132        $status = $image->Set(interlace=>$self->interlace);
1133        warn "$status" if $status ;
1134               
1135        if($bRotate){
1136            $image->Rotate( degrees=>$degrees );       
1137        }       
1138        $image->Write(
1139            $self->current_image->site_high_file
1140        );
1141        warn "$status ", $self->current_image->site_high_file, "\n" if $status ;
1142        return 0 if $status;
1143       
1144        undef $image;
1145
1146        if($bAddWatermark){
1147          my $file_out = $self->current_image->site_high_file;
1148          $self->CreateWatermark(
1149             $self->watermark_text,
1150                $self->watermark_text_size,
1151                $self->watermark_position,
1152                $self->watermark_x,
1153                $self->watermark_y,
1154                $self->watermark_color,
1155                $file_out
1156            );
1157        }
1158
1159
1160        $self->_set_exif_tag(
1161            $self->current_image->site_high_file,
1162            'Orientation',
1163            'Horizontal (normal)',
1164        );
1165
1166        # Now all images that need to be rotated are done. Update exif
1167        $self->current_image->exif_metadata->{Orientation} = 'Horizontal (normal)';
1168
1169
1170    }
1171    else{
1172        # high file is the original file
1173        $self->current_image->site_high_file(
1174            $self->current_image->file
1175        );
1176        #printf("site high file %s\n", $self->current_image->site_high_file);
1177    }
1178
1179    return 1;
1180}
1181
1182# file name for original copy
1183sub _set_site_high_file {
1184        my ( $self ) = @_;
1185
1186        my ( $vol, $dir, $file ) = File::Spec->splitpath(
1187            $self->current_image->file
1188        );
1189   
1190        my ( $filename, $ext ) = split /\./, $file ;
1191   
1192        # high_file is a resized of original
1193        $self->current_image->site_high_file( 
1194            File::Spec->catfile(
1195                $self->site_resized_dir,
1196                sprintf(
1197                    "%s_high.%s",
1198                    $filename,
1199                    $self->type,
1200                )
1201            )
1202        );
1203}
1204
1205sub CreateWatermark {
1206    my ( $self, $text, $text_size, $position, $x, $y, $color, $file_out ) = @_;
1207   
1208    my $rval = 1 ;
1209    my $gravity = $self->gravity->{$position};
1210    my $fill = $self->rgbcolor->{$color};
1211
1212    # debug
1213    #printf("Create watermark %s\n", $file_out);
1214
1215   
1216
1217    my $image = new Image::Magick;
1218   
1219    my $status = $image->ReadImage(
1220        $file_out
1221    );     
1222
1223    my $ratio = $image->Get('height')/($self->resize_h||$image->Get('height'));
1224    $ratio||=1;
1225    $text ||="Your watermark";
1226    $image->Annotate(
1227        pointsize => $text_size*$ratio,
1228        fill => $fill,
1229        x => $x*$ratio,
1230        y => $y*$ratio,
1231        text => $text,
1232        gravity => $gravity,
1233    );
1234                     
1235    $image->Write(
1236        sprintf(
1237            "%s:%s",
1238            $self->type,
1239            $file_out,
1240        )
1241    );
1242}
1243
1244sub _prepare_upload_properties {
1245    my ( $self ) = @_;
1246
1247       
1248        $self->pwg->reupload_action_files(
1249            $self->reupload_action_files||1
1250        );
1251        $self->pwg->reupload_action_properties(
1252            $self->reupload_action_properties||2
1253        );
1254
1255        $self->pwg->reupload_action_properties_m(
1256            $self->reupload_action_properties_m||1
1257        );
1258   
1259    $self->pwg->upload_high(
1260        $self->upload_high
1261    );
1262
1263    $self->pwg->site_high_file(
1264        $self->current_image->site_high_file
1265    );
1266
1267    $self->pwg->site_resized_file(
1268        $self->current_image->site_resized_file
1269    );
1270
1271    $self->pwg->site_thumb_file(
1272        $self->current_image->site_thumb_file
1273    );
1274
1275    $self->pwg->site_author(
1276        $self->current_image->site_author
1277    );
1278
1279    $self->pwg->site_comment(
1280        $self->current_image->site_comment
1281    );
1282
1283    $self->pwg->site_image_name(
1284        $self->current_image->site_name
1285    );
1286
1287    $self->pwg->site_img_date_creation(
1288        substr($self->current_image->create_date, 0, 10)
1289    );
1290
1291        $self->pwg->privacy_level(
1292            $self->current_image->privacy_level
1293        );
1294       
1295    $self->current_image->site_categories(
1296        $self->categories
1297    );
1298
1299    $self->pwg->categories(
1300        sprintf(
1301            "%s",
1302            join(';', @{$self->categories})
1303        )
1304    );
1305
1306    $self->pwg->site_tags(
1307        join(',', @{$self->current_image->site_tags})
1308    );
1309
1310       
1311}
1312
1313# read Orientation exif tag from original image
1314# apply rotation to $file image
1315sub RotateImage {
1316    my ( $self, $file ) = @_;
1317   
1318    # exif from original image
1319    my $orientation = $self->current_image->exif_metadata->{Orientation};
1320
1321    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
1322    if( $orientation =~ m/Rotate (\d+)/ ){
1323        printf(
1324            "Rotate %s\n",
1325            $1
1326        );
1327
1328        my $image = Image::Magick->new();
1329       
1330        # read resized file
1331        my $status = $image->Read(
1332            $file
1333        );
1334        warn "$status ", $file, "\n" if $status ;
1335        return 0 if $status;
1336   
1337        $image->Rotate( degrees=>$1 ); 
1338       
1339        # write resized file
1340        $image->Write(
1341            $file
1342        );
1343        warn "$status ", $file, "\n" if $status ;
1344        return 0 if $status;
1345       
1346        undef $image;
1347   
1348    }   
1349    return 1;
1350}
1351
1352sub GetImage {
1353    my ( $self, $indx ) = @_;
1354   
1355    my $sum = $self->sums->[$indx];
1356
1357    $self->image_sums->{$sum};
1358}
1359
1360sub DeleteImage {
1361    my ( $self, $indx ) = @_;
1362   
1363    my $sum = $self->sums->[$indx];
1364
1365    delete $self->image_sums->{$sum};
1366}
1367
1368
13691;
Note: See TracBrowser for help on using the repository browser.