2024-05-25 18:48:30 +03:00
|
|
|
#!/usr/bin/env bash
|
2019-04-05 02:04:03 +03:00
|
|
|
#
|
|
|
|
|
#######################################################################
|
|
|
|
|
#
|
|
|
|
|
# This does not care about actual topology of the archive directory
|
|
|
|
|
# that is passed it, it will find all the supported raw files and
|
|
|
|
|
# create the apropriate directories one level up.
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
|
|
# CPU threads to keep free...
|
2019-03-31 16:11:04 +03:00
|
|
|
KEEP_FREE=2
|
|
|
|
|
|
|
|
|
|
THREADS=`cat /proc/cpuinfo | awk '/^processor/{print $3}' | wc -l`
|
2019-04-01 11:26:49 +03:00
|
|
|
if [ $KEEP_FREE ] && (( THREADS > KEEP_FREE )) ; then
|
2019-03-31 16:11:04 +03:00
|
|
|
THREADS=$((THREADS - KEEP_FREE))
|
|
|
|
|
fi
|
2019-03-31 16:04:34 +03:00
|
|
|
|
2019-04-01 11:26:49 +03:00
|
|
|
|
2013-09-03 07:24:37 +04:00
|
|
|
# TODO make this runnable from anywhere...
|
|
|
|
|
# - prepend paths with './' only if local/relative
|
|
|
|
|
|
2013-09-01 11:47:55 +04:00
|
|
|
# HACK: this is here to avoid using windows find...
|
|
|
|
|
PATH=/bin:$PATH
|
|
|
|
|
|
|
|
|
|
printhelp(){
|
2013-09-03 07:24:37 +04:00
|
|
|
echo "Usage: `basename $0` [ARGUMENTS] [ARCHIVE_ROOT]"
|
2013-09-01 11:47:55 +04:00
|
|
|
echo
|
2013-09-03 07:24:37 +04:00
|
|
|
echo "Arguments:"
|
|
|
|
|
echo " -h --help - print this help and exit."
|
|
|
|
|
echo " --common-previews PATH"
|
|
|
|
|
echo " - build a single preview set at PATH."
|
2014-05-21 19:28:23 +04:00
|
|
|
echo " -c - build a single common path at ARCHIVE_ROOT;"
|
|
|
|
|
echo " this is a shorthand for: --common-path '.'."
|
2019-03-31 15:35:19 +03:00
|
|
|
echo " -l --low-res-previews"
|
|
|
|
|
echo " - generate low resolution previews and store"
|
|
|
|
|
echo " original previews in \"hi-res (RAW)\"."
|
2013-09-01 11:47:55 +04:00
|
|
|
echo
|
2013-09-03 07:24:37 +04:00
|
|
|
echo " --skip-archive - skip creating archive structure (use: exiftool)."
|
|
|
|
|
echo " --skip-previews - skip creating previews (use: vips)."
|
|
|
|
|
echo " --skip-cache - skip creating cache (use: buildcache)."
|
|
|
|
|
echo " --skip-all - same as setting all of the above."
|
2013-09-01 11:47:55 +04:00
|
|
|
echo
|
2013-09-03 07:24:37 +04:00
|
|
|
echo "NOTE: common preview path is relative to ARCHIVE_ROOT."
|
2019-04-05 02:04:03 +03:00
|
|
|
echo "NOTE: if no ARCHIVE_ROOT is passed then this will process all"
|
|
|
|
|
echo " directories in cwd."
|
|
|
|
|
# XXX this is how exiftool does things, need to figure out a workaround...
|
|
|
|
|
echo "NOTE: this expects the RAW files to be located at least one level"
|
|
|
|
|
echo " down the ARCHIVE_ROOT to make room for the metadata and preview"
|
|
|
|
|
echo " directories."
|
|
|
|
|
echo " If any raw files are found in the ARCHIVE_ROOT directly this"
|
|
|
|
|
echo " will create the preview and metadata directly one level above"
|
|
|
|
|
echo " that."
|
2013-09-01 11:47:55 +04:00
|
|
|
echo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# process args...
|
|
|
|
|
while true ; do
|
|
|
|
|
case $1 in
|
|
|
|
|
-h|--help)
|
|
|
|
|
printhelp
|
|
|
|
|
exit
|
|
|
|
|
;;
|
|
|
|
|
|
2014-05-21 19:28:23 +04:00
|
|
|
-c)
|
|
|
|
|
COMMON_PREVIEWS="."
|
|
|
|
|
shift
|
|
|
|
|
;;
|
2013-09-01 11:47:55 +04:00
|
|
|
--common-previews)
|
2013-10-31 07:40:02 +04:00
|
|
|
COMMON_PREVIEWS="${2}"
|
2013-09-01 11:47:55 +04:00
|
|
|
shift
|
|
|
|
|
shift
|
|
|
|
|
;;
|
2019-03-31 15:35:19 +03:00
|
|
|
-l|--low-res-previews)
|
|
|
|
|
LOW_RES_PREVIEWS=1
|
|
|
|
|
shift
|
|
|
|
|
;;
|
2013-09-01 11:47:55 +04:00
|
|
|
|
|
|
|
|
--skip-archive)
|
|
|
|
|
SKIP_ARCHIVE=yes
|
|
|
|
|
echo skipping making archive...
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--skip-previews)
|
|
|
|
|
SKIP_PREVIEWS=yes
|
|
|
|
|
echo skipping making previews...
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--skip-cache)
|
|
|
|
|
SKIP_CACHE=yes
|
|
|
|
|
echo skipping making cache...
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--skip-all)
|
|
|
|
|
SKIP_ARCHIVE=yes
|
|
|
|
|
echo skipping making archive...
|
|
|
|
|
SKIP_PREVIEWS=yes
|
|
|
|
|
echo skipping making previews...
|
|
|
|
|
SKIP_CACHE=yes
|
|
|
|
|
echo skipping making cache...
|
|
|
|
|
shift
|
|
|
|
|
;;
|
2013-09-08 03:28:11 +04:00
|
|
|
*)
|
|
|
|
|
break
|
|
|
|
|
;;
|
2013-09-01 11:47:55 +04:00
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
if [ -z "$1" ] ; then
|
2013-07-03 03:14:40 +04:00
|
|
|
ARCHIVE_ROOT="."
|
2013-09-08 03:28:11 +04:00
|
|
|
else
|
|
|
|
|
ARCHIVE_ROOT="$1"
|
2013-07-03 03:14:40 +04:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "Doing: \"$ARCHIVE_ROOT\""
|
2013-06-28 00:14:48 +04:00
|
|
|
|
|
|
|
|
|
2019-03-31 16:04:34 +03:00
|
|
|
if [ $LOW_RES_PREVIEWS ] ; then
|
2019-03-31 15:35:19 +03:00
|
|
|
RAW_PREVIEW_DIR="hi-res (RAW)"
|
|
|
|
|
else
|
|
|
|
|
RAW_PREVIEW_DIR="preview (RAW)"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
2013-06-28 18:37:15 +04:00
|
|
|
PROCESSED_PREVIEW_DIR="preview"
|
2019-03-31 15:35:19 +03:00
|
|
|
METADATA_DIR="metadata"
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2013-06-28 18:37:15 +04:00
|
|
|
PROCESSED_PREVIEW_NAME="%-:1d/${PROCESSED_PREVIEW_DIR}/%f.jpg"
|
2013-06-28 00:14:48 +04:00
|
|
|
PREVIEW_NAME="%-:1d/${RAW_PREVIEW_DIR}/%f.jpg"
|
|
|
|
|
JSON_NAME="%-:1d/${METADATA_DIR}/%f.json"
|
|
|
|
|
|
2013-06-28 03:48:16 +04:00
|
|
|
|
2013-06-29 04:14:45 +04:00
|
|
|
# TODO do a version of this using exiv2...
|
|
|
|
|
# - to be more flexible...
|
|
|
|
|
# - check speed...
|
|
|
|
|
# - give the user more options...
|
2015-09-17 04:47:01 +03:00
|
|
|
# TODO use dcraw to extract/generate previews if we could not get any
|
|
|
|
|
# via exiftool
|
|
|
|
|
# dcraw -e $RAW
|
|
|
|
|
# - try and extract a preview
|
|
|
|
|
# - creates a file: $RAW-thumb.jpg
|
|
|
|
|
# dcraw -c $RAW | pnmtojpeg -quality=90 > $JPG
|
|
|
|
|
# - process raw and convert to jpeg (slow)
|
2019-04-05 02:04:03 +03:00
|
|
|
# TODO ignore raw images located in the ARCHIVE_ROOT directly...
|
2013-06-28 03:48:16 +04:00
|
|
|
|
|
|
|
|
# XXX need to also copy jpg originals to the preview dir (things that
|
|
|
|
|
# were shot in jpeg in-camera)...
|
2013-06-28 00:14:48 +04:00
|
|
|
# XXX need to prevent overwriting of unchanged exif data...
|
|
|
|
|
# when file exists??
|
2013-06-28 18:37:15 +04:00
|
|
|
# XXX add PSD metadata extraction...
|
2013-06-29 04:14:45 +04:00
|
|
|
# -execute '-FileModifyDate<DateTimeOriginal' -tagsfromfile @ \
|
|
|
|
|
# -srcfile "$PROCESSED_PREVIEW_NAME" -overwrite_original \
|
2013-06-28 18:37:15 +04:00
|
|
|
# XXX keep file dates...
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2013-09-01 11:47:55 +04:00
|
|
|
if [ -z $SKIP_ARCHIVE ] ; then
|
|
|
|
|
exiftool -if '$jpgfromraw' -b -jpgfromraw -w "$PREVIEW_NAME" \
|
|
|
|
|
-execute -if '$previewimage' -b -previewimage -w "$PREVIEW_NAME" \
|
2019-03-28 02:16:33 +03:00
|
|
|
-execute '-FileModifyDate<DateTimeOriginal' -addtagsfromfile @ \
|
|
|
|
|
-srcfile "$PREVIEW_NAME" '-all>all' '-xmp' \
|
|
|
|
|
-overwrite_original \
|
|
|
|
|
-execute -j -G -w "$JSON_NAME" \
|
2013-09-01 11:47:55 +04:00
|
|
|
-common_args --ext jpg -r "./$ARCHIVE_ROOT" -progress
|
|
|
|
|
fi
|
2013-06-28 00:14:48 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
SIZE=900
|
|
|
|
|
|
|
|
|
|
COMPRESSION=90
|
|
|
|
|
|
2013-07-03 03:14:40 +04:00
|
|
|
# XXX remove this in production...
|
2013-06-29 04:14:45 +04:00
|
|
|
PATH=$PATH:/mnt/d/Program\ Files/vips/bin/
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2013-09-01 11:47:55 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
# makepreview SIZE IN [OUT [SIZE [COMPRESSION]]]
|
|
|
|
|
#
|
|
|
|
|
# NOTE: SIZE and COMPRESSION will be set as follows (in order of priority):
|
|
|
|
|
# - explicit argument
|
|
|
|
|
# - global env var, if set
|
|
|
|
|
# - hardcoded default value
|
|
|
|
|
#
|
2019-03-31 15:35:19 +03:00
|
|
|
# TODO:
|
|
|
|
|
# - make this run in parallel
|
|
|
|
|
# - add option --mixed-previews and check preview size once per dir
|
|
|
|
|
# if it is not set...
|
|
|
|
|
#
|
2013-09-01 11:47:55 +04:00
|
|
|
# XXX cahnge global var names to be less generic...
|
2013-06-28 03:48:16 +04:00
|
|
|
makepreview(){
|
|
|
|
|
|
2013-09-01 11:47:55 +04:00
|
|
|
# arguments...
|
2013-06-28 03:48:16 +04:00
|
|
|
SIZE="$1"
|
|
|
|
|
IN="$2"
|
2013-09-01 11:47:55 +04:00
|
|
|
# output dir...
|
|
|
|
|
if [ -z $OUT ] ; then
|
|
|
|
|
# default...
|
|
|
|
|
# XXX is this correct??? (not generic enough...)
|
|
|
|
|
OUT="${IN/hi-res\ /preview }"
|
|
|
|
|
else
|
|
|
|
|
OUT="$3"
|
|
|
|
|
fi
|
|
|
|
|
# size...
|
|
|
|
|
if [ -z $4 ] ; then
|
|
|
|
|
if [ -z $SIZE ] ; then
|
|
|
|
|
# default...
|
|
|
|
|
SIZE=900
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
SIZE=$4
|
|
|
|
|
fi
|
|
|
|
|
# compression...
|
|
|
|
|
if [ -z $5 ] ; then
|
|
|
|
|
if [ -z $COMPRESSION ] ; then
|
|
|
|
|
# default...
|
|
|
|
|
COMPRESSION=90
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
COMPRESSION=$5
|
|
|
|
|
fi
|
|
|
|
|
|
2013-06-28 03:48:16 +04:00
|
|
|
|
2013-06-28 00:14:48 +04:00
|
|
|
# create preview dir if it does not already exist...
|
2013-07-03 01:44:03 +04:00
|
|
|
DIR="`dirname \"./${OUT}\"`"
|
|
|
|
|
if ! [ -e "./$DIR" ] ; then
|
|
|
|
|
mkdir -p "./$DIR"
|
2013-06-28 00:14:48 +04:00
|
|
|
fi
|
|
|
|
|
|
2013-06-28 00:23:04 +04:00
|
|
|
# create previews...
|
2013-07-03 01:44:03 +04:00
|
|
|
if ! [ -e "./${OUT}" ] ; then
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2013-06-28 00:23:04 +04:00
|
|
|
# get source size...
|
2013-06-28 03:48:16 +04:00
|
|
|
W=$(vips im_header_int width "$IN")
|
|
|
|
|
H=$(vips im_header_int height "$IN")
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2013-06-28 00:23:04 +04:00
|
|
|
# NOTE: vips appends nasty unprintable \r's to values, so we need to clean them out...
|
|
|
|
|
W=${W//[![:digit:]]/}
|
|
|
|
|
H=${H//[![:digit:]]/}
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2013-06-28 00:23:04 +04:00
|
|
|
# calculate the factor...
|
|
|
|
|
FACTOR=$(echo "scale = 4; if($H > $W) s = $H else s = $W ; s / $SIZE" | bc -l)
|
|
|
|
|
|
2015-09-17 02:56:20 +03:00
|
|
|
# NOTE: bash does not do float comparisons so we cheat again ;)
|
|
|
|
|
TOO_SMALL=$(echo "if($FACTOR <= 1) s = 1 else s = 0 ; s" | bc -l)
|
2013-06-28 00:14:48 +04:00
|
|
|
|
2015-09-17 02:56:20 +03:00
|
|
|
# the input is smaller than target size, copy as-is...
|
|
|
|
|
if [[ $TOO_SMALL == 1 ]] ; then
|
|
|
|
|
echo "$IN: Too small, copying as-is..."
|
|
|
|
|
|
|
|
|
|
cp "./$IN" "./$OUT"
|
|
|
|
|
|
|
|
|
|
# shrink...
|
|
|
|
|
else
|
|
|
|
|
echo "($FACTOR): ${OUT}:${COMPRESSION}"
|
|
|
|
|
|
|
|
|
|
vips im_shrink "./$IN" "./${OUT}:${COMPRESSION}" $FACTOR $FACTOR 2> /dev/null
|
|
|
|
|
fi
|
2013-09-01 11:47:55 +04:00
|
|
|
|
|
|
|
|
touch -c -r "./$IN" "./${OUT}"
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
echo "File already exists: ${OUT}"
|
2013-06-28 00:14:48 +04:00
|
|
|
fi
|
2013-06-28 03:48:16 +04:00
|
|
|
}
|
|
|
|
|
|
2013-09-01 11:47:55 +04:00
|
|
|
export SIZE COMPRESSION
|
|
|
|
|
export -f makepreview
|
2013-06-29 04:14:45 +04:00
|
|
|
|
2013-07-04 02:14:48 +04:00
|
|
|
cd "./${ARCHIVE_ROOT}"
|
2013-06-29 04:14:45 +04:00
|
|
|
|
2013-07-04 02:14:48 +04:00
|
|
|
|
2013-08-02 01:25:28 +04:00
|
|
|
|
2019-03-31 15:35:19 +03:00
|
|
|
# make low-res previews...
|
|
|
|
|
if [ -z $SKIP_PREVIEWS ] || [ $LOW_RES_PREVIEWS ] ; then
|
2019-03-31 16:04:34 +03:00
|
|
|
#find . -path '*hi-res (RAW)/*.jpg' -exec bash -c 'makepreview "$SIZE" "{}"' \;
|
|
|
|
|
find . -path '*hi-res (RAW)/*.jpg' -print0 \
|
|
|
|
|
| xargs -0 -n 1 -P $THREADS -I {} bash -c 'makepreview "$SIZE" "{}"'
|
2013-10-29 02:51:05 +04:00
|
|
|
fi
|
|
|
|
|
|
2013-09-01 11:47:55 +04:00
|
|
|
# collect previews to one location...
|
2013-10-29 09:23:49 +04:00
|
|
|
# XXX test!!!
|
2013-10-31 07:40:02 +04:00
|
|
|
if ! [ -z "$COMMON_PREVIEWS" ] ; then
|
2013-09-01 11:47:55 +04:00
|
|
|
if ! [ -e "./$COMMON_PREVIEWS" ] ; then
|
|
|
|
|
mkdir -p "./$COMMON_PREVIEWS"
|
|
|
|
|
fi
|
2015-09-07 15:06:45 +03:00
|
|
|
#if [ -z $TOTAL ] ; then
|
|
|
|
|
# export TOTAL=`find . -path '*hi-res (RAW)/*.jpg' | wc -l`
|
|
|
|
|
#fi
|
2019-02-18 03:29:36 +03:00
|
|
|
# XXX BUG: this does not rename if target exists...
|
2013-10-31 07:40:02 +04:00
|
|
|
find . -type d \
|
|
|
|
|
-name 'preview (RAW)' \
|
|
|
|
|
-print \
|
2019-02-19 16:33:14 +03:00
|
|
|
-exec cp --backup=t -rl "{}" "./$COMMON_PREVIEWS" \;
|
2013-10-31 07:40:02 +04:00
|
|
|
#-exec rm -rf "./$d"
|
2019-02-19 16:33:14 +03:00
|
|
|
|
|
|
|
|
# cleanup filenames... (HACK)
|
|
|
|
|
# image.jpg -> image_3.jpg
|
|
|
|
|
# image.jpg.~3~ -> image_2.jpg
|
|
|
|
|
# image.jpg.~2~ -> image_1.jpg
|
|
|
|
|
# image.jpg.~1~ -> image.jpg
|
|
|
|
|
#
|
|
|
|
|
i=0
|
|
|
|
|
while true ; do
|
|
|
|
|
i=$((i + 1))
|
|
|
|
|
images=("$COMMON_PREVIEWS/preview (RAW)/"*.~$i~)
|
|
|
|
|
|
|
|
|
|
# break if no matches...
|
|
|
|
|
if ! [ -e "${images[0]}" ] ; then
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
for img in "${images[@]}" ; do
|
|
|
|
|
# decrement...
|
|
|
|
|
# image.jpg.~(N)~ -> image_(N-1).jpg
|
|
|
|
|
mv "$img" "${img/.jpg.~${i}~/_$((i-1)).jpg}"
|
|
|
|
|
|
|
|
|
|
# next image does not exist...
|
|
|
|
|
# image.jpg -> image_(N).jpg
|
|
|
|
|
# image_0.jpg -> image.jpg
|
|
|
|
|
if ! [ -e "${img/.jpg.~${i}~/.jpg.~$((i+1))~}" ] ; then
|
|
|
|
|
mv "${img/.jpg.~${i}~/.jpg}" "${img/.jpg.~${i}~/_$((i)).jpg}"
|
|
|
|
|
mv "${img/.jpg.~${i}~/_0.jpg}" "${img/.jpg.~${i}~/.jpg}"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
done
|
2013-09-01 11:47:55 +04:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-10-29 09:23:49 +04:00
|
|
|
# build cache...
|
|
|
|
|
if [ -z $SKIP_CACHE ] ; then
|
2023-01-17 00:09:51 +03:00
|
|
|
|
|
|
|
|
# ig...
|
|
|
|
|
if ! [ -z `command -v ig` ] ; then
|
|
|
|
|
CACHE="ig init"
|
|
|
|
|
# buildcache (legacy)...
|
|
|
|
|
elif [ -z `command -v buildcache` ] ; then
|
|
|
|
|
# a little tweak to make build cache work...
|
|
|
|
|
export PYTHONIOENCODING=UTF-8
|
|
|
|
|
CACHE=buildcache
|
|
|
|
|
fi
|
|
|
|
|
|
2015-09-07 15:06:45 +03:00
|
|
|
#if [ -z $TOTAL ] ; then
|
|
|
|
|
# export TOTAL=`find . -path '*hi-res (RAW)/*.jpg' | wc -l`
|
|
|
|
|
#fi
|
2013-10-31 07:40:02 +04:00
|
|
|
if ! [ -z "$COMMON_PREVIEWS" ] && [ -e "./$COMMON_PREVIEWS/preview (RAW)" ] ; then
|
2023-01-17 00:09:51 +03:00
|
|
|
$CACHE "./$COMMON_PREVIEWS/preview (RAW)"
|
2013-10-31 07:40:02 +04:00
|
|
|
else
|
2023-01-17 00:09:51 +03:00
|
|
|
find . -type d -name 'preview (RAW)' -exec $CACHE "{}" \;
|
2013-10-31 07:40:02 +04:00
|
|
|
fi
|
2013-10-29 09:23:49 +04:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-29 04:14:45 +04:00
|
|
|
# vim:set nowrap nospell :
|