scripts/photos/import.sh

246 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
declare -A out_dirs=(
["image"]="${HOME}/media/photos"
["video"]="${HOME}/media/videos"
)
declare -a g_files=()
# list of sidecar extensions
SIDECAR="pp3 xmp pp2 bib"
# params
TITLE=
DELETE=0
DEBUG=0
YES=0
NO_JPEG=0
MONTH_ONLY=0
import_photo()
{
local title=$1
local image=$2
local mimetype
local mimetype_short
mimetype=$(exiftool -mimetype -s3 "${image}" 2>/dev/null)
mimetype_short=${mimetype%%/*}
# skip files not returning exif data
if [ x"$?" != "x0" ]
then
if [ ${DEBUG} -eq 1 ]
then
echo "Skip unknown file ${image}"
fi
return
fi
# skip unmanaged files
if [ "${mimetype_short}" != "image" -a "${mimetype_short}" != "video" ]
then
echo "Skip file ${image} of unmanaged mime type ${mimetype}"
return
fi
local out=${out_dirs[$mimetype_short]}
# handle raw+jpeg
if [ "${mimetype}" = "image/jpeg" -a ${NO_JPEG} -eq 1 ]
then
# if raw file exists, skip the jpeg
local file_count=${#g_files[@]}
local i
for (( i = 0; i < file_count ; i++ ))
do
if [ "${g_files[$i]}" != "${image}" -a "${g_files[$i]%.*}" = "${image%.*}" ]
then
if [ ${DELETE} -eq 1 ]
then
rm -f "${image}"
for side_ext in $SIDECAR
do
if [ -f "${image}.${side_ext}" ]
then
rm -f "${image}.${side_ext}"
fi
done
fi
echo "Skip file ${image} from a RAW+jpeg pair"
return
fi
done
fi
# prepend date prefix to dest file name
local file
local prefix
prefix=$((exiftool -q -d "%Y%m%d_%H%M%S" -if '($datetimeoriginal and ($datetimeoriginal ne "0000:00:00 00:00:00"))' -datetimeoriginal -s3 "${image}" 2>/dev/null ; \
exiftool -q -d "%Y%m%d_%H%M%S" -if '($createdate and ($createdate ne "0000:00:00 00:00:00"))' -createdate -s3 "${image}" 2>/dev/null ; \
exiftool -q -d "%Y%m%d_%H%M%S" -filemodifydate -s3 "${image}" 2>/dev/null) | head -n 1)
file=$(basename "${image,,}")
file="${prefix}_${file}"
# prepare dir name
local dir
local pattern
pattern="%Y/%Y-%m-%d"
if [ ${MONTH_ONLY} -eq 1 ]
then
pattern="%Y/%Y-%m"
fi
dir=$((exiftool -q -d "${pattern}" -if '($datetimeoriginal and ($datetimeoriginal ne "0000:00:00 00:00:00"))' -datetimeoriginal -s3 "${image}" 2>/dev/null ; \
exiftool -q -d "${pattern}" -if '($createdate and ($createdate ne "0000:00:00 00:00:00"))' -createdate -s3 "${image}" 2>/dev/null ; \
exiftool -q -d "${pattern}" -filemodifydate -s3 "${image}" 2>/dev/null) | head -n 1)
if [ "x${title}" != "x" ]
then
dir="${dir} - ${title}"
fi
# ensure out dir is created
if [ ! -d "${out}/${dir}" ]
then
mkdir -p "${out}/${dir}"
fi
if [ -f "${out}/${dir}/${file}" ]
then
echo "'${image}' =! '${out}/${dir}/${file}' already exists, aborting"
else
# copy file
echo "'${image}' => '${out}/${dir}/${file}'…"
cp -n --preserve=timestamps --no-preserve=mode "${image}" "${out}/${dir}/${file}"
if [ ${DELETE} -eq 1 ]
then
rm -f "${image}"
fi
# handle sidecar files if exists
for side_ext in $SIDECAR
do
if [ -f "${image}.${side_ext}" ]
then
echo "Copying sidecar ${side_ext} file ${image}.${side_ext}"
cp -n --preserve=timestamps --no-preserve=mode "${image}.${side_ext}" "${out}/${dir}/${file}.${side_ext}"
if [ ${DELETE} -eq 1 ]
then
rm -f "${image}.${side_ext}"
fi
fi
done
# Add the needed XMP metadata for later Digikam processing (the yellow flag, alias XMP-digiKam:PickLabel=2)
exiftool -xmp:XMP-digiKam:PickLabel=2 -overwrite_original -P "${out}/${dir}/${file}.xmp"
fi
}
while getopts "hdjmn:y" flag
do
case $flag in
h)
echo "Usage: $0 [options] <file|directory>..."
echo "-d : delete source"
echo "-j : RAW+jpeg, skip jpeg"
echo "-m : breakdown by month"
echo "-n <name> : title"
echo "-y : force-yes"
exit
;;
d)
DELETE=1
;;
j)
NO_JPEG=1
;;
m)
MONTH_ONLY=1
;;
n)
TITLE=${OPTARG}
case ${TITLE} in
*/*)
echo "'/' is forbidden in title"
exit 1
;;
esac
;;
y)
YES=1
;;
esac
done
shift "$((OPTIND-1))"
if [ "x${TITLE}" != "x" ]
then
echo "Processing queue with title: ${TITLE}"
else
echo "Processing queue with no title"
fi
if [ ${NO_JPEG} -eq 1 ]
then
echo "--- RAW+jpeg handling enabled ---"
fi
if [ ${DELETE} -eq 1 ]
then
echo "--- Deletion of source image enabled ---"
fi
if [ ${MONTH_ONLY} -eq 1 ]
then
echo "--- Image breakdown per month only ---"
fi
if [ ${YES} -ne 1 ]
then
read -p "Proceed? [Y/n] "
if [[ ! $REPLY =~ ^[Yy]*$ ]]
then
echo "Abort"
exit
fi
fi
# build a complete file list
add_file()
{
local file=$1
# skip sidecar files
for side_ext in $SIDECAR
do
if [[ "${file}" == *"${side_ext}" ]]
then
if [ ${DEBUG} -eq 1 ]
then
echo "Skip sidecar file"
fi
return
fi
done
g_files+=("${file}")
}
for rsrc in "$@"
do
if [ -f "${rsrc}" ]
then
add_file "${rsrc}"
elif [ -d "${rsrc}" ]
then
echo "Recursing into '${rsrc}'"
while read file
do
add_file ${file}
done < <(find "${rsrc}" -type f | sort)
fi
done
# now process the list
file_count=${#g_files[@]}
for (( i = 0; i < file_count ; i++ ))
do
if [ -f "${g_files[$i]}" ]
then
import_photo "${TITLE}" "${g_files[$i]}"
else
echo "warning : '${g_files[$i]}' does not exists. file vanished during import (typical for sidecar files with agressive globing or jpeg in RAW+jpeg mode)?"
fi
done