#!/bin/bash
# /usr/local/bin/images
# celeste:crystalfaery IMAGES 2018-12-15 15:51:40+00:00
# Review images size-order listed in ~/.imgs.txt (generated by find_images)
# We EXCLUDE from view previously seen listed in ~/.dush.imgs.txt
# as per: /usr/local/doc/txt/douche.txt
# d: We handle any arbitrary directory as argument ( /directory/ )
# p: We handle the pictures directory of ~/documents
# c: We handle the clipart directory of website in /home/crystalfaeries.net
# We handle super-directories with argument "." to option -g or -i, which select:
# g: galleries directory in /home
# i: imgs directory of website in /home/crystalfaeries.net
# i or g: give argument of "subdirectory_name", "." for top level directory, else you'll be offered a menu of valid directories
# v: VERSION INFOrmation (invocation: images -v)
# h: HELP INFOrmation (invocation: images -h)
# NOTE: Not yet reviewed for XDG compliance, and likely depends on other crystalfaeries.net scripts.
# NOTE: Upon discovery of any files with hardlinks by different names,
# we will tediously and stupidly scan EVERYWHERE listing them all,
# (rather than intelligently scanning only the relevant partition),
# then exit with an error 1 so you can intervene manually :-)
# by default you are left with no ~/.imgs.txt to continue with, forcing a rescan
# you man manually cp ~/.imgs.txt- ~/.imgs.txt to continue where you left off...
let help=22 # this line number -1
# CONFIGURATION:
alert="/usr/share/sounds/gnome/default/alerts/drip.ogg" # alert sound
DIRECTORY="/" # Default to all directories
# last definition wins:
SORTING="tac" # Default to smallest first
SORTING="cat" # Default to largest first
viewed="$HOME/.dush.imgs.txt" # list of pre-viewed files not to be re-viewed
unhardlink "${viewed}" # in case a name_tidy hardlinked the main file and its backup.
# see also the REVIEW section below, where we EXCLUDE from view certain file_names generated by 'igal2' program, (with which we generate WEB galleries)
cd || exit -1 # only place /usr/local/bin/delete may execute (until rewritten)
# OPTIONS:
while getopts ":repcd:i:g:lsvmh" opt
do
case $opt in
r ) mv ~/.imgs.txt{,-} # Rescan for images (/usr/local/bin/find_images)
shift # Saving old images list as backup
if [ $# -ne 0 ]
then # Rescan specified directory only
echo "scanning ${OPTARG} to create list of images..." >&2
/usr/local/bin/find_images "${OPTARG}"
let found=$?
if [ ${found} -eq 0 ]
then
/bin/echo "`basename $0` Successfully generated new list of images." >&2
else
/bin/echo "`basename $0` ERROR: ${found} from find_images." >&2
exit -1 # we failed to find images in requested directory
fi
fi;;
e ) # wash the sorted ${viewed} list of any deleted files and review in editor with list of images to be viewed
sort -u < ${viewed} > ${viewed}- || exit -1
cp /dev/null ${viewed} || exit -1
while read f
do
if [ -f "${f}" ]
then # file exists so preserve exclusion of it
echo "${f}" >> ${viewed}
fi
done < ${viewed}- # leave old version of viewed list as a backup
mv .imgs.txt{,-} || exit -1 # backup images list before editing
cp .imgs.txt{-,} || exit -1 # backup images list before editing
vi ${viewed} .imgs.txt ${viewed} # edit viewed list and to-view list
exit;;
p ) DIRECTORY="~/documents/pictures/";; # Display user's pictures
c ) DIRECTORY="/home/crystalfaeries.net/clipart/";; # Display website's clipart
d ) DIRECTORY="${OPTARG}";; # Display specified directory
i ) DIRECTORY="/home/crystalfaeries.net/imgs" # Display website's imgs directory (.) or specified subdirectory
if [ -d /home/crystalfaeries.net/imgs/"${OPTARG}" ]
then
DIRECTORY=/home/crystalfaeries.net/imgs/"${OPTARG}"
else
select DIRECTORY in $( find /home/crystalfaeries.net/imgs/ -maxdepth 1 -type d | sort )
do
if [ ! ${DIRECTORY} ]
then
echo 'Invalid directory selection.' 1>&2
else
break
fi
done
fi;;
g ) DIRECTORY="/home/galleries/" # Display /home/galleries directory (.) or specified subdirectory
if [ -d /home/galleries/"${OPTARG}" ]
then
DIRECTORY=/home/galleries/"${OPTARG}"
else
select DIRECTORY in $( find /home/galleries/ -maxdepth 1 -type d | sort )
do
if [ ! ${DIRECTORY} ]
then
echo 'Invalid directory selection.' 1>&2
else
break
fi
done
fi;;
l ) SORTING="cat";; # Display largest to smallest images
s ) SORTING="tac";; # Display smallest to largest images
v ) tail -n +3 $0 | head -n 1 1>&2 # VERSION info
exit 0;;
m ) # Generate man page
help2man -N --help-option=-h --version-option=-v --no-discard-stderr --section=1 --output=/usr/local/share/man/man1/images.1 $0
exit 0;; # why does help2man discard help-option's line-breaks? I consider that a bug! does it have an option not to?
h ) echo 'usage info: [--help] for extended help information.'
echo 'usage info: [-h] for this help information, [-v] for version information, [-e] to edit exclusions.'
echo 'usage: images [-c] [-g directory] [-i directory] [-p] [-l] [-s] [-r [directory]] [-d directory]'
echo '...... c(lipart) g(alleries) i(mgs) p(ictures) {largest,smallest} r(escan) <dir> directory'
echo 'Default is to display all images from largest to smallest. [-m] to generate a man page.'
exit 0;; # HELP info
\? ) head -n $help $0 1>&2
exit 1;; # HELP info
esac
done; shift $((OPTIND - 1))
# continue with existing non-zero, or create new list of images (see /usr/local/bin/find_images)
if [ -s ~/.imgs.txt ]
then
echo "Continuing with existing list of images..." >&2
else
if [ -s ~/.imgs.txt- ]
then
echo "Continuing with old list of images..." >&2
sort -u < \
~/.imgs.txt- > \
~/.imgs.txt
else
echo "scanning to create list of images... will alert when done." >&2
/usr/local/bin/find_images
let found=$?
if [ ${found} -eq 0 ]
then
/usr/local/bin/alert "`basename $0` Successfully generated new list of images." >&2
else
/usr/local/bin/alert "`basename $0` ERROR: ${found} from find_images." >&2
exit ${found}
fi
fi
fi
# REVIEW for (possible) deletion Images
cd ~ # delete only works in home directory
for f in $( ${SORTING} ~/.imgs.txt | grep -v .thumb_ | grep -v .tile.png | grep ${DIRECTORY} )
do
echo "======= ${f} ======="
if [ -d "${f}" ]
then # it is a directory
alert "${f} SKIPPED directory." # ERROR?: WHY ARE WE HANDLING A DIRECTORY? WHAT SHOULD WE DO WITH IT?
elif [ -h "${f}" ]
then
echo "${f} SKIPPED symlink." 1>&2 # Symlinks are ignored, presuming we will deal with their target file.
elif [ -f "${f}" ]
then # it is a file, determine file TYPE from file EXTENSION (how did ~/.imgs.txt get NON-image formats?)
case $(echo "${f}" | sed 's/^.*\.//') in
html)
/usr/local/bin/delete -i "${f}" # presumably it was deleted locally and we need to query deleting remotely
;;
htm)
/usr/local/bin/delete -i "${f}" # presumably it was deleted locally and we need to query deleting remotely
;;
txt)
/usr/local/bin/delete -i "${f}" # presumably it was deleted locally and we need to query deleting remotely
;;
css)
/usr/local/bin/delete -i "${f}" # presumably it was deleted locally and we need to query deleting remotely
;;
js)
/usr/local/bin/delete -i "${f}" # presumably it was deleted locally and we need to query deleting remotely
;;
*) # if we have already reviewed this file and did not delete it, do NOT display it again:
if grep "${f}" "${viewed}" >& /dev/null
then # we have ALREADY SEEN this image
: # No-Operation
else # we have yet to reVIEW the image, notify user of all known copies and usages:
find ~/documents/pictures/ /home/crystalfaeries.net/ /home/galleries/ -name `basename "${f}"` -exec ls -Flad {} \; # all locations (EXCEPT /home/downloads)
grep `basename "${f}"` \
/home/crystalfaeries.net/*.html \
/home/crystalfaeries.net/imgs/HEADER.html \
/home/crystalfaeries.net/imgs/index.html \
/home/crystalfaeries.net/imgs/*/HEADER.html \
/home/crystalfaeries.net/src/{.??,}* \
| grep -v /home/`whoami`/.cache/thumbnails \
| grep -v /home/crystalfaeries.net/imgs/3d2/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/3d2/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/3dc/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/3dc/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/animations/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/animations/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/ankle/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/ankle/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/ballet/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/ballet/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/bernie_dexter/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/bernie_dexter/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/bettie+ets/index.html \
| grep -v /home/crystalfaeries.net/imgs/bettie_page/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/bettie_page/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/between_legs/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/between_legs/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/bottle/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/bottle/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/breasts/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/breasts/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/celeste/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/celeste/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/coins/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/coins/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/corset/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/corset/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/cum/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/cum/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/dita/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/dita/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/emilymarilyn/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/emilymarilyn/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/encasement/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/encasement/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/eve/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/eve/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/faeries/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/faeries/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/fishnets/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/fishnets/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/garters/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/garters/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/girdle/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/girdle/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/heels/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/heels/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/hooker/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/hooker/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/jessica/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/jessica/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/latex/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/latex/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/legshow/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/legshow/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/lesbian/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/lesbian/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/maids/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/maids/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/music/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/music/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/panties/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/panties/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/pantyhose/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/pantyhose/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/passion/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/passion/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/pinups/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/pinups/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/plaid/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/plaid/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/pussy/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/pussy/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/puthg/index.html \
| grep -v /home/crystalfaeries.net/imgs/rug/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/rug/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/stockings/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/stockings/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/suspender_belts/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/suspender_belts/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/tech/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/tech/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/ts/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/ts/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/upskirt/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/upskirt/portrait/index.html \
| grep -v /home/crystalfaeries.net/imgs/zlata/landscape/index.html \
| grep -v /home/crystalfaeries.net/imgs/zlata/portrait/index.html \
> /tmp/$$.txt # we may have matched on a substring
if [ $? -eq 0 ]
then # we MAY be using it, or have matched on a substring, we must further investigate `basename "${f}"` versus entries in /tmp/$$.txt
echo 'Image IS! used in website:' >&2
sort -u < /tmp/$$.txt # display the found usages in sorted order (not sure using a pipe would deliver return code of the grep itself)
rm /tmp/$$.txt # our list WAS accurate, but now user may change things with the gwenview, the graphical viewer:
echo "${f}" | xclip # file path for img markup
echo "------- ${f} -------" # USER VIEWS THE IMAGE, POSSIBLY DELETING IT (AND MAYBE OTHER IMAGES) VIA THE GRAPHICAL VIEWER IN THE GUI
mplayer "$alert" > /dev/null 2>&1 # warn the user of window popping up
sleep 2
/usr/bin/gwenview -f "${f}" 2>/dev/null || /usr/bin/gthumb "${f}" 2>/dev/null # view the file without all the debug info
# /usr/local/bin/delete -i "${f}" # DO NOT OFFER TO DELETE THE IMAGE WHICH IS USED BY OUR WEBSITE! (try be idiotproof!)
if [ -f "${f}" ]
then # image was kept locally, so log all hardlinked copies by any name, and all same-named files as SEEN:
cp ${viewed}{,-}
touch /tmp/$$.txt /tmp/.$$.txt # in case we do not find any in our standard directores, (${f} is external thereunto)
find ~/documents/pictures/ /home/crystalfaeries.net/{clipart,imgs}/ /home/galleries/ -samefile "${f}" \
| tee -a ${viewed}- > /tmp/$$.txt
find ~/documents/pictures/ /home/crystalfaeries.net/{clipart,imgs}/ /home/galleries/ -name `basename "${f}"` \
| tee -a ${viewed}- >>/tmp/$$.txt
sort -u < /tmp/$$.txt # display the remaining files in sorted order
for f in `cat /tmp/$$.txt`;do
echo $(basename ${f}) >> /tmp/.$$.txt
done
sort -u < /tmp/.$$.txt > /tmp/$$.txt
rm /tmp/.$$.txt
let file_count=$(/usr/bin/wc /tmp/$$.txt | sed 's/^ *//g;s/ .*$//g')
if [ $file_count -gt 1 ]
then # NAME VARIANCE
echo "####### MULTIPLE NAMES DETECTED #######" >&2
cat /tmp/$$.txt
mv ~/.imgs.txt{,-} # FORCE Rescan for all images after MANUAL INTERVENTION
echo "======= MULTIPLE NAMES scanning... ${f} =======" >&2
find / -samefile "${f}" 2>/dev/null | \
tee /tmp/$$.txt
echo "======= All HardLinks Shown for ${f} ( see /tmp/$$.txt ) =======" >&2
exit 1 # FORCE MANUAL INTERVENTION
fi
rm /tmp/$$.txt # cleanup
sort -u ${viewed}- > ${viewed}
fi
else
echo 'Image NOT used in website.' >&2
echo "${f}" | xclip # file path for img markup
echo "------- ${f} -------" # USER VIEWS THE IMAGE, POSSIBLY DELETING IT (AND MAYBE OTHER IMAGES) VIA THE GRAPHICAL VIEWER IN THE GUI
mplayer "$alert" > /dev/null 2>&1 # warn the user of window popping up
sleep 2
/usr/bin/gwenview -f "${f}" 2>/dev/null || /usr/bin/gthumb "${f}" 2>/dev/null # view the file without all the debug info
/usr/local/bin/delete -i "${f}" # even if deleted locally in viewer, we need to query deleting our twin's copy
if [ -f "${f}" ]
then # image was kept locally, so log all hardlinked copies by any name, and all same-named files as SEEN:
cp ${viewed}{,-}
touch /tmp/$$.txt /tmp/.$$.txt # in case we do not find any in our standard directores, (${f} is external thereunto)
find ~/documents/pictures/ /home/crystalfaeries.net/{clipart,imgs}/ /home/galleries/ -samefile "${f}" \
| tee -a ${viewed}- > /tmp/$$.txt
find ~/documents/pictures/ /home/crystalfaeries.net/{clipart,imgs}/ /home/galleries/ -name `basename "${f}"` \
| tee -a ${viewed}- >>/tmp/$$.txt
sort -u < /tmp/$$.txt # display the remaining files in sorted order
for f in `cat /tmp/$$.txt`;do
echo $(basename ${f}) >> /tmp/.$$.txt
done
sort -u < /tmp/.$$.txt > /tmp/$$.txt
rm /tmp/.$$.txt
let file_count=$(/usr/bin/wc /tmp/$$.txt | sed 's/^ *//g;s/ .*$//g')
if [ $file_count -gt 1 ]
then # NAME VARIANCE
echo "####### MULTIPLE NAMES DETECTED #######" >&2
cat /tmp/$$.txt
rm /tmp/$$.txt
mv ~/.imgs.txt{,-} # FORCE Rescan for all images
echo "======= MULTIPLE NAMES scanning... ${f} =======" >&2
find / -samefile "${f}" 2>/dev/null
echo "======= All HardLinks Shown for ${f} =======" >&2
exit 1 # FORCE MANUAL INTERVENTION
fi
rm /tmp/$$.txt
sort -u ${viewed}- > ${viewed}
fi
fi
fi
;;
esac
else
/usr/local/bin/delete -i "${f}" # presumably it was deleted locally (probably in the graphics viewer) and we need to query deleting our twin's remote copy
fi
echo "=-----= ${f} =-----="
# remove the file from our to-do list:
mv ~/.imgs.txt ~/.imgs.txt-
grep -v "${f}" ~/.imgs.txt- > ~/.imgs.txt
done
exit $?
syntax highlighted by Code2HTML, v. 0.9.1