####################################################################################### # # # ################################################################################### # # # Title : # # Description : # # Coded by : Justin Lee # # # # Version : PRE:0.1 # # Date : Friday, February 2, 2008 # # # # License : GNU General Public License v.2 # # # # Copyright (C) 2008 Justin Lee # # # ################################################################################### # # # # ################################################################################### # # # This program is free software; you can redistribute it and/or # # # # modify it under the terms of the GNU General Public License version 2 # # # # as published by the Free Software Foundation. # # # # # # # # This program is distributed in the hope that it will be useful, # # # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # # # GNU General Public License for more details. # # # # # # # # You should have received a copy of the GNU General Public License # # # # along with this program; if not, write to the Free Software # # # # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # ################################################################################### # # # ####################################################################################### use strict; use warnings; use Class::Date qw(date); use File::Basename; use FileHandle; #use Win32::Event; use Term::ReadKey; #use Win32::Pipe; use IO::Handle; use File::Copy qw(cp); use File::Find; use Image::MetaData::JPEG; use Image::Magick; use Getopt::Std; ## get our name and such my ($EXEC,$NAME,$DEBUG,%opt) = ( basename($0), # vv Hacks FTW! vv @{[ split(/\./,basename($0)) ]}[0], new FileHandle, () ); ## getopts! getopts('hwdf:t:D:',\%opt) or omen(0,'invalid switch use',"`$EXEC -g' for help"); help() if $opt{h}; ## open debug file, if needed if (defined($opt{d})) { my $log = "$NAME.log"; unlink($log); $DEBUG->open("> $log"); unless(defined($DEBUG)) { undef $opt{d}; ReadMode 4; print "\u$NAME: Was not able to open logging file, continue without logs? [y/n]"; sleep 1 until (defined(my $key = ReadKey(-1))); ReadMode 0; print "\r\n"; exit 1 unless $key =~ /^y$/i; } } ## hide the window with Win32::GUI if (defined($opt{w})) { require Win32::GUI; my $root = Win32::GUI::GetPerlWindow(); Win32::GUI::Hide($root); } ## set defaults if needed foreach my $lol ( [ 'camera directory', # value's name \$opt{f}, # value's home 'C:/Documents and Settings/dean/Desktop/cam' # 'E:\\DCIM\\100HP740\\' # value's default ],[ 'local directory', # value's name \$opt{t}, # value's home -- vv value's default vv 'C:/Documents and Settings/dean/My Documents/My Pictures/From Camera' ] ) { unless(${$lol->[1]}) { omen(1,"`$lol->[0]' set to default"); ${$lol->[1]} = $lol->[2]; } } my %PIC; ## enter the `local' directory, open and read the camera dir chdir($opt{t}) or omen(0,'unable to access local dir',$!); omen(1,"`$opt{t}' entered"); my ($from_client,$to_server); pipe $from_client, $to_server or omen (0,'unable to pipe',$!); $to_server->autoflush(1); omen(1,'init done, forking'); if (my $pid = fork()) { omen(1,'parent ready'); while (1) { chomp(my $current = <$from_client>); last if $current =~ /::DONE$/o; omen(1,"starting $current process"); while (<$from_client>) { chomp; last if $_ eq $current; my ($loc,$dir,$file) = split(/::/,$_); push(@{$PIC{$loc}},{ 'dir' => $dir, 'file' => $file, 'full' => "$dir/$file" }); omen(1,0,"processed $file"); } omen(1,"finished $current process"); } } elsif (defined $pid) { map { my ($loc_name,$loc_loc) = @{$_}; print $to_server "READ::$loc_name\n"; find( { wanted => sub { parse_find($loc_name,$File::Find::dir,$_) } }, $loc_loc ); print $to_server "READ::$loc_name\n"; } (['CAM',$opt{f}],['LOC',$opt{t}]); print $to_server "READ::DONE\n"; #if (my $pid = fork()) { #oh god, what was I thinking } else { omen(0,'can\'t fork',$!); } ## the end. did you have fun? if (defined($opt{w})) { my $root = Win32::GUI::GetPerlWindow(); Win32::GUI::Show($root); } undef $DEBUG if defined $DEBUG; exit 0; ## subs, mmmmm~ sub parse_find { my ($e_name,$dir,$file) = @_; return 0 unless $file =~ /jpe?g$/oi; print $to_server join('::',$e_name,$dir,$file), "\n"; return 1; } sub date_to_class { my ($date,$time) = split(/\s+/,shift); $date =~ s/:/-/og; return date "$date $time"; } sub class_to_dir { my $date = shift; my $dir = sprintf('%04d-%02d-%02d',$date->year,$date->mon,$date->day); unless (-d $dir) { unless (mkdir($dir,0777)) { omen(0,"wasn't able to create $dir",$!); } } return $dir; } sub omen { if (not shift) { my $msg = "\u$NAME: FATAL - \u$_[0]: $_[1]"; $DEBUG->print($msg) if defined($opt{d}); # let's not tick people off if (defined($opt{w})) { my $root = Win32::GUI::GetPerlWindow(); Win32::GUI::Show($root); } #kill it die "$msg\n"; } else { return 1 unless defined($opt{d}); $DEBUG->print("\u$NAME: \u$_[0].\n") if $_[0]; $DEBUG->print("\u$NAME: > $_[1]\n") if $_[1]; } return 1; } sub help { print <<"EOH"; Name : \u$NAME - Automatically move, compress and sort your pictures. Usage : $EXEC [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'. Note that for the moment this format cannot be changed for parsing reasons. Options : -h Prints this message. -w Use Win32::GUI to hide the console window. -f "X:\\path\\to\\jpegs\\folder\\" Specify the path to your camera's picture folder. -t "C:\\path\\to\\local\\folder\\" Specify the path to your local picture folder. -d Turn on debug mode. Writes to `$NAME.log'. EOH exit 0; }