# version 3 # don't steal it # or else use strict; use warnings; use subs qw(inbox); use File::Basename; # imports basename() use IO::Handle; use FileHandle; use File::Copy; # imports copy() use File::Find; # imports find() use Image::MetaData::JPEG; use Image::Magick; use Getopt::Long qw(:config bundling); use Deans::Functions qw( skew ); # imports skew() use constant { NAME => basename($0), HOME => skew(@{[ fileparse($0) ]}[1]) }; ## get the command line args my ( $orig_remove, # Do not unlink old pics from the camera. $justin_is_sexy, # Well, I am. $image_format_regex, # The regex that find will use to see if it's found a valid file. $raw_dir_orig, # Specify where the camera stores it's pictures. $raw_dir_final, # Specify where raw pictures are to be moved. $raw_dir_temp # Specify a pictures will be worked on. ) = ( 1, 1, 'hpim(\d+)\.jpe?g$', 'P:/', skew($ENV{USERPROFILE},'My Documents/My Pictures/From Camera/raws'), $ENV{TEMP} ); GetOptions( 'raw-directory|R=s' => \$raw_dir_orig, 'local-directory|L=s' => \$raw_dir_final, 'temp-directory|T=s' => \$raw_dir_temp, 'remove-old!' => \$orig_remove, 'image-format-regex=s' => \$image_format_regex, 'help|h|H' => \&print_help ); ## test the directories, and enter the temp dir die $! unless -d $raw_dir_orig; die $! unless -d $raw_dir_final; die $! unless -d $raw_dir_temp; die $! unless chdir($raw_dir_temp); ## check if there's already a temp dir, if not make one unless (-d 'MNSPICMAN') { die $! unless mkdir('MNSPICMAN',0777); } die $! unless chdir('MNSPICMAN'); unlink(<*.jpg>); unlink(<*.jpeg>); ## prime our best smokin' pipe my ($from_file_manager, $to_compressor); pipe $from_file_manager, $to_compressor or die $!; $to_compressor->autoflush(1); ## FORK! if (my $pid = fork) { ## parent (compresses) while (inbox) { my $dir = inbox; my $path = inbox; die $! unless defined $dir; die $! unless defined $path; my $file = skew($dir,join('',split(/_TEMP_/,$path))); #haha, screw off print "$file"; my $magick = new Image::Magick; $magick->Read($path); $magick->[0]->Resize( geometry => '52%', filter => 'sinc' ); $magick->[0]->Crop( geometry => '1600x1200' ); $magick->[0]->Write( filename => $file, comment => 'Captured by: Justin Lee (kool.name@gmail.com)', quality => 97 ); die $! unless -e $file; undef $magick; unlink $path; print "...done\n"; } print "DONE!\n"; } elsif (defined $pid) { ## child (copies and dates pictures) print "welcome\n"; find( { no_chdir => 1, wanted => \©_date_move }, $raw_dir_orig ); print $to_compressor "done\n"; } else { ## fork failed die $!; } ## the end exit 0; ## subs sub inbox { chomp(my $in = <$from_file_manager>); return 0 unless $in; return 0 if $in =~ /^(?:0|done|failed)$/io; return 1 if $in =~ /^(?:1|working)$/io; return $in; } sub copy_date_move { return unless $_ =~ /$image_format_regex/oi; my $id = defined($1) ? $1 : ''; print $to_compressor "working\n"; my $old = $_; my $new = basename($old); #this is okay, you'll see move($old,$new); my $image = new Image::MetaData::JPEG ($new); my $exif = $image->get_Exif_data('IMAGE_DATA', 'TEXTUAL'); my ($date, $time) = split(/\s+/,$exif->{DateTimeOriginal}->[0]); $date =~ s/:|\s|;/-/go; $time =~ s/:|\s|-|;//go; chop($time); #wtf my $dated_dir = skew($raw_dir_final,$date); unless (-d $dated_dir) { die $! unless mkdir($dated_dir,0777); } print $to_compressor "$dated_dir\n"; my $to_compress = "${time}${id}_TEMP_.JPG"; die $! unless move($new,$to_compress); undef $image; undef $exif; print $to_compressor "$to_compress\n"; return; } sub print_help { print <<"EOH"; Name : \u@{[ NAME ]} - Automatically move, compress and sort your pictures. Usage : @{[ NAME ]} [options] Description : \u@{[ NAME ]} is a script written for moving and compressing pictures from your camera to a local folder. The pictures are stored in directories named with ISO-like dates of `yyyy-mm-dd'. Options : -h, -H, --help Prints this message. -R, --raw-directory < /path/to/camera/raws/ > Specifies the path to the camera raws. It can also be specified with -I in the setup file. Note that this is a required piece of data. -L, --local-directory < /path/to/new/files/ > Specifies the place to save the sorted pictures and directories. Defaults to `@{[ skew($ENV{'USERPROFILE'},'/My Documents/My Pictures/From Camera/raws') ]}'. -T, --temp-directory < /path/to/temp/files/ > Specifies the place to store pictures while they are being worked on. Defaults to `@{[ skew($ENV{'TEMP'}) ]}'. --image-format-regex Specifies the regex that find() will use to see if it's found a valid file. Defaults to `^hpim(\\d+)\\.jpe?g$', uses /i. You can have one backtrace for use in the final file name. --remove-old, --no-remove-old Specifies whether or not to remove the original raws from the camera directory. --remove-old by default. EOH exit 0; }