#!/usr/bin/perl

# exif_touch changes the modified date of a file to match exif information
# Copyright (C) 2005  Mike Lococo
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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 Getopt::Std;

my $dirname;
my $imgname;
my $imgtime;
my %options;

# Parse options. Allow entry of a file or a directory, but not both.
Getopt::Std::getopts('f:d:', \%options);
if (exists $options{d} && exists $options{f}) {
 display_error();
 exit(1)
}
if (!exists $options{d} && !exists $options{f}) {
 display_error();
 exit(1);
}

# Process a single file provided via -f option
if (exists $options{f}) {
 my $imgname = $options{f};
 $imgtime = exif_to_touch($imgname);
 system ("touch", "-t" ,$imgtime, $imgname);
}

# Process a directory of files provided via -d option
if (exists $options{d}) {
 my $dirname = $options{d};
 $dirname =~ s/\/$//;
 opendir(IMGDIR, $dirname)
  or die "Can't open directory: $dirname\nDoes it exist?\n";
 while ($imgname = readdir IMGDIR) {
  next unless $imgname =~ /\.jpg|\.JPG|\.jpeg|\.JPEG$/; # operate only on jpgs
  $imgname = $dirname . '/' . $imgname;
  $imgtime = exif_to_touch($imgname);
 system ("touch", "-t" ,$imgtime, $imgname);
 }
 closedir(IMGDIR);
}

sub exif_to_touch {
 # Accepts a filename, gets the exif "image created" time using the external
 # program "exiftime", and returns that time in a format suitable for passing
 # to the external program "touch" with the -t option
 #
 # Format given by exiftime:
 #    "Image Generated: YYYY:MM:DD HH:MM:SS\n"
 # Format needed by touch -t:
 #    "YYYYMMDDHHMM.SS"
 my $imgname = $_[0];
 my $imgtime = `exiftime -tc '$imgname'`
  or print "External program \"exiftime\" failed on $imgname\n";
 $imgtime =~ s/Image Created: //;  # Strip leading text
 $imgtime =~ s/:(..)$/\.$1/;       # Change final : to .
 $imgtime =~ s/://g;               # Strip :'s
 $imgtime =~ s/ //g;               # Strip spaces
 chomp($imgtime);                  # Strip newline
 return ($imgtime);
}

sub display_error {
 print "Used to set the \"modified date\" of a jpg to match the \"Image Created\"\n";
 print "date in the EXIF headers.  Relies on the external the external programs\n";
 print "\"touch\" and \"exiftime\".  It may operate either on a single file, or\n";
 print "on a directory of files.\n";
 print "\n";
 print "Examples:\n";
 print "set_photo_date.pl -f filename\n";
 print "set_photo_date.pl -d /directory/of-files/to-process/\n";
}
