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

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

Feature 1446 added : transmit the original filename.

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