#######################################################################################
# #
# ################################################################################### #
# # 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 <kool.name at gmail.com> # #
# ################################################################################### #
# #
# ################################################################################### #
# # 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;
}