Changeset 6522


Ignore:
Timestamp:
06/12/10 09:07:43 (10 years ago)
Author:
ronosman
Message:

Refactor thread management to reduce memory footprint ( pLoader now starts with 60 Mo instead of 90 Mo ).

Location:
extensions/pLoader/trunk/src/Uploader
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • extensions/pLoader/trunk/src/Uploader/GUI/App.pm

    r6513 r6522  
    134134 
    135135 
    136 my @transfer_properties = qw/ 
    137     transfer_thread 
    138     transfer_thread_queue 
    139     resize_thread 
    140     resize_thread_queue 
    141 /; 
    142  
    143136my @custom_events = qw/ 
    144137    resize_start_event 
     
    151144__PACKAGE__->mk_accessors(@localized_properties); 
    152145__PACKAGE__->mk_accessors(@language_properties); 
    153 __PACKAGE__->mk_accessors(@transfer_properties); 
    154146__PACKAGE__->mk_accessors(@custom_events); 
    155147 
     
    206198 
    207199 
    208 sub cancel_queues { 
    209     my ( $self ) = @_; 
    210  
    211     $self->cancel_resize; 
    212     $self->cancel_transfer; 
     200sub cancel_all { 
     201    my ( $self ) = @_; 
     202 
     203    $self->resize_manager->cancel; 
     204    $self->transfer_manager->cancel; 
    213205} 
    214206 
     
    217209    my( $self ) = @_; 
    218210 
    219     $self->stop_resize_manager; 
    220     $self->stop_transfer_manager; 
     211    $self->resize_manager->stop; 
     212    $self->transfer_manager->stop; 
    221213    $self->stop_single_instance_server; 
    222214    $self->login_dlg->Destroy;     
     
    224216 
    225217 
    226 } 
    227  
    228  
    229 sub stop_queues { 
    230     my ( $self ) = @_; 
    231  
    232     $self->stop_resize; 
    233     $self->stop_transfer; 
    234 } 
    235  
    236  
    237 sub stop_resize_manager { 
    238     my( $self ) = @_; 
    239  
    240     $self->stop_resize; 
    241     $self->resize_thread->detach; 
    242 } 
    243  
    244  
    245 sub stop_transfer_manager { 
    246     my( $self ) = @_; 
    247  
    248     $self->stop_transfer; 
    249     $self->transfer_thread->detach; 
    250 } 
    251  
    252 sub cancel_transfer { 
    253     my( $self ) = @_; 
    254      
    255     my $data : shared = "CANCEL"; 
    256  
    257     $self->transfer_thread_queue->insert(0, $data); 
    258 } 
    259  
    260  
    261 sub stop_transfer { 
    262     my( $self ) = @_; 
    263      
    264     my $data : shared = "STOP"; 
    265  
    266     $self->transfer_thread_queue->insert(0, $data); 
    267218} 
    268219 
     
    759710    $self->resize_manager( 
    760711        Uploader::ResizeManager->new({ 
    761             site_thumb_dir   => $self->thumb_dir, 
    762             wx_thumb_dir     => $self->wx_thumb_dir, 
    763             site_resized_dir => $self->resized_dir, 
    764             preferences      => sub { $self->preferences(@_) }, 
    765             write_type       => 'jpg', 
     712            thumb_dir      => $self->thumb_dir, 
     713            wx_thumb_dir   => $self->wx_thumb_dir, 
     714            resized_dir    => $self->resized_dir, 
     715            preferences    => sub { $self->preferences(@_) }, 
     716            progress_event => $resize_progress_event, 
     717            done_event     => $resize_done_event, 
     718            event_handler  => $self, 
    766719        }) 
    767720    ); 
    768721 
    769     $self->init_resize_thread_queue; 
    770722    $self->init_resize_done_event_handler; 
    771723    $self->init_resize_progress_event_handler; 
    772 } 
    773  
    774  
    775 sub init_resize_thread_queue { 
    776     my ( $self ) = @_; 
    777  
    778     $self->resize_thread_queue( 
    779         Thread::Queue->new() 
    780     ); 
    781  
    782     # resize worker starts when receiving data from the resize queue 
    783     # resize data must be sent to the calling $handler because $handler data 
    784     # cannot be updated inside the thread 
    785     $self->resize_thread( 
    786         $self->new_resize_thread 
    787     ); 
    788  
    789 } 
    790  
    791  
    792 sub new_resize_thread { 
    793     my ( $self ) = @_; 
    794  
    795     threads->create(  
    796         sub {  
    797             my ( $handler, $resize_manager, $queue ) = @_; 
    798             while (my $data = $queue->dequeue ) { 
    799                  
    800                 return 1 if 'STOP' eq $data; 
    801                 if('CANCEL' eq $data){ 
    802                     # remove pending 
    803                     while($queue->pending){ 
    804                         # must check if valid $image hash 
    805                         $resize_manager->cancel_image( 
    806                             $queue->dequeue 
    807                         ); 
    808                     } 
    809                 } 
    810                 else{ 
    811                     $resize_manager->process_image( 
    812                         $handler, 
    813                         $resize_progress_event, 
    814                         $resize_done_event, 
    815                         $data 
    816                     ); 
    817                 } 
    818             } 
    819             printf("resize queue %s\n", $queue->pending); 
    820         }, 
    821         $self, 
    822         $self->resize_manager, 
    823         $self->resize_thread_queue 
    824     ); 
    825  
    826724} 
    827725 
     
    836734        sub { 
    837735            my ( $handler, $event ) = @_; 
    838             my $data : shared = shared_clone($event->GetData); 
    839             $handler->on_image_progress($data); 
     736            my $image : shared = shared_clone($event->GetData); 
     737            $handler->on_image_progress($image); 
    840738            # image is prepared, send to transfer queue 
    841             $self->transfer_thread_queue->enqueue($data); 
     739            $self->transfer_manager->add_images([ $image ]); 
    842740        }  
    843741    ); 
     
    1077975 
    1078976    my $app = { 
    1079         site_thumb_dir   => $self->thumb_dir, 
     977        thumb_dir   => $self->thumb_dir, 
    1080978        wx_thumb_dir     => $self->wx_thumb_dir, 
    1081         site_resized_dir => $self->resized_dir, 
     979        resized_dir => $self->resized_dir, 
    1082980        userdata_dir     => $self->userdata_dir, 
    1083981        version          => $self->version, 
     
    11071005    } 
    11081006    else { 
    1109         $self->stop_resize_manager; 
     1007        $self->resize_manager->stop; 
    11101008        $self->stop_single_instance_server; 
    11111009    } 
     
    12831181    $self->transfer_manager( 
    12841182        Uploader::TransferManager->new({ 
    1285             site_thumb_dir   => $self->thumb_dir, 
    1286             site_resized_dir => $self->resized_dir, 
    1287             pwg              => $self->pwg, 
     1183            pwg            => $self->pwg, 
     1184            progress_event => $transfer_progress_event, 
     1185            done_event     => $transfer_done_event, 
     1186            event_handler  => $self, 
    12881187        }) 
    12891188    ); 
     
    12921191        $image_progress_event 
    12931192    ); 
    1294     $self->init_transfer_thread_queue; 
     1193 
    12951194    $self->init_transfer_done_event_handler; 
    12961195    $self->init_transfer_progress_event_handler; 
     
    13141213 
    13151214 
    1316 sub init_transfer_thread_queue { 
    1317     my ( $self ) = @_; 
    1318  
    1319     $self->transfer_thread_queue( 
    1320         Thread::Queue->new() 
    1321     ); 
    1322  
    1323     # transfer worker starts when receiving data from the queue 
    1324     # transfer data must be sent to the calling $handler because $handler data 
    1325     # cannot be updated inside the thread 
    1326     $self->transfer_thread( 
    1327         $self->new_transfer_thread 
    1328     ); 
    1329  
    1330 } 
    1331  
    1332  
    1333 sub new_transfer_thread { 
    1334     my ( $self ) = @_; 
    1335  
    1336     threads->create(  
    1337         sub { 
    1338             my ( $handler, $transfer_manager, $queue ) = @_; 
    1339             while (my $data = $queue->dequeue ) { 
    1340                 return 1 if 'STOP' eq $data; 
    1341                 if('CANCEL' eq $data){ 
    1342                     while($queue->pending){ 
    1343                         $transfer_manager->cancel_image( 
    1344                             $queue->dequeue 
    1345                         ); 
    1346                     } 
    1347                 } 
    1348                 else{ 
    1349                     $transfer_manager->process_image( 
    1350                         $handler, 
    1351                         $transfer_progress_event, 
    1352                         $transfer_done_event, 
    1353                         $data 
    1354                     ); 
    1355                 } 
    1356             } 
    1357             printf("transfer queue %s\n", $queue->pending); 
    1358         }, 
    1359         $self, 
    1360         $self->transfer_manager, 
    1361         $self->transfer_thread_queue 
    1362     ); 
    1363  
    1364 } 
    13651215 
    13661216 
     
    13991249 
    14001250 
    1401 sub start_transfer { 
    1402     my( $self, $images ) = @_; 
    1403      
    1404     my $data : shared = shared_clone($images); 
    1405  
    1406     $self->transfer_thread_queue->enqueue($data); 
    1407 } 
    1408  
    1409  
    14101251sub start_resize { 
    14111252    my( $self, $all_images ) = @_; 
     
    14171258        $all_images 
    14181259    ); 
    1419     printf("resize thread %s\n", $self->resize_thread); 
    1420     $self->resize_thread_queue->enqueue( 
    1421         map { shared_clone($_) }@$images 
    1422     ); 
     1260 
     1261    $self->resize_manager->add_images($images); 
    14231262 
    14241263    Wx::PostEvent( 
     
    14351274 
    14361275 
    1437 sub stop_resize { 
    1438     my( $self ) = @_; 
    1439      
    1440     my $data : shared = "STOP"; 
    1441  
    1442     $self->resize_thread_queue->insert(0,$data); 
    1443 } 
    1444  
    1445  
    14461276sub cancel_resize { 
    14471277    my( $self ) = @_; 
    1448      
    1449     my $data : shared = "CANCEL"; 
    14501278 
    14511279    # 
    1452     if( $self->resize_thread_queue->pending and wxYES == Wx::MessageBox(  
     1280    if( $self->resize_manager->pending and wxYES == Wx::MessageBox(  
    14531281        sprintf( 
    14541282            "Cancel %s pending job(s) ?", 
    1455             $self->resize_thread_queue->pending, 
     1283            $self->resize_manager->pending, 
    14561284        ), 
    14571285        "pLoader job processing", 
    14581286        wxYES_NO|wxNO_DEFAULT| wxICON_QUESTION, )  
    14591287    ){ 
    1460         $self->resize_thread_queue->insert(0,$data); 
     1288        $self->resize_manager->cancel; 
    14611289    } 
    14621290} 
  • extensions/pLoader/trunk/src/Uploader/ResizeManager.pm

    r6426 r6522  
    11package Uploader::ResizeManager; 
    2 use threads; 
    3 use threads::shared; 
    42use strict; 
    5 use base qw/Uploader::Object/; 
    6 use Image::Magick; 
    7 use Data::Dumper; 
    8  
    9 $|=1; 
     3use base qw/Uploader::ThreadManager/; 
     4use Uploader::ResizeWorker; 
    105 
    116__PACKAGE__->mk_accessors(qw/ 
     7    wx_thumb_dir 
    128    preferences 
    13     wx_thumb_dir 
    14     site_thumb_dir 
    15     site_resized_dir 
    16     write_type 
    17     progress_event 
    18     done_event 
    19     event_handler 
    20     cancel_event 
    219/); 
    2210 
    2311 
    24 sub Init { 
     12sub new_worker { 
    2513    my ( $self ) =@_; 
    2614 
     15 
     16    Uploader::ResizeWorker->new({ 
     17        thumb_dir    => $self->thumb_dir, 
     18        wx_thumb_dir => $self->wx_thumb_dir, 
     19        resized_dir  => $self->resized_dir, 
     20        preferences  => $self->preferences, 
     21        write_type   => 'jpg', 
     22    }); 
    2723} 
    2824 
    2925 
    30 sub cancel_image { 
    31     my ( $self, $image ) = @_; 
    32      
    33     #must check if $image is a valid hash 
    34     return unless 'HASH' eq ref $image; 
    35     return unless $image->{image_id}; 
    36  
    37     $self->log_image_progress( 
    38         $image, 
    39         "cancelled", 
    40         0, 
    41     ); 
    42 } 
    43  
    44  
    45 sub process_image { 
    46     my ( $self, $handler, $progress_event, $resize_done_event, $image ) = @_; 
    47  
    48     $self->event_handler( 
    49         $handler 
    50     ); 
    51  
    52  
    53     $self->progress_event( 
    54         $progress_event 
    55     ); 
    56  
    57     $self->done_event( 
    58         $resize_done_event 
    59     ); 
    60  
    61     $self->resize_image($image); 
    62     $self->process_high_image($image); 
    63     $self->thumbnail_image($image); 
    64  
    65     $self->post_image_done_event($image); 
    66 } 
    67  
    68  
    69 sub post_image_progress_event { 
    70     my ( $self, $image ) = @_; 
    71  
    72     $self->post_image_event( 
    73         $self->progress_event, 
    74         $image 
    75     ); 
    76 } 
    77  
    78  
    79 sub post_image_done_event { 
    80     my ( $self, $image ) = @_; 
    81  
    82     $image->{status}   = "prepared, waiting for transfer"; 
    83     $image->{progress} = 25; 
    84  
    85     $self->post_image_event( 
    86         $self->done_event, 
    87         $image 
    88     ); 
    89 } 
    90  
    91  
    92 sub post_image_cancel_event { 
    93     my ( $self, $image ) = @_; 
    94  
    95     $image->{status}   = "cancelled"; 
    96     $image->{progress} = 0; 
    97  
    98     $self->post_image_event( 
    99         $self->cancel_event, 
    100         $image 
    101     ); 
    102 } 
    103  
    104  
    105 sub post_image_event { 
    106     my ( $self, $event_type, $image ) = @_; 
    107  
    108     my $thread_event = Wx::PlThreadEvent->new( 
    109         -1, 
    110         $event_type, 
    111         shared_clone($image) 
    112     ); 
    113     Wx::PostEvent($self->event_handler, $thread_event); 
    114 } 
    115  
    116  
    117 sub resize_image { 
    118     my ( $self, $image ) = @_; 
    119  
    120     $self->log_image_progress( 
    121         $image, 
    122         "creating web size", 
    123         5, 
    124     ); 
    125  
    126     my $preferences = $image->{preferences}; 
    127  
    128     if( $preferences->{create_resized} ){ 
    129         $self->create_resized($image); 
    130     } 
    131     # the original is at the right size, no need to create a resize 
    132     else { 
    133         #printf("original no resized %s\n", $self->create_resized); 
    134         $image->{site_resized_file} = $image->{file}; 
    135     } 
    136  
    137     $self->log_image_progress( 
    138         $image, 
    139         "web size created", 
    140         10, 
    141     ); 
    142  
    143 } 
    144  
    145  
    146 sub log_image_progress { 
    147     my ( $self, $image, $status, $value ) = @_; 
    148  
    149     $image->{status}   = $status; 
    150     $image->{progress} = $value; 
    151     $self->post_image_progress_event($image); 
    152 } 
    153  
    154  
    155 sub process_high_image { 
    156     my ( $self, $image ) = @_; 
    157  
    158     my $decode = { 
    159         'No' => 0, 
    160         'Yes, use HD resized of the original photo' => 'HD', 
    161         'Yes, use a copy of the original photo' => 'ORIGINAL', 
    162     }; 
    163  
    164     my $preferences = $image->{preferences}; 
    165     $image->{upload_high} = $decode->{$preferences->{upload_hd}}; 
    166     # if upload high, rotate a copy of original file 
    167     if($image->{upload_high}){ 
    168         $self->create_high($image); 
    169     } 
    170 } 
    171  
    172  
    173 # $image is a hash, not an object 
    174 sub create_resized { 
    175     my ( $self, $image ) = @_; 
    176  
    177     my $rval = 1 ; 
    178  
    179     $image->{site_resized_file} = File::Spec->catfile( 
    180         $self->site_resized_dir, 
    181         sprintf( 
    182             "%s.%s.%s", 
    183             $image->{image_id}, 
    184             $image->{global_rank}, 
    185             $self->write_type, 
    186         ), 
    187     ); 
    188  
    189     my $imgk = new Image::Magick; 
    190  
    191     my $status = $imgk->ReadImage( 
    192         $image->{file} 
    193     ); 
    194     warn "$status" if $status ; 
    195     return 0 if $status; 
    196  
    197     my $w = $imgk->Get('width'); 
    198     my $h = $imgk->Get('height'); 
    199  
    200     $status = $imgk->Set(Gravity=>"Center"); 
    201     warn "$status" if $status ; 
    202  
    203     # exif from original image 
    204     my $orientation = $image->{exif_metadata}{Orientation}; 
    205     my $preferences = $image->{preferences}; 
    206      
    207     # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW 
    208     if( $orientation =~ m/Rotate (\d+)/ ){ 
    209         printf( 
    210             "Rotate %s\n", 
    211             $1 
    212         ); 
    213      
    214         $imgk->Rotate( degrees=>$1 ) if $preferences->{auto_rotate};     
    215     } 
    216  
    217  
    218     #printf("resize with blur value %s\n", $self->blur); 
    219     $status = $imgk->Resize( 
    220         geometry => sprintf( 
    221             "%sx%s>", 
    222             $preferences->{resize_w}, 
    223             $preferences->{resize_h} 
    224         ), 
    225         filter => sprintf( 
    226             "%s", 
    227             $preferences->{filter} 
    228         ),  
    229         blur => $preferences->{blur} 
    230     ); 
    231     warn "$status" if $status ; 
    232     return 0 if $status; 
    233  
    234     #printf("resize with quality value %s\n", $self->quality); 
    235     $status = $imgk->Set(quality=>$preferences->{quality}); 
    236     warn "$status" if $status ; 
    237  
    238     $status = $imgk->Set(interlace=>$preferences->{interlace}); 
    239     warn "$status" if $status ; 
    240  
    241     $imgk->Write( 
    242         sprintf( 
    243             "%s:%s", 
    244             $self->write_type, 
    245             $image->{site_resized_file}, 
    246         ) 
    247     ); 
    248     warn "$status" if $status ; 
    249     return 0 if $status; 
    250      
    251     undef $imgk; 
    252  
    253     
    254     $rval = 0 if $status; 
    255  
    256     return $rval; 
    257 } 
    258  
    259 # $image is a hash, not an object 
    260 sub thumbnail_image { 
    261     my ( $self, $image ) = @_; 
    262      
    263     my $rval = 1; 
    264  
    265     $image->{site_thumb_file} = File::Spec->catfile( 
    266         $self->site_thumb_dir, 
    267         sprintf( 
    268             "%s.%s.%s", 
    269             $image->{image_id}, 
    270             $image->{global_rank}, 
    271             $self->write_type, 
    272         ), 
    273     ); 
    274  
    275  
    276     my $imgk = new Image::Magick; 
    277  
    278     my $status = $imgk->ReadImage( 
    279         $image->{site_resized_file} 
    280     ); 
    281     warn "$status" if $status ; 
    282  
    283     my $preferences = $image->{preferences}; 
    284     my $pattern = $preferences->{thumbnail_shape_square} ? 
    285         "%sx%s^" : 
    286         "%sx%s>" ; 
    287     $status = $imgk->Resize( 
    288         geometry => sprintf( 
    289             $pattern,  
    290             $preferences->{thumb_size},  
    291             $preferences->{thumb_size} 
    292         ), 
    293     ); 
    294     warn "$status" if $status ; 
    295  
    296     $status = $imgk->Set(Gravity=>"Center"); 
    297     warn "$status" if $status ; 
    298  
    299     $status = $imgk->Crop( 
    300         geometry=>sprintf( 
    301             "%sx%s+0+0", 
    302             $preferences->{thumb_size}, 
    303             $preferences->{thumb_size} 
    304         ) 
    305     ) if $preferences->{thumbnail_shape_square}; 
    306  
    307  
    308     $status = $imgk->Set(quality=>$preferences->{th_quality}); 
    309     warn "$status" if $status ; 
    310  
    311     $status = $imgk->Strip(); 
    312     warn "$status" if $status ; 
    313  
    314  
    315     $imgk->Write( 
    316         sprintf( 
    317             "%s:%s", 
    318             $self->write_type, 
    319             $image->{site_thumb_file}, 
    320         ) 
    321     ); 
    322      
    323     undef $image; 
    324  
    325  
    326     $rval = 0 if $status; 
    327  
    328     return $rval; 
    329 } 
    330  
    331  
    332 sub create_high { 
    333     my ( $self, $image ) = @_; 
    334  
    335     $self->log_image_progress( 
    336         $image, 
    337         "preparing high", 
    338         15, 
    339     ); 
    340  
    341     $self->set_site_high_file($image); 
    342  
    343     my $bModifyOriginal; 
    344     my $bRotate; 
    345     my $bAddWatermark; 
    346     my $bResize; 
    347     my $orientation = $image->{exif_metadata}{Orientation}; 
    348     my $degrees; 
    349      
    350     my $preferences = $image->{preferences}; 
    351     # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW 
    352     if( $preferences->{auto_rotate} and $orientation =~ m/Rotate (\d+)/ ){ 
    353         $bModifyOriginal = 1; 
    354         $bRotate = 1; 
    355         $degrees = $1; 
    356     } 
    357  
    358     if( $preferences->{watermark_activate_pwg_high} ){ 
    359         $bModifyOriginal = 1; 
    360         $bAddWatermark = 1; 
    361     } 
    362      
    363     # HD resize 
    364     if('HD' eq $image->{upload_high}){ 
    365         $bModifyOriginal = 1; 
    366         $bResize = 1; 
    367     } 
    368  
    369     if($bModifyOriginal){ 
    370  
    371         my $imgk = Image::Magick->new(); 
    372         # we read original 
    373         my $status = $imgk->Read( 
    374             $image->{file} 
    375         ); 
    376         warn "$status ", $image->{file}, "\n" if $status ; 
    377         return 0 if $status; 
    378  
    379         if($bRotate){ 
    380             $imgk->Rotate( degrees=>$degrees );     
    381         }         
    382         $imgk->Write( 
    383             $image->{site_high_file} 
    384         ); 
    385         warn "$status ", $image->{site_high_file}, "\n" if $status ; 
    386         return 0 if $status; 
    387  
    388         if($bResize){ 
    389             $status = $imgk->Resize( 
    390                 geometry => sprintf( 
    391                     "%sx%s>", 
    392                     $preferences->{hd_w}, 
    393                     $preferences->{hd_h} 
    394                 ),  
    395                 filter => sprintf( 
    396                     "%s", 
    397                     $preferences->{hd_filter} 
    398                 ),  
    399                 blur => $preferences->{hd_blur} 
    400             ); 
    401             warn "$status" if $status ; 
    402             return 0 if $status; 
    403         } 
    404          
    405         #printf("resize with quality value %s\n", $self->quality); 
    406         $status = $imgk->Set(quality=>$preferences->{quality}); 
    407         warn "$status" if $status ; 
    408  
    409         $status = $imgk->Set(interlace=>$preferences->{interlace}); 
    410         warn "$status" if $status ; 
    411          
    412          
    413         undef $imgk; 
    414  
    415         if($bAddWatermark){ 
    416             my $file_out = $image->{site_high_file}; 
    417             $self->create_watermark( 
    418                 $preferences->{watermark_text}, 
    419                 $preferences->{watermark_text_size}, 
    420                 $preferences->{watermark_position}, 
    421                 $preferences->{watermark_x}, 
    422                 $preferences->{watermark_y}, 
    423                 $preferences->{watermark_color}, 
    424                 $file_out 
    425             ); 
    426         } 
    427  
    428         $self->set_file_exif_tag( 
    429             $image->{site_high_file}, 
    430             'Orientation', 
    431             'Horizontal (normal)', 
    432         ); 
    433  
    434         # Now all images that need to be rotated are done. Update exif 
    435         $image->{exif_metadata}{Orientation} = 'Horizontal (normal)'; 
    436  
    437  
    438     } 
    439     else{ 
    440         # high file is the original file 
    441         $image->{site_high_file} = $image->{file}; 
    442         #printf("site high file %s\n", $self->current_image->site_high_file); 
    443     } 
    444     $self->log_image_progress( 
    445         $image, 
    446         "high prepared", 
    447         25, 
    448     ); 
    449  
    450     return 1; 
    451  
    452 } 
    453  
    454  
    455 sub set_site_high_file { 
    456     my ( $self, $image ) = @_; 
    457  
    458     my ( $vol, $dir, $file ) = File::Spec->splitpath( 
    459         $image->{file} 
    460     ); 
    461      
    462     my ( $filename, $ext ) = split /\./, $file ; 
    463      
    464     # high_file is a resized of original 
    465     $image->{site_high_file} = File::Spec->catfile( 
    466         $self->site_resized_dir, 
    467         sprintf( 
    468             "%s_high.%s.%s", 
    469             $image->{image_id}, 
    470             $image->{global_rank}, 
    471             $self->write_type, 
    472         ), 
    473     ); 
    474 } 
    475  
    476  
    477 sub set_file_exif_tag { 
    478     my ( $self, $file, $tag, $newValue ) = @_;     
    479  
    480     my $options = {}; 
    481     # Create a new Image::ExifTool object 
    482     my $exifTool = new Image::ExifTool; 
    483  
    484     # Extract meta information from an image 
    485     $exifTool->ExtractInfo($file, $options); 
    486  
    487     # Set a new value for a tag 
    488     $exifTool->SetNewValue($tag, $newValue); 
    489  
    490     # Write new meta information to a file 
    491     $exifTool->WriteInfo($file); 
    492  
    493 } 
    494  
    495  
    496 # used for display in GUI. has to fit a square box ( wxImageList ) 
    497 # $image is an object 
    49826sub create_wx_thumbnail { 
    49927    my ( $self, $image ) = @_; 
    50028 
    501  
    502     $image->wx_thumb_file(  
    503         File::Spec->catfile( 
    504             $self->wx_thumb_dir, 
    505             sprintf( 
    506                 "%s.%s.%s", 
    507                 $image->image_id, 
    508                 $image->global_rank, 
    509                 $self->write_type, 
    510             ), 
    511         ) 
    512     ); 
    513  
    514  
    515     my $rval = 0; 
    516     my $imgk = new Image::Magick; 
    517  
    518     my $preferences = $image->{preferences}; 
    519     my $size = $preferences->{wx_thumb_size}||100; 
    520  
    521     my $status = $imgk->Set(size=>sprintf("%sx%s", 2*$size, 2*$size)); 
    522     warn "$status" if $status ; 
    523  
    524     $status = $imgk->ReadImage( 
    525         $image->file 
    526     ); 
    527     warn "$status" if $status; 
    528     return $rval if $status; 
    529  
    530     # maximize size and keep aspect ratio 
    531     $status = $imgk->Thumbnail( 
    532         geometry=>sprintf("%s%s>", $size*$size, '@') 
    533     ); 
    534     # to get adjusted to a square box 
    535     #$status = $image->Thumbnail( 
    536     #    geometry=>sprintf("%sx%s%s", $size, $size, '^') 
    537     #); 
    538     warn "$status" if $status; 
    539     return $rval if $status; 
    540  
    541     $status = $imgk->Set(Gravity=>"Center"); 
    542     warn "$status" if $status ; 
    543  
    544     $imgk->Extent( 
    545         geometry=>sprintf("%sx%s", $size, $size), 
    546         gravity=>'center', 
    547     ); 
    548      
    549     $imgk->Set( 
    550         quality=>$preferences->{wx_quality}||90 
    551     ); 
    552  
    553     $status = $imgk->Strip(); 
    554     warn "$status" if $status ; 
    555  
    556     # exif from original image 
    557     my $orientation = $image->exif_metadata->{Orientation}; 
    558      
    559     # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW 
    560     if( $orientation =~ m/Rotate (\d+)/ ){ 
    561         printf( 
    562             "Rotate %s\n", 
    563             $1 
    564         ); 
    565      
    566         $imgk->Rotate( degrees=>$1 ) if $preferences->{auto_rotate};     
    567     } 
    568      
    569  
    570     $imgk->Write( 
    571         sprintf( 
    572             "%s:%s", 
    573             $self->write_type, 
    574             $image->wx_thumb_file, 
    575         ) 
    576     ); 
    577  
    578     undef $imgk; 
    579      
    580     $rval = 1; 
    581      
    582     return $rval; 
     29    $self->worker->create_wx_thumbnail($image); 
    58330} 
    58431 
  • extensions/pLoader/trunk/src/Uploader/TransferManager.pm

    r6426 r6522  
    22use threads; 
    33use threads::shared; 
     4use Thread::Queue; 
    45use strict; 
    5 use base qw/Uploader::Object/; 
    6 use Data::Dumper; 
    7 use Digest::MD5::File qw/file_md5_hex md5_hex/; 
    8  
    9 $|=1; 
    10  
     6use base qw/Uploader::ThreadManager/; 
     7use Uploader::TransferWorker; 
     8use vars qw/$AUTOLOAD/; 
    119__PACKAGE__->mk_accessors(qw/ 
    12     preferences 
    13     site_thumb_dir 
    14     site_resized_dir 
    15     write_type 
    16     destination_category 
    1710    pwg 
    18     event_handler 
    19     progress_event 
    20     done_event 
    2111/); 
    2212 
    2313 
    24 sub Init { 
     14sub new_worker { 
    2515    my ( $self ) =@_; 
    2616 
    27     $self->destination_category([]); 
    28     $self->pwg->log_progress_cbk( 
    29         sub { $self->post_image_progress_event(@_) } 
    30     ); 
    31 } 
    3217 
    33  
    34 sub cancel_image { 
    35     my ( $self, $image ) = @_; 
    36  
    37     #must check if $image is a valid hash 
    38     return unless 'HASH' eq ref $image; 
    39     return unless $image->{image_id}; 
    40  
    41     $self->log_image_progress( 
    42         $image, 
    43         "cancelled", 
    44         0, 
    45     ); 
    46 } 
    47  
    48  
    49 sub process_image { 
    50     my ( $self, $handler, $progress_event, $transfer_done_event, $image) = @_; 
    51  
    52     $self->event_handler( 
    53         $handler 
    54     ); 
    55  
    56  
    57     $self->progress_event( 
    58         $progress_event 
    59     ); 
    60  
    61     $self->done_event( 
    62         $transfer_done_event 
    63     ); 
    64  
    65  
    66     if(!$self->exists_image($image)){ 
    67         $self->insert_image($image); 
    68     } 
    69     else { 
    70         $self->update_image($image); 
    71     } 
     18    Uploader::TransferWorker->new({ 
     19        pwg => $self->pwg, 
     20    }); 
    7221 
    7322} 
    7423 
    7524 
    76 sub exists_image { 
    77     my ( $self, $image ) = @_; 
     25sub destination_category { 
     26    my ( $self, $category ) = @_; 
    7827 
    79     $self->pwg->exists_image( 
    80         $image 
    81     ); 
    82 } 
    83  
    84  
    85 sub insert_image { 
    86     my ( $self, $image ) = @_; 
    87  
    88     $self->log_image_progress($image, "sending files", 0); 
    89     $self->add_image_files($image); 
    90     $self->add_image($image); 
    91     $self->log_image_progress($image, "transfered", 100); 
    92  
    93 } 
    94  
    95  
    96 sub log_image_progress { 
    97     my ( $self, $image, $status, $value ) = @_; 
    98  
    99     $image->{status}   = $status; 
    100     $image->{progress} = $value; 
    101     $self->post_image_progress_event($image); 
    102 } 
    103  
    104  
    105 sub add_image_files { 
    106     my ( $self, $image ) = @_; 
    107  
    108     $self->init_image_files_checksums($image); 
    109     $self->send_image_files_chunks($image); 
    110 } 
    111  
    112  
    113 sub init_image_files_checksums { 
    114     my ( $self, $image ) = @_; 
    115  
    116  
    117     $self->log_image_progress($image, "check files", 0); 
    118     my @file_types = ('site_resized_file', 'site_thumb_file'); 
    119     push @file_types, 'site_high_file' if $image->{upload_high}; 
    120  
    121     map { 
    122         $self->init_image_file_type_checksum($image, $_) 
    123     }@file_types; 
    124  
    125     $self->log_image_progress($image, "files checked", 100); 
    126 } 
    127  
    128  
    129 sub init_image_file_type_checksum { 
    130     my ( $self, $image, $file_type ) = @_; 
    131  
    132     my $file = $image->{$file_type}; 
    133     $image->{"$file_type"."_checksum"} = $self->checksum($file); 
    134 } 
    135  
    136  
    137 sub checksum { 
    138     my ( $self, $file ) = @_; 
    139  
    140     my $file_sum; 
    141  
    142     eval { 
    143         $file_sum = file_md5_hex( 
    144             $file 
    145         ); 
    146     }; 
    147  
    148     $file_sum; 
    149 } 
    150  
    151  
    152 sub send_image_files_chunks { 
    153     my ( $self, $image ) = @_; 
    154  
    155     $self->pwg->send_image_files_chunks( 
    156         $image 
    157     ); 
    158 } 
    159  
    160  
    161 sub add_image { 
    162     my ( $self, $image ) = @_; 
    163  
    164     $self->pwg->add_image($image); 
    165 } 
    166  
    167  
    168 sub update_image { 
    169     my ( $self, $image ) = @_; 
    170  
    171     $self->log_image_progress($image, "updating", 0); 
    172  
    173     $self->update_image_files($image); 
    174     $self->update_image_properties($image); 
    175  
    176     $self->log_image_progress($image, "updated", 100); 
    177 } 
    178  
    179  
    180 sub update_image_files { 
    181     my ( $self, $image ) = @_; 
    182  
    183     if($image->{preferences}{reupload_action_files}){ 
    184         $self->log_image_progress($image, "updating files", 0); 
    185         $self->init_image_files_checksums($image); 
    186         $self->update_image_modified_files($image); 
    187         $self->log_image_progress($image, "files updated", 100); 
    188     } 
    189 } 
    190  
    191  
    192 sub update_image_modified_files { 
    193     my ( $self, $image ) = @_; 
    194  
    195     $self->pwg->update_image_modified_files($image); 
    196 } 
    197  
    198  
    199 sub update_image_properties { 
    200     my ( $self, $image ) = @_; 
    201  
    202     $self->log_image_progress($image, "updating properties", 0); 
    203     $self->pwg->update_image_properties($image); 
    204     $self->log_image_progress($image, "properties updated", 100); 
    205 } 
    206  
    207  
    208 sub post_image_progress_event { 
    209     my ( $self, $image ) = @_; 
    210  
    211     $self->post_image_event( 
    212         $self->progress_event, 
    213         $image 
    214     ); 
    215 } 
    216  
    217  
    218 sub post_image_event { 
    219     my ( $self, $event_type, $image ) = @_; 
    220  
    221     my $thread_event = Wx::PlThreadEvent->new( 
    222         -1, 
    223         $event_type, 
    224         shared_clone($image) 
    225     ); 
    226     Wx::PostEvent($self->event_handler, $thread_event); 
     28    $self->worker->destination_category($category); 
    22729} 
    22830 
     
    23133    my ( $self ) = @_; 
    23234 
    233     !scalar @{$self->destination_category}; 
     35    $self->worker->destination_category_is_empty; 
    23436} 
    23537 
Note: See TracChangeset for help on using the changeset viewer.