dotfiles/vifm/.config/vifm/scripts/vifm-thumbnailer
Marty Oehme 4abfc41ca2
vifm: Extend nsxiv thumbnailer
Now works recursively, only looks for fitting format extensions and can
display video thumbnails as well.

All options are documented in `-h` help display - `-r` enables recursive
lookup for directory current file is in, `-m` enables displaying video
thumbnails (takes a little longer to load) and `-t` starts nsxiv in
thumbnail mode.
2022-05-01 18:48:09 +02:00

116 lines
3 KiB
Bash
Executable file

#!/usr/bin/env bash
show_help() {
printf """
vifm-thumbnailer
Easily show images/thumbnails from the vifm file manager.
Usage: vifm-thumbnailer <current file>
Point it to a file whose directory you want thumbnailed.
If you point it to a directory itself, it will list its contents.
Options:
-h Display this help.
-r Show images recursively from current folder.
-t Open viewer in thumbnail mode.
-m Show thumbnails for video files in addition to image files.
Will take longer to load up and requires ffmpeg utilities.
Vifm:
If the file is on your path (e.g. in ~/.vifm/scripts) from within
vifm you can run the script by invoking it with:
\`:!vifm-thumbnailer \%%c\`
which will show all directory thumbnails with the current file
initially shown.
If you want to have vifm show a filtered view for selected files
afterwards add a \%%u to the command.
"""
}
TMPDIR="$(mktemp -d)"
valid_files_tmp="$TMPDIR/nsxiv_rifle_$$"
# get all files in directory
list_img_files() {
if exist fd; then
fd --max-depth="$maxdepth" -tf . "${1%/*}" | is_img_extension | sort | tee -a "$valid_files_tmp"
else
find -L "${1%/*}" -maxdepth "$maxdepth" -type f -print | is_img_extension | sort | tee -a "$valid_files_tmp"
fi
}
list_vid_files() {
# shellcheck disable=2016
find "${1%/*}" -mindepth 1 -maxdepth "$maxdepth" \( -type f -o -type l \) -printf "%P\0" |
xargs -r0 -n 20 -P 64 file -00 -L --mime-type -- |
xargs -r0 -n 2 sh -c '
case "$2" in
video/*) printf "%s\0" "$1";;
esac
' -- |
sort -z |
xargs -r0 -I FILE ffmpegthumbnailer -i FILE -o "$TMPDIR/FILE.jpg" -m -s 384
find -L "$TMPDIR/" -maxdepth "$maxdepth" -type f -print | sort | tee -a "$valid_files_tmp"
}
img_ext="jpe?g|png|gif|svg|webp|tiff|heif|avif|ico|bmp"
is_img_extension() {
grep -iE "\.($img_ext)$"
}
# TODO if marking video thumbnail - will use wrong temporary path on output, makes e.g. vifm %u not work
open() {
trap 'rm -rf -- $TMPDIR' TERM INT EXIT
current="$(list_img_files "$1" | grep -nF "$1")"
if [ "$videos" = true ]; then
list_vid_files "$1"
fi
[ "$thumbnails" = true ] && nsxiv_args="-t"
if [ -n "$current" ]; then
nsxiv "$nsxiv_args" -i -n "${current%%:*}" -o -- <"$valid_files_tmp"
else
# fallback incase file didn't have a valid extension, or we couldn't
# find it inside the list
nsxiv -o -i -- <"$valid_files_tmp"
fi
}
maxdepth=1
while getopts "mrt?h" opt; do
case "$opt" in
r)
maxdepth=100
;;
m)
videos=true
;;
t)
thumbnails=true
;;
h | \? | *)
show_help
exit 0
;;
esac
done
shift $((OPTIND - 1))
[ "$1" = '--' ] && shift
case "$1" in
"")
echo "Usage: ${0##*/} PICTURES" >&2
exit 1
;;
/*) open "$1" ;;
"~"/*) open "$HOME/${1#"~"/}" ;;
*) open "$PWD/$1" ;;
esac