#!/bin/ksh
# exif_dates_to_file_dates
# Author: Perette Barella
# Copyright 2018 Devious Fish.  All rights reserved.
VERSION='$Id: exif_dates_to_file_dates 61 2021-08-09 18:49:07Z perette $'

arg0=$(basename "$0")
# Korn shell/zsh require
# Author: Perette Barella
# Copyright 2018 Devious Fish.  All rights reserved.
# $Id: require 61 2021-08-09 18:49:07Z perette $

function require {
	typeset requirement
	integer result=0
	for requirement
	do
		if ! whence -p "${requirement%:*}" >/dev/null 2>&1
		then
			print -- "$arg0${arg0+: }${requirement#*:} not found; please install." 1>&2
			result=1
		fi
	done
	(( $result != 0 )) && exit $result
	return 0
}

# Validate that ksh supports the modern/extended getopts format.
# Author: Perette Barella 
# Copyright 2018 Devious Fish.  All rights reserved.
# $Id: modern_ksh_check 19 2018-07-28 23:40:39Z perette $  


function modern_ksh_check {
	if [[ $(getopts '[-][12:abc]' flag --abc; print -- 0$flag) != "012" ]]
	then
		print -- "$arg0${arg0+: }Outdated Korn shell." 1>&2
		exit 1
	fi
}
# extract_exif_date
# Author: Perette Barella
# Copyright 2018-2021 Devious Fish.  All rights reserved.
VERSION='$Id$'

require exiv2

typeset -r EXIF_DATE_ORDER_CAPTURE="Exif.Photo.DateTimeOriginal Exif.Photo.DateTimeDigitized Exif.Image.DateTime"
typeset -r EXIF_DATE_ORDER_MODIFICATION="Exif.Image.DateTime Exif.Photo.DateTimeDigitized Exif.Photo.DateTimeOriginal"

# Extract EXIF date information
#   $1 -- Filename
#   $2 -- Exif field name, or "capture" or "modification" to pick best available
# Return: 0 on success, 1 out failure.
#         Datetime on stdout, format: YYYYmmddHHMM.SS
function extract_exif_date {
	typeset file="$1" order="$2" tag date exif_order

	case "$order" in
		capture)	exif_order="$EXIF_DATE_ORDER_CAPTURE" ;;
		modification)	exif_order="$EXIF_DATE_ORDER_MODIFICATION" ;;
		Exif.Photo.DateTimeOriginal)
				exif_order="$order" ;;
		Exif.Photo.DateTimeDigitized)
				exif_order="$order" ;;
		Exif.Image.DateTime)
				exif_order="$order" ;;
		*)		print "extract_exif_date: $order: Unknown request." 1>&2
				return 1;
	esac
	# Check if the tag exists
	for tag in $exif_order
	do
		if date=$(exiv2 -K$tag -Pv "$file")
		then
			date=${date//:/}
			date=${date// /}
			if [[ ${#date} -eq 14 ]]
			then
				print -- "${date:0:12}.${date:12}"
				return 0
			fi
			print "$file: Corrupt EXIF date tag $tag: $date" 1>&2
		fi
	done
	print "$file: No date EXIF tags found." 1>&2
	return 1
}


require
modern_ksh_check

USAGE=$'
[-1?'$VERSION$']
[+NAME?exif_dates_to_file_dates - Set file modification dates using EXIF data]
[+DESCRIPTION?\b'$arg0$'\b sets jpeg file modification times based on the EXIF
metadata contained within the file.  The original capture time is used, if
present; otherwise, the modification time is used.  If neither is present,
files are left untouched.]
[m:modification-time?Prefer EXIF modification time over capture time.]
[w:warnings?Treat missing EXIF data as a warning.  Omit this option if missing
data should not affect a successful exit status.]
[+EXIT STATUS?0 on success, 1 on error, 2 on warning (EXIF data not found).]
[+SEE ALSO?\bexiv2\b(1), \bexif_where\b(1), \bexif_date_adjust\b(1)]
[+CAVEATS?This utility is timezone naive.]

files ...

[-author?Perette Barella <perette@deviousfish.com>]
'



WARNINGS=false
EXIF_DATE_ORDER="capture"
while getopts -a "$arg0" "$USAGE" option
do
	case "$option" in
	    m)
		EXIF_DATE_ORDER="modification"
		;;
	    w)
		WARNINGS=true
		;;
	esac
done

shift $((OPTIND - 1))
if [ $# -eq 0 ]
then
	OPTIND=0
	getopts -a "$arg0" "$USAGE" option --short
	exit 1
fi


status=0
for file in "$@"
do
	if [ ! -f "$file" ] 
	then
		print "$file: Does not exist or is not a file." 1>&2
		status=1
		continue
	fi

	# Try to extract the exif date information
	if date=$(extract_exif_date "$file" "$EXIF_DATE_ORDER")
	then
		touch -t "$date" "$file" || status=1
	elif $WARNINGS
	then
		[ $status -eq 0 ] && status=2
	fi
done

exit $status
