mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
Merge branch 'master' of github.com:flynx/ImageGrid
This commit is contained in:
commit
c09b055ee5
@ -1,5 +1,18 @@
|
|||||||
|
sync-flash.sh
|
||||||
|
Syncs a camera flash card to an archive folder.
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
- process-archive.sh
|
||||||
|
- compress-archive.sh (optional)
|
||||||
|
- bash
|
||||||
|
|
||||||
|
For more info see:
|
||||||
|
sync-flash.sh --help
|
||||||
|
|
||||||
|
|
||||||
process-archive.sh
|
process-archive.sh
|
||||||
Processes and prepares the archive folder for viewing.
|
Processes and prepares the archive folder for viewing via
|
||||||
|
ImageGrid.Viewer.
|
||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- exiftool
|
- exiftool
|
||||||
@ -9,16 +22,18 @@ process-archive.sh
|
|||||||
|
|
||||||
XXX add self dependency check...
|
XXX add self dependency check...
|
||||||
|
|
||||||
|
For more info see:
|
||||||
process-archive.bat -- windows version of process-archive.sh (partial)
|
process-archive.sh --help
|
||||||
|
|
||||||
|
|
||||||
sync-flash.sh
|
compress-archive.sh
|
||||||
Syncs a camera flash card to an archive folder.
|
compresses raw files.
|
||||||
|
|
||||||
Dependencies:
|
By default this will NTFS compress sony ARW files, but other
|
||||||
- process-archive.sh
|
compression methods and raw formats are supported...
|
||||||
- bash
|
|
||||||
|
For more info see:
|
||||||
|
compress-archive.sh --help
|
||||||
|
|
||||||
|
|
||||||
update-exif.sh
|
update-exif.sh
|
||||||
@ -27,6 +42,12 @@ update-exif.sh
|
|||||||
Dependencies:
|
Dependencies:
|
||||||
- exiv2 (to be deprecated)
|
- exiv2 (to be deprecated)
|
||||||
|
|
||||||
|
For more info see:
|
||||||
|
update-exif.sh --help
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
flatten.sh
|
flatten.sh
|
||||||
Flatten flickr/instagram favorite folder structure created by
|
Flatten flickr/instagram favorite folder structure created by
|
||||||
@ -34,11 +55,13 @@ flatten.sh
|
|||||||
./<author>/<filename> -> ./ALL/<author> - <filename>
|
./<author>/<filename> -> ./ALL/<author> - <filename>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vips-tn.sh
|
vips-tn.sh
|
||||||
|
|
||||||
cleannwcache.bat
|
cleannwcache.bat
|
||||||
|
|
||||||
extract-metadata.sh
|
extract-metadata.sh
|
||||||
|
|
||||||
|
process-archive.bat -- windows version of process-archive.sh (partial)
|
||||||
|
|
||||||
|
|||||||
@ -29,11 +29,11 @@ printhelp(){
|
|||||||
echo "Arguments:"
|
echo "Arguments:"
|
||||||
echo " -h --help - print this help and exit."
|
echo " -h --help - print this help and exit."
|
||||||
echo
|
echo
|
||||||
echo " -bz -bzip2 - use bzip2 to compress (default)."
|
echo " -bz -bzip2 - use bzip2 to compress`[[ $ARCH == $ARCH_BZIP2 ]] && echo " (default)" || echo ""`."
|
||||||
echo " -gz -gzip - use gzip to compress."
|
echo " -gz -gzip - use gzip to compress`[[ $ARCH == $ARCH_GZIP ]] && echo " (default)" || echo ""`."
|
||||||
echo " -c -compact - use ntfs compression."
|
echo " -c -compact - use ntfs compression`[[ $ARCH == $ARCH_NTFS ]] && echo " (default)" || echo ""`."
|
||||||
echo
|
echo
|
||||||
echo " -ext EXT - set file extension to compress (default: ARW)"
|
echo " -ext EXT - set file extension to compress (default: ${EXT})"
|
||||||
echo " NOTE: only one -ext is supported now".
|
echo " NOTE: only one -ext is supported now".
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,8 @@ COUNT=1
|
|||||||
TITLE=""
|
TITLE=""
|
||||||
|
|
||||||
RSYNC=rsync
|
RSYNC=rsync
|
||||||
RSYNCFLAGS="-arptgoA --info=progress2,flist --human-readable"
|
#RSYNCFLAGS="-arptgoA --info=progress2,flist --human-readable"
|
||||||
|
RSYNCFLAGS="-arpt --info=progress2,flist --human-readable"
|
||||||
|
|
||||||
CP=cp
|
CP=cp
|
||||||
CPFLAGS=-Rpfv
|
CPFLAGS=-Rpfv
|
||||||
@ -14,6 +15,10 @@ CPFLAGS=-Rpfv
|
|||||||
COPY=$RSYNC
|
COPY=$RSYNC
|
||||||
COPYFLAGS=$RSYNCFLAGS
|
COPYFLAGS=$RSYNCFLAGS
|
||||||
|
|
||||||
|
COMPRESSOR=./compress-archive.sh
|
||||||
|
COMPRESS=1
|
||||||
|
|
||||||
|
|
||||||
# base mount dir...
|
# base mount dir...
|
||||||
# systems with /mnt
|
# systems with /mnt
|
||||||
if [ -d /mnt ] ; then
|
if [ -d /mnt ] ; then
|
||||||
@ -40,10 +45,20 @@ while true ; do
|
|||||||
echo " single shoot."
|
echo " single shoot."
|
||||||
echo " -l|-last last flash card in set, run"
|
echo " -l|-last last flash card in set, run"
|
||||||
echo " process-archive.sh after copying."
|
echo " process-archive.sh after copying."
|
||||||
echo " -b|-base the base dir to look for drives in"
|
echo " -b|-base BASE the base dir to look for drives in"
|
||||||
echo " default: $BASE"
|
echo " default: $BASE"
|
||||||
echo " --rsync use rsync (default)"
|
echo " --rsync use rsync (default)"
|
||||||
echo " --cp use cp"
|
echo " --cp use cp"
|
||||||
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
echo " --compress toggle archive compression"
|
||||||
|
echo " default: `[[ $COMPRESS ]] && echo "on" || echo "off"`"
|
||||||
|
fi
|
||||||
|
# notes...
|
||||||
|
echo
|
||||||
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
echo "NOTE: the index is fully usable during the compression stage"
|
||||||
|
fi
|
||||||
|
echo "NOTE: cp under Cygwin may messup permissions, use rsync."
|
||||||
echo
|
echo
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
@ -61,17 +76,24 @@ while true ; do
|
|||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-b|-base|--base)
|
-b|-base|--base)
|
||||||
BASE=1
|
BASE=$2
|
||||||
shift
|
shift 2
|
||||||
;;
|
;;
|
||||||
-cp|--cp)
|
-cp|--cp)
|
||||||
COPY=cp
|
COPY=cp
|
||||||
COPYFLAGS=-Rpfv
|
COPYFLAGS=-Rpfv
|
||||||
|
shift
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
-rsync|--rsync)
|
-rsync|--rsync)
|
||||||
COPY=$RSYNC
|
COPY=$RSYNC
|
||||||
COPYFLAGS=$RSYNCFLAGS
|
COPYFLAGS=$RSYNCFLAGS
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-compress|--compress)
|
||||||
|
COMPRESS=`[[ $COMPRESS ]] && echo "" || echo 1`
|
||||||
|
shift
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@ -99,7 +121,12 @@ while true ; do
|
|||||||
echo "Enter) copy drive ${DRIVE}"
|
echo "Enter) copy drive ${DRIVE}"
|
||||||
fi
|
fi
|
||||||
echo "2) build."
|
echo "2) build."
|
||||||
echo "3) quit."
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
echo "3) compresion is `[[ $COMPRESS ]] && echo "on" || echo "off"`"
|
||||||
|
echo "4) quit."
|
||||||
|
else
|
||||||
|
echo "3) quit."
|
||||||
|
fi
|
||||||
read -p ": " RES
|
read -p ": " RES
|
||||||
|
|
||||||
case $RES in
|
case $RES in
|
||||||
@ -126,8 +153,15 @@ while true ; do
|
|||||||
LAST=1
|
LAST=1
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
|
|
||||||
3)
|
3)
|
||||||
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
COMPRESS=`[[ ! $COMPRESS ]] && echo 1 || echo ""`
|
||||||
|
else
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
4)
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@ -138,6 +172,17 @@ while true ; do
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# sanity check...
|
||||||
|
if ! [ -e "${BASE}/${DRIVE}" ] ; then
|
||||||
|
echo
|
||||||
|
echo "ERR: ${BASE}/${DRIVE}: does not exist, nothing to copy."
|
||||||
|
echo
|
||||||
|
if [[ $INTERACTIVE || ! $DRIVE ]] ; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
# XXX do a real three digit count...
|
# XXX do a real three digit count...
|
||||||
# single flash card...
|
# single flash card...
|
||||||
SCOUNT=`printf "%03d" $COUNT`
|
SCOUNT=`printf "%03d" $COUNT`
|
||||||
@ -166,7 +211,7 @@ while true ; do
|
|||||||
|
|
||||||
mkdir -vp "$DIR"
|
mkdir -vp "$DIR"
|
||||||
|
|
||||||
echo "Copying files from ${BASE}/${DRIVE}..."
|
echo "Copying files from ${BASE}/${DRIVE} (`du -hs "${BASE}/${DRIVE}" | cut -f 1`)..."
|
||||||
$COPY $COPYFLAGS ${BASE}/${DRIVE}/* "$DIR"
|
$COPY $COPYFLAGS ${BASE}/${DRIVE}/* "$DIR"
|
||||||
echo "Copying files: done."
|
echo "Copying files: done."
|
||||||
|
|
||||||
@ -187,4 +232,13 @@ if [[ ! $MULTI || $LAST ]] ; then
|
|||||||
echo "Building archive: done."
|
echo "Building archive: done."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ $COMPRESS ]] ; then
|
||||||
|
echo "Compressing archive..."
|
||||||
|
${COMPRESSOR} "$BASE_DIR"
|
||||||
|
echo "Compressing archive: done."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "`basename "$0"`: done."
|
||||||
|
|
||||||
|
# vim:set nowrap :
|
||||||
|
|||||||
@ -1,7 +1,32 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DIR=`pwd`
|
DIR=`pwd`
|
||||||
|
|
||||||
|
printhelp(){
|
||||||
|
echo "Usage: `basename $0` [ARGUMENTS] [PATH]"
|
||||||
|
echo
|
||||||
|
echo "Arguments:"
|
||||||
|
echo " -h --help - print this help and exit."
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
while true ; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
printhelp
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exifup(){
|
exifup(){
|
||||||
PREVIEW_DIR=$1
|
PREVIEW_DIR=$1
|
||||||
|
|||||||
92
ui (gen4)/archive/media/img/my/work/compress-archive.sh
Normal file
92
ui (gen4)/archive/media/img/my/work/compress-archive.sh
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# TODO make this runnable from anywhere...
|
||||||
|
# - prepend paths with './' only if local/relative
|
||||||
|
|
||||||
|
BASE_PATH=.
|
||||||
|
|
||||||
|
|
||||||
|
ARCH_BZIP2='bzip2 -v {}'
|
||||||
|
ARCH_GZIP='gzip -v {}'
|
||||||
|
# XXX should we cygpath -w all the inputs???
|
||||||
|
ARCH_NTFS='compact /c /exe:lzx {}'
|
||||||
|
|
||||||
|
|
||||||
|
# default...
|
||||||
|
ARCH=$ARCH_NTFS
|
||||||
|
|
||||||
|
|
||||||
|
EXT=ARW
|
||||||
|
|
||||||
|
# HACK: this is here to avoid using windows find...
|
||||||
|
PATH=/bin:$PATH
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
printhelp(){
|
||||||
|
echo "Usage: `basename $0` [ARGUMENTS] [PATH]"
|
||||||
|
echo
|
||||||
|
echo "Arguments:"
|
||||||
|
echo " -h --help - print this help and exit."
|
||||||
|
echo
|
||||||
|
echo " -bz -bzip2 - use bzip2 to compress`[[ $ARCH == $ARCH_BZIP2 ]] && echo " (default)" || echo ""`."
|
||||||
|
echo " -gz -gzip - use gzip to compress`[[ $ARCH == $ARCH_GZIP ]] && echo " (default)" || echo ""`."
|
||||||
|
echo " -c -compact - use ntfs compression`[[ $ARCH == $ARCH_NTFS ]] && echo " (default)" || echo ""`."
|
||||||
|
echo
|
||||||
|
echo " -ext EXT - set file extension to compress (default: ${EXT})"
|
||||||
|
echo " NOTE: only one -ext is supported now".
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# process args...
|
||||||
|
while true ; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
printhelp
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
|
||||||
|
# archivers...
|
||||||
|
-bz|--bzip2)
|
||||||
|
ARCH=$ARCH_BZIP2
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-gz|--gzip)
|
||||||
|
ARCH=$ARCH_GZIP
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-c|--compact)
|
||||||
|
ARCH=$ARCH_NTFS
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
# extension to compress...
|
||||||
|
--ext)
|
||||||
|
EXT=$2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# get path...
|
||||||
|
if [ "$1" ] ; then
|
||||||
|
BASE_PATH=$1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# do the work...
|
||||||
|
find "$BASE_PATH" -name \*.${EXT} -exec ${ARCH} \;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo done.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set nowrap nospell :
|
||||||
@ -5,7 +5,8 @@ COUNT=1
|
|||||||
TITLE=""
|
TITLE=""
|
||||||
|
|
||||||
RSYNC=rsync
|
RSYNC=rsync
|
||||||
RSYNCFLAGS="-arptgoA --info=progress2,flist --human-readable"
|
#RSYNCFLAGS="-arptgoA --info=progress2,flist --human-readable"
|
||||||
|
RSYNCFLAGS="-arpt --info=progress2,flist --human-readable"
|
||||||
|
|
||||||
CP=cp
|
CP=cp
|
||||||
CPFLAGS=-Rpfv
|
CPFLAGS=-Rpfv
|
||||||
@ -14,6 +15,10 @@ CPFLAGS=-Rpfv
|
|||||||
COPY=$RSYNC
|
COPY=$RSYNC
|
||||||
COPYFLAGS=$RSYNCFLAGS
|
COPYFLAGS=$RSYNCFLAGS
|
||||||
|
|
||||||
|
COMPRESSOR=./compress-archive.sh
|
||||||
|
COMPRESS=1
|
||||||
|
|
||||||
|
|
||||||
# base mount dir...
|
# base mount dir...
|
||||||
# systems with /mnt
|
# systems with /mnt
|
||||||
if [ -d /mnt ] ; then
|
if [ -d /mnt ] ; then
|
||||||
@ -40,10 +45,20 @@ while true ; do
|
|||||||
echo " single shoot."
|
echo " single shoot."
|
||||||
echo " -l|-last last flash card in set, run"
|
echo " -l|-last last flash card in set, run"
|
||||||
echo " process-archive.sh after copying."
|
echo " process-archive.sh after copying."
|
||||||
echo " -b|-base the base dir to look for drives in"
|
echo " -b|-base BASE the base dir to look for drives in"
|
||||||
echo " default: $BASE"
|
echo " default: $BASE"
|
||||||
echo " --rsync use rsync (default)"
|
echo " --rsync use rsync (default)"
|
||||||
echo " --cp use cp"
|
echo " --cp use cp"
|
||||||
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
echo " --compress toggle archive compression"
|
||||||
|
echo " default: `[[ $COMPRESS ]] && echo "on" || echo "off"`"
|
||||||
|
fi
|
||||||
|
# notes...
|
||||||
|
echo
|
||||||
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
echo "NOTE: the index is fully usable during the compression stage"
|
||||||
|
fi
|
||||||
|
echo "NOTE: cp under Cygwin may messup permissions, use rsync."
|
||||||
echo
|
echo
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
@ -61,17 +76,24 @@ while true ; do
|
|||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-b|-base|--base)
|
-b|-base|--base)
|
||||||
BASE=1
|
BASE=$2
|
||||||
shift
|
shift 2
|
||||||
;;
|
;;
|
||||||
-cp|--cp)
|
-cp|--cp)
|
||||||
COPY=cp
|
COPY=cp
|
||||||
COPYFLAGS=-Rpfv
|
COPYFLAGS=-Rpfv
|
||||||
|
shift
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
-rsync|--rsync)
|
-rsync|--rsync)
|
||||||
COPY=$RSYNC
|
COPY=$RSYNC
|
||||||
COPYFLAGS=$RSYNCFLAGS
|
COPYFLAGS=$RSYNCFLAGS
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-compress|--compress)
|
||||||
|
COMPRESS=`[[ $COMPRESS ]] && echo "" || echo 1`
|
||||||
|
shift
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@ -99,7 +121,12 @@ while true ; do
|
|||||||
echo "Enter) copy drive ${DRIVE}"
|
echo "Enter) copy drive ${DRIVE}"
|
||||||
fi
|
fi
|
||||||
echo "2) build."
|
echo "2) build."
|
||||||
echo "3) quit."
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
echo "3) compresion is `[[ $COMPRESS ]] && echo "on" || echo "off"`"
|
||||||
|
echo "4) quit."
|
||||||
|
else
|
||||||
|
echo "3) quit."
|
||||||
|
fi
|
||||||
read -p ": " RES
|
read -p ": " RES
|
||||||
|
|
||||||
case $RES in
|
case $RES in
|
||||||
@ -126,8 +153,15 @@ while true ; do
|
|||||||
LAST=1
|
LAST=1
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
|
|
||||||
3)
|
3)
|
||||||
|
if ! [ -z $COMPRESSOR ] ; then
|
||||||
|
COMPRESS=`[[ ! $COMPRESS ]] && echo 1 || echo ""`
|
||||||
|
else
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
4)
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@ -138,6 +172,17 @@ while true ; do
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# sanity check...
|
||||||
|
if ! [ -e "${BASE}/${DRIVE}" ] ; then
|
||||||
|
echo
|
||||||
|
echo "ERR: ${BASE}/${DRIVE}: does not exist, nothing to copy."
|
||||||
|
echo
|
||||||
|
if [[ $INTERACTIVE || ! $DRIVE ]] ; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
# XXX do a real three digit count...
|
# XXX do a real three digit count...
|
||||||
# single flash card...
|
# single flash card...
|
||||||
SCOUNT=`printf "%03d" $COUNT`
|
SCOUNT=`printf "%03d" $COUNT`
|
||||||
@ -166,7 +211,7 @@ while true ; do
|
|||||||
|
|
||||||
mkdir -vp "$DIR"
|
mkdir -vp "$DIR"
|
||||||
|
|
||||||
echo "Copying files from ${BASE}/${DRIVE}..."
|
echo "Copying files from ${BASE}/${DRIVE} (`du -hs "${BASE}/${DRIVE}" | cut -f 1`)..."
|
||||||
$COPY $COPYFLAGS ${BASE}/${DRIVE}/* "$DIR"
|
$COPY $COPYFLAGS ${BASE}/${DRIVE}/* "$DIR"
|
||||||
echo "Copying files: done."
|
echo "Copying files: done."
|
||||||
|
|
||||||
@ -187,4 +232,13 @@ if [[ ! $MULTI || $LAST ]] ; then
|
|||||||
echo "Building archive: done."
|
echo "Building archive: done."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ $COMPRESS ]] ; then
|
||||||
|
echo "Compressing archive..."
|
||||||
|
${COMPRESSOR} "$BASE_DIR"
|
||||||
|
echo "Compressing archive: done."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "`basename "$0"`: done."
|
||||||
|
|
||||||
|
# vim:set nowrap :
|
||||||
|
|||||||
@ -1,7 +1,32 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DIR=`pwd`
|
DIR=`pwd`
|
||||||
|
|
||||||
|
printhelp(){
|
||||||
|
echo "Usage: `basename $0` [ARGUMENTS] [PATH]"
|
||||||
|
echo
|
||||||
|
echo "Arguments:"
|
||||||
|
echo " -h --help - print this help and exit."
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
while true ; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
printhelp
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exifup(){
|
exifup(){
|
||||||
PREVIEW_DIR=$1
|
PREVIEW_DIR=$1
|
||||||
|
|||||||
@ -524,17 +524,52 @@ var BaseItemPrototype = {
|
|||||||
: undefined },
|
: undefined },
|
||||||
|
|
||||||
|
|
||||||
// XXX BUG: this does not work for nested header elements...
|
// NOTE: these should not clash with user-supplied handlers ('update' does not)...
|
||||||
|
//
|
||||||
|
// XXX BUG: calling this on a nested/inlined browser will mess things up...
|
||||||
|
// ...the issue seems to be with root options not being available
|
||||||
|
// for partial render in a nested context...
|
||||||
|
// ...one way to fix this would be to make the options inheritance
|
||||||
|
// protocol more strict:
|
||||||
|
// - if no options given use defaults (i.e. this.options)
|
||||||
|
// - if options given use as-is
|
||||||
|
// - defaults are taken from this.options if not present
|
||||||
|
//
|
||||||
// to reproduce:
|
// to reproduce:
|
||||||
// dialog
|
// dialog.disable('2')
|
||||||
// .get({children: true})
|
// or:
|
||||||
// .update()
|
// dialog.disable('B/C/D/a')
|
||||||
// ...for some reason the affected element is removed from dom...
|
//
|
||||||
|
// ...in both cases the whole nested browser disappears...
|
||||||
|
//
|
||||||
|
// but this works OK:
|
||||||
|
// dialog.disable('nested/2')
|
||||||
|
//
|
||||||
|
// This might also be a side effect of the .dom / .elem set of
|
||||||
|
// issues...
|
||||||
|
//
|
||||||
|
// This issue seems to go away after expanding/collapsing the
|
||||||
|
// nested item several times, the buttons are gone but the
|
||||||
|
// subtrees stop vanishing on update -- could this be related
|
||||||
|
// to .dom/.elem again???
|
||||||
update: function(options){
|
update: function(options){
|
||||||
this.parent
|
this.parent
|
||||||
&& this.parent.render(this, options)
|
&& this.parent.render(this, options)
|
||||||
return this
|
return this },
|
||||||
},
|
/* XXX this is disabled to avoid user confusion when a user item
|
||||||
|
// event handler would not call/replicate the top-level (this)
|
||||||
|
// functionality and this break code relying on it...
|
||||||
|
// ...for this to work well need to either:
|
||||||
|
// - separate item options form the item object,
|
||||||
|
// - force the user to follow strict protocols,
|
||||||
|
// - use a proxy when accessing items (reverse of #1)
|
||||||
|
// XXX this also applies to .update(..) above...
|
||||||
|
focus: function(){
|
||||||
|
arguments.length == 0
|
||||||
|
&& this.parent
|
||||||
|
&& this.parent.focus(this)
|
||||||
|
return this },
|
||||||
|
//*/
|
||||||
|
|
||||||
|
|
||||||
__init__(...state){
|
__init__(...state){
|
||||||
@ -785,6 +820,9 @@ object.Constructor('BaseRenderer', {
|
|||||||
// placeholders...
|
// placeholders...
|
||||||
root: null,
|
root: null,
|
||||||
|
|
||||||
|
isRendered: function(){
|
||||||
|
throw new Error('.isRendered(..): Not implemented.') },
|
||||||
|
|
||||||
// component renderers...
|
// component renderers...
|
||||||
elem: function(item, index, path, options){
|
elem: function(item, index, path, options){
|
||||||
throw new Error('.elem(..): Not implemented.') },
|
throw new Error('.elem(..): Not implemented.') },
|
||||||
@ -810,6 +848,9 @@ module.TextRenderer =
|
|||||||
object.Constructor('TextRenderer', {
|
object.Constructor('TextRenderer', {
|
||||||
__proto__: BaseRenderer.prototype,
|
__proto__: BaseRenderer.prototype,
|
||||||
|
|
||||||
|
// always render...
|
||||||
|
isRendered: function(){ return false },
|
||||||
|
|
||||||
elem: function(item, index, path, options){
|
elem: function(item, index, path, options){
|
||||||
return path
|
return path
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
@ -840,6 +881,9 @@ module.PathRenderer =
|
|||||||
object.Constructor('PathRenderer', {
|
object.Constructor('PathRenderer', {
|
||||||
__proto__: TextRenderer.prototype,
|
__proto__: TextRenderer.prototype,
|
||||||
|
|
||||||
|
// always render...
|
||||||
|
isRendered: function(){ return false },
|
||||||
|
|
||||||
elem: function(item, index, path, options){
|
elem: function(item, index, path, options){
|
||||||
return path.join('/') },
|
return path.join('/') },
|
||||||
inline: function(item, lst, index, path, options){
|
inline: function(item, lst, index, path, options){
|
||||||
@ -2654,10 +2698,14 @@ var BaseBrowserPrototype = {
|
|||||||
return r && typeof(e) != typeof({}) }, true))){
|
return r && typeof(e) != typeof({}) }, true))){
|
||||||
// reverse index...
|
// reverse index...
|
||||||
index = this
|
index = this
|
||||||
.reduce(function(res, e, i, p){
|
.reduce(
|
||||||
res.set(e, [i, p])
|
function(res, e, i, p){
|
||||||
return res
|
res.set(e, [i, p])
|
||||||
}, new Map(), {iterateAll: true})
|
return res },
|
||||||
|
new Map(),
|
||||||
|
Object.assign(
|
||||||
|
Object.flatCopy(options || {}),
|
||||||
|
{iterateAll: true}))
|
||||||
var res
|
var res
|
||||||
var Stop = new Error('Stop iteration')
|
var Stop = new Error('Stop iteration')
|
||||||
try {
|
try {
|
||||||
@ -2676,7 +2724,10 @@ var BaseBrowserPrototype = {
|
|||||||
throw Stop })
|
throw Stop })
|
||||||
: pattern ]
|
: pattern ]
|
||||||
// search...
|
// search...
|
||||||
: that.search(pattern, ...args.slice(1)) })
|
: !(pattern instanceof BaseItem) ?
|
||||||
|
that.search(pattern, ...args.slice(1))
|
||||||
|
// not found...
|
||||||
|
: [] })
|
||||||
.flat()
|
.flat()
|
||||||
.unique()
|
.unique()
|
||||||
} catch(e){
|
} catch(e){
|
||||||
@ -2946,6 +2997,13 @@ var BaseBrowserPrototype = {
|
|||||||
|
|
||||||
__renderer__: TextRenderer,
|
__renderer__: TextRenderer,
|
||||||
|
|
||||||
|
isRendered: function(renderer){
|
||||||
|
var render = renderer || this.__renderer__
|
||||||
|
render = render.root == null ?
|
||||||
|
new render(this, this.options)
|
||||||
|
: render
|
||||||
|
return render.isRendered() },
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render browser...
|
// Render browser...
|
||||||
// .render([options])
|
// .render([options])
|
||||||
@ -3594,19 +3652,39 @@ var BaseBrowserPrototype = {
|
|||||||
// XXX should we force calling update if options are given???
|
// XXX should we force calling update if options are given???
|
||||||
// ...and should full get passed if at least one call in sequence
|
// ...and should full get passed if at least one call in sequence
|
||||||
// got a full=true???
|
// got a full=true???
|
||||||
__update_full: undefined,
|
// XXX supported mdoes:
|
||||||
|
// 'full' | true - make - render - post-render
|
||||||
|
// 'normal' - render - post-render
|
||||||
|
// 'partial' - post-render
|
||||||
|
__update_mode: undefined,
|
||||||
__update_args: undefined,
|
__update_args: undefined,
|
||||||
__update_timeout: undefined,
|
__update_timeout: undefined,
|
||||||
__update_max_timeout: undefined,
|
__update_max_timeout: undefined,
|
||||||
update: makeEventMethod('update',
|
update: makeEventMethod('update',
|
||||||
function(evt, full, options){
|
function(evt, mode, options){
|
||||||
options =
|
var modes = [
|
||||||
(full && full !== true && full !== false) ?
|
'full',
|
||||||
full
|
'normal',
|
||||||
: options
|
'partial',
|
||||||
full = full === options ?
|
]
|
||||||
false
|
|
||||||
: full
|
options = mode instanceof Object ?
|
||||||
|
mode
|
||||||
|
: options
|
||||||
|
mode = mode === options ?
|
||||||
|
'normal'
|
||||||
|
: mode === true ?
|
||||||
|
'full'
|
||||||
|
: mode
|
||||||
|
// sanity check...
|
||||||
|
if(!modes.includes(mode)){
|
||||||
|
throw new Error(`.update(..): unsupported mode: ${mode}`) }
|
||||||
|
var m = this.__update_mode
|
||||||
|
// if the queued mode is deeper than the requested, ignore the requested...
|
||||||
|
if(m != null && modes.indexOf(mode) > modes.indexOf(m)){
|
||||||
|
return this }
|
||||||
|
|
||||||
|
// queue update...
|
||||||
// NOTE: we can't simply use _update(..) closure for this as
|
// NOTE: we can't simply use _update(..) closure for this as
|
||||||
// it can be called out of two contexts (timeout and
|
// it can be called out of two contexts (timeout and
|
||||||
// max_timeout), one (timeout) is renewed on each call
|
// max_timeout), one (timeout) is renewed on each call
|
||||||
@ -3616,14 +3694,14 @@ var BaseBrowserPrototype = {
|
|||||||
// its setTimeout(..)...
|
// its setTimeout(..)...
|
||||||
// storing the arguments in .__update_args would remove
|
// storing the arguments in .__update_args would remove
|
||||||
// this inconsistency...
|
// this inconsistency...
|
||||||
|
this.__update_mode = mode
|
||||||
var args = this.__update_args = [
|
var args = this.__update_args = [
|
||||||
[evt, full,
|
[evt, mode,
|
||||||
...(options ?
|
...(options ?
|
||||||
[options]
|
[options]
|
||||||
: [])],
|
: [])],
|
||||||
options]
|
options]
|
||||||
this.__update_full = (full && args)
|
|
||||||
|| this.__update_full
|
|
||||||
var timeout = (options || {}).updateTimeout
|
var timeout = (options || {}).updateTimeout
|
||||||
|| this.options.updateTimeout
|
|| this.options.updateTimeout
|
||||||
var max_timeout = (options || {}).updateMaxDelay
|
var max_timeout = (options || {}).updateMaxDelay
|
||||||
@ -3637,20 +3715,22 @@ var BaseBrowserPrototype = {
|
|||||||
delete this.__update_timeout }.bind(this)
|
delete this.__update_timeout }.bind(this)
|
||||||
var _update = function(){
|
var _update = function(){
|
||||||
_clear_timers()
|
_clear_timers()
|
||||||
var full = !!this.__update_full
|
var mode = this.__update_mode
|
||||||
var [args, opts] = this.__update_full
|
var [args, opts] = this.__update_args
|
||||||
|| this.__update_args
|
|
||||||
|
|
||||||
delete this.__update_full
|
delete this.__update_mode
|
||||||
delete this.__update_args
|
delete this.__update_args
|
||||||
|
|
||||||
full
|
// make...
|
||||||
|
modes.indexOf(mode) <= modes.indexOf('full')
|
||||||
&& this.make(opts)
|
&& this.make(opts)
|
||||||
var context = {}
|
// render...
|
||||||
this
|
;(!this.isRendered((opts || {}).renderer)
|
||||||
// XXX this needs access to render context....
|
|| modes.indexOf(mode) <= modes.indexOf('normal'))
|
||||||
.preRender(opts, (opts || {}).renderer, context)
|
&& this
|
||||||
.render(opts, (opts || {}).renderer, context)
|
.preRender(opts, (opts || {}).renderer)
|
||||||
|
.render(opts, (opts || {}).renderer)
|
||||||
|
// update...
|
||||||
this.trigger(...args) }.bind(this)
|
this.trigger(...args) }.bind(this)
|
||||||
var _update_n_delay = function(){
|
var _update_n_delay = function(){
|
||||||
// call...
|
// call...
|
||||||
@ -3771,6 +3851,7 @@ object.Constructor('BaseBrowser',
|
|||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
// HTML-specific UI...
|
||||||
|
|
||||||
var KEYBOARD_CONFIG =
|
var KEYBOARD_CONFIG =
|
||||||
module.KEYBOARD_CONFIG = {
|
module.KEYBOARD_CONFIG = {
|
||||||
@ -4034,17 +4115,17 @@ var updateElemClass = function(action, cls, handler){
|
|||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Renderer...
|
// HTML Renderer...
|
||||||
|
|
||||||
// XXX needs testing...
|
|
||||||
// - partial rendering...
|
|
||||||
// - local re-rendering...
|
|
||||||
// XXX HACK: see .nest(..)
|
// XXX HACK: see .nest(..)
|
||||||
var HTMLRenderer =
|
var HTMLRenderer =
|
||||||
module.HTMLRenderer =
|
module.HTMLRenderer =
|
||||||
object.Constructor('HTMLRenderer', {
|
object.Constructor('HTMLRenderer', {
|
||||||
__proto__: BaseRenderer.prototype,
|
__proto__: BaseRenderer.prototype,
|
||||||
|
|
||||||
|
isRendered: function(){
|
||||||
|
return !!this.root.dom },
|
||||||
|
|
||||||
// secondary renderers...
|
// secondary renderers...
|
||||||
//
|
//
|
||||||
// base dialog...
|
// base dialog...
|
||||||
@ -4654,7 +4735,6 @@ var HTMLBrowserPrototype = {
|
|||||||
__item__: HTMLItem,
|
__item__: HTMLItem,
|
||||||
__renderer__: HTMLRenderer,
|
__renderer__: HTMLRenderer,
|
||||||
|
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
__proto__: BaseBrowser.prototype.options,
|
__proto__: BaseBrowser.prototype.options,
|
||||||
|
|
||||||
@ -5045,29 +5125,28 @@ var HTMLBrowserPrototype = {
|
|||||||
__copy: function(text){
|
__copy: function(text){
|
||||||
navigator.clipboard.writeText(text || this.path) },
|
navigator.clipboard.writeText(text || this.path) },
|
||||||
|
|
||||||
// XXX need a better name...
|
|
||||||
_updateDOMItems: function(){
|
// Events extensions...
|
||||||
|
//
|
||||||
|
// XXX should tweaking DOM be done here or in the renderer???
|
||||||
|
__update__: function(){
|
||||||
var c = 0
|
var c = 0
|
||||||
this.forEach(function(e){
|
this.forEach(function(e){
|
||||||
// shortcut number hint...
|
// shortcut number hint...
|
||||||
if(c < 10 && !e.disabled && !e.hidden){
|
if(c < 10 && !e.disabled && !e.hidden){
|
||||||
var a = e.attrs = e.attrs || {}
|
var a = e.attrs = e.attrs || {}
|
||||||
c = a['shortcut-number'] = (++c) % 10
|
|
||||||
e.elem
|
e.elem
|
||||||
&& e.elem.setAttribute('shortcut-number', c)
|
&& e.elem.setAttribute('shortcut-number',
|
||||||
|
a['shortcut-number'] = (c+1) % 10)
|
||||||
// cleanup...
|
// cleanup...
|
||||||
} else {
|
} else {
|
||||||
delete (e.attrs || {})['shortcut-number']
|
delete (e.attrs || {})['shortcut-number']
|
||||||
e.elem
|
e.elem
|
||||||
&& e.elem.removeAttribute('shortcut-number')
|
&& e.elem.removeAttribute('shortcut-number')
|
||||||
}
|
}
|
||||||
|
c++
|
||||||
}) },
|
}) },
|
||||||
|
|
||||||
// Events extensions...
|
|
||||||
//
|
|
||||||
// NOTE: this will also kill any user-set keys for disabled/hidden items...
|
// NOTE: this will also kill any user-set keys for disabled/hidden items...
|
||||||
//
|
|
||||||
// XXX also handle global button keys...
|
// XXX also handle global button keys...
|
||||||
__preRender__: function(evt, options, renderer, context){
|
__preRender__: function(evt, options, renderer, context){
|
||||||
var that = this
|
var that = this
|
||||||
@ -5079,18 +5158,6 @@ var HTMLBrowserPrototype = {
|
|||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
this.map(function(e){
|
this.map(function(e){
|
||||||
// shortcut number hint...
|
|
||||||
// NOTE: these are just hints, the actual keys are handled
|
|
||||||
// in .keybindings...
|
|
||||||
// XXX move this to the renderer...
|
|
||||||
if(i < 10 && !e.disabled && !e.hidden){
|
|
||||||
var attrs = e.attrs = e.attrs || {}
|
|
||||||
attrs['shortcut-number'] = (++i) % 10
|
|
||||||
// cleanup...
|
|
||||||
} else {
|
|
||||||
delete (e.attrs || {})['shortcut-number']
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle item keys...
|
// handle item keys...
|
||||||
if(!e.disabled && !e.hidden){
|
if(!e.disabled && !e.hidden){
|
||||||
;((e.value instanceof Array ?
|
;((e.value instanceof Array ?
|
||||||
@ -5140,7 +5207,7 @@ var HTMLBrowserPrototype = {
|
|||||||
block: 'nearest',
|
block: 'nearest',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
// set focus...
|
// XXX do we need this???
|
||||||
.focus() },
|
.focus() },
|
||||||
__blur__: function(evt, elem){
|
__blur__: function(evt, elem){
|
||||||
var that = this
|
var that = this
|
||||||
@ -5157,14 +5224,22 @@ var HTMLBrowserPrototype = {
|
|||||||
// element up to reveal the expanded subtree...
|
// element up to reveal the expanded subtree...
|
||||||
// ...would also be logical to "show" the expanded tree but
|
// ...would also be logical to "show" the expanded tree but
|
||||||
// keeping the focused elem in view...
|
// keeping the focused elem in view...
|
||||||
__expand__: function(evt, elem){ elem.update() },
|
__expand__: function(evt, elem){
|
||||||
__collapse__: function(evt, elem){ elem.update() },
|
elem.update()
|
||||||
|
this.update('partial') },
|
||||||
|
__collapse__: function(evt, elem){
|
||||||
|
elem.update()
|
||||||
|
this.update('partial') },
|
||||||
__select__: updateElemClass('add', 'selected'),
|
__select__: updateElemClass('add', 'selected'),
|
||||||
__deselect__: updateElemClass('remove', 'selected'),
|
__deselect__: updateElemClass('remove', 'selected'),
|
||||||
__disable__: updateElemClass('add', 'disabled',
|
__disable__: updateElemClass('add', 'disabled',
|
||||||
function(evt, elem){ elem.update() }),
|
function(evt, elem){
|
||||||
|
elem.update()
|
||||||
|
this.update('partial') }),
|
||||||
__enable__: updateElemClass('remove', 'disabled',
|
__enable__: updateElemClass('remove', 'disabled',
|
||||||
function(evt, elem){ elem.update() }),
|
function(evt, elem){
|
||||||
|
elem.update()
|
||||||
|
this.update('partial') }),
|
||||||
__hide__: updateElemClass('add', 'hidden'),
|
__hide__: updateElemClass('add', 'hidden'),
|
||||||
__show__: updateElemClass('remove', 'hidden'),
|
__show__: updateElemClass('remove', 'hidden'),
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user