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

Revision 4467, 34.0 KB checked in by ronosman, 10 years ago (diff)

Feature 1052 added : photo re-upload management. When uploading an already added photo, the user is warned and has a choice on action for files, simple properties and multi-values properties.

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