Created
July 23, 2019 10:59
-
-
Save hackerb9/fe209e749a01efeddbc9d0e638bac3e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# XXX showanddelete hacked to show best view by default and to | |
# change the image every five seconds if no key pressed. | |
# Maximum number of seconds to wait for a response from the terminal | |
# after a an escape sequence query. Usually, terminals respond much | |
# faster than 0.1 seconds, but may need to be increased for slow links | |
# (e.g., RS232C, ssh). | |
TIMEOUT=0.1 | |
# Default sixel geometry if terminal does not respond to queries. | |
DEFAULT_WIDTH=800; DEFAULT_HEIGHT=480 | |
cleanup() { | |
# If the user hits ^C, we don't want them stuck in SIXEL mode | |
echo -n $'\e[?80h' # Reenable sixel scrolling | |
echo -n $'\e\\' # Escape sequence to stop SIXEL | |
tput el | |
exit 0 | |
} | |
trap cleanup SIGINT SIGHUP SIGABRT | |
getwindowsize() { | |
# Send control sequences to find how large of a sixel image can be shown. | |
# Prints geometry as width then height. | |
local -i x y # for reading width and height integers | |
local d # dummy variable | |
# Before querying the terminal, wait for it to be ready. | |
waitforterminal | |
# Send control sequence to query the sixel graphics geometry. | |
IFS=";" read -s -t ${TIMEOUT} -d "S" -p $'\e[?2;1;0S' d d x y d >&2 | |
if [[ $? -ne 0 ]]; then | |
# Fall back to dtterm WindowOps to approximate sixel geometry. | |
IFS=";" read -s -t ${TIMEOUT} -d "t" -p $'\e[14t' d x y d >&2 | |
fi | |
# Return the results (or the default if querying didn't work) | |
[[ x -gt 0 ]] || x=${DEFAULT_WIDTH} | |
[[ y -gt 0 ]] || y=${DEFAULT_HEIGHT} | |
echo $x $y | |
return | |
} | |
waitforterminal() { | |
# Send an escape sequence and wait for a response from the terminal. | |
# This routine will let us know when an image transfer has finished | |
# and it's okay to send escape sequences that request results. | |
# This is important if sixcat is run multiple times in a row, | |
# or if we want to run resetnumcolors at the end of the program. | |
# WARNING. While this should work with any terminal, but if it fails | |
# it'll end up waiting for approximately *forever* (i.e., 60 seconds). | |
read -s -t ${1:-60} -d "c" -p $'\e[c' | |
} | |
flushstdin() { | |
# flush stdin in case a key was hit twice by accident | |
while read -s -n1 -t .001; do :; done | |
} | |
e() { | |
# Clear current line and print text on it without a formfeed | |
echo -en "\r" | |
tput el | |
echo -en "$*" | |
} | |
E() { | |
# Clear current line and print text on it with a formfeed | |
echo -en "\r" | |
tput el | |
echo -e "$*" | |
} | |
rename() { | |
# Maybe rename an image file. | |
local file="$1" | |
local ext=${f##*.} | |
local base=$(basename "$file" ".$ext") | |
e "New name for $base? " | |
read newname | |
if [ "$newname" ]; then | |
newname="$(dirname "$file")/$newname" | |
newname="${newname#./}" # Remove dotslash from "./foo.jpg" | |
if [[ "$newname" != *$ext ]]; then | |
newname="$newname.$ext" | |
fi | |
e "Rename $file to $newname (y/N)? " | |
read -s -n 1 | |
case $REPLY in | |
y|Y) | |
mv -i "$file" "$newname" && | |
E "Renamed $file to $newname" && | |
# If rename successful, write to outerscope variable "f"!!! | |
f="$newname" | |
;; | |
*) | |
E "Rename cancelled." | |
;; | |
esac | |
else | |
E "Rename cancelled." | |
fi | |
} | |
editcomment() { | |
# Retrieve the current image comment/caption and let the user edit it. | |
local file="$1" | |
comment=$(rdjpgcom "$1") | |
read -e -i "$comment" -p "New comment? " newcomment | |
if [ "$newcomment" == "$comment" ]; then | |
E "Comment editing cancelled." | |
return | |
fi | |
mv "$file" "$file.old" | |
wrjpgcom -replace -comment "$newcomment" "$file.old" > "$file" | |
gio trash "$file.old" | |
} | |
doit () { | |
# For every file, show it and ask what is to be done. | |
for f; do | |
waitforterminal # Wait for the terminal to be ready. | |
if [[ -d "$f" ]]; then | |
echo "recursing on $f"; | |
doit "$f"/* | |
continue | |
fi | |
[[ -f "$f" ]] || continue; | |
# If the current file isn't an image, just skip it. | |
if ! identify "$f" 2>/dev/null 1>&2; then | |
continue | |
fi | |
# Show a quick preview | |
E "$f" | |
e "preparing best fit view\r" | |
convert -rotate '-90>' -rotate '+90' -gravity center \ | |
-geometry ">${WIDTH}x>${HEIGHT}" "$f" sixel:- | |
# Read a key loop | |
while true; do | |
e "Press space to keep, 'd' to delete, 'v' to view, 'h' for help, 'q' to quit.\r"; | |
flushstdin | |
if read -s -n1 -t 5 </dev/tty; then | |
tput el | |
case $REPLY in | |
s|" ") continue 2 # Nothing to do, just skip the image. | |
;; | |
d|t) gio trash "$f" && echo "trashed $f" | |
sleep 0.25; flushstdin # Slow down deletes | |
continue 2 | |
;; | |
D) rm "$f" && echo "deleted $f" | |
sleep 0.25; flushstdin # Slow down deletes | |
continue 2 | |
;; | |
v) e "preparing high quality view\r" # About 1 second | |
convert -geometry ">${WIDTH}x>${HEIGHT}" "$f" sixel:- | |
;; | |
b) # Rotate to fit screen. Double rotate for square images. | |
e "preparing best fit view\r" | |
convert -rotate '-90>' -rotate '+90' -gravity center \ | |
-geometry ">${WIDTH}x>${HEIGHT}" "$f" sixel:- | |
;; | |
c|i) identify "$f" | |
rdjpgcom "$f" 2>/dev/null | |
;; | |
r) rename "$f" | |
;; | |
C) editcomment "$f" | |
;; | |
w) e "preparing wide view\r" | |
convert -geometry ">${WIDTH}x" \ | |
-crop ${WIDTH}x${HEIGHT} \ | |
"$f" sixel:- | |
;; | |
e) e "preparing enhanced view\r" | |
convert -geometry ">${WIDTH}x>${HEIGHT}" "$f" \ | |
-channel rgb -auto-level -gamma 1.5 sixel:- | |
;; | |
p) e "Paused. Hit any key.\r" | |
read -n1 | |
;; | |
h|'?') E "$(basename $0): Rapidly browse and delete image files" | |
cat <<- "EOF" | |
For each image in a directory, a low quality preview will be shown. | |
You can then hit one of these keys: | |
space (or s): skip to next image. | |
d: trash image (also try 'gio list trash:' and 'gio trash --empty') | |
D: delete image immediately (no confirmation!) | |
v: view image in higher quality (can take a second). | |
b: best fit view (same as v, but image rotated to landscape). | |
w: wide view, show image full width | |
e: enhanced view (auto-level + gamma 1.5) | |
c: display comments and image size. | |
r: rename image. | |
C: edit image comment. | |
h: help (looks like you found it). | |
q: quit | |
EOF | |
;; | |
q) exit;; | |
esac; | |
else | |
continue 2 | |
fi; | |
done | |
done | |
e | |
} | |
### MAIN | |
# # Set global variables to hold the window size. | |
declare -i -g WIDTH HEIGHT | |
read WIDTH HEIGHT < <(getwindowsize) | |
HEIGHT=HEIGHT-32 # Trim some space for a line of text. | |
if [[ $# -gt 0 ]]; then | |
doit "$@" | |
else | |
doit * | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment