#!/bin/bash
#                       /usr/local/bin/images
# https://crystalfaeries.net/posix/bin/images
# celeste:crystalfaery IMAGES 2021-02-23 17:30:45+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: https://crystalfaeries.net/posix/doc/txt/douche.txt
#
# while getopts ":repcji:g:d:lsmvh" opt
# Arguments:
# r: RESCAN for images (/usr/local/bin/find_images)
# e: wash the sorted ${viewed} list of any deleted files and review in EDITor with list of images to be viewed
# p: We handle the PICTURES directory of ~/documents
# c: We handle the CLIPART directory of website in $HOME/crystalfaeries.net/imgs/clipart
# j: See celeste's JOURNAL images in $HOME/crystalfaeries.net/imgs/journal/
#
# We handle super-directories with optional argument to option -g or -i, which select:
# i: IMGS	directory in $HOME/crystalfaeries.net/imgs
# g: GALLERIES	directory in $HOME/crystalfaeries.net/galleries
# i or g: give argument of "subdirectory_name", "index" for top level directory, else you'll be offered a menu of valid directories
# d: We handle any arbitrary DIRECTORY as argument ( /directory/ )
#
# Sorting:
# l: Display LARGEST to smallest images (default)
# s: Display SMALLEST to largest images
#
# m: Generate MAN page
# 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 to update our files to match whatever you did.
#	You can manually cp ~/.imgs.txt- ~/.imgs.txt to continue where you left off...
let help=38	# 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

# OPTIONS:
while getopts ":repcji:g:d:lsmvh" opt
do
    case $opt in
	r )	mv ~/.imgs.txt{,-}				# Rescan for images (/usr/local/bin/find_images)
		cp /dev/null ~/.imgs.txt			# Rescan for images (/usr/local/bin/find_images)
		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
		shift;;						# Saving old images list as backup
	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="$HOME/documents/pictures/";;			# Display user's pictures
	c )	DIRECTORY="$HOME/crystalfaeries.net/imgs/clipart/";;	# Display website's clipart
	j )	DIRECTORY="$HOME/crystalfaeries.net/imgs/journal/";;	# Display celeste's journal 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/crystalfaeries.net/galleries/"	# Display /home/crystalfaeries.net/galleries directory (.) or specified subdirectory
		if [ -d		  $HOME/crystalfaeries.net/galleries/"${OPTARG}" ]
		then
			DIRECTORY=$HOME/crystalfaeries.net/galleries/"${OPTARG}"
		else
			select DIRECTORY in $( find $HOME/crystalfaeries.net/galleries/ -maxdepth 1 -type d | sort )
			do
				if [ ! ${DIRECTORY} ]
				then
					echo 'Invalid directory selection.'								1>&2
				else
					break
				fi
			done
		fi;;
	d )	DIRECTORY="${OPTARG}"					# Display specified directory
		if [ -d		  "${OPTARG}" ]
		then
			DIRECTORY="${OPTARG}"
		else
			echo 'Invalid directory selection.'								1>&2
			break
		fi;;
	l )	SORTING="cat";;						# Display largest to smallest images
	s )	SORTING="tac";;						# Display smallest to largest images
	m )								# Generate man page
		/usr/bin/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?
	v )	tail -n +4 $0 | head -n 1	1>&2			# VERSION info
		exit 0;;
	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
		echo 'usage info: [--help] for the this help information.'
		echo 'usage info: [-h] for summary help info, [-v] for version info, [-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 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	# RESSURECT THE OLD LIST OF IMAGES
#		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 historically 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
	echo "${f} SKIPPED directory."	1>&2 	# 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	${DIRECTORY}/							\
			$HOME/documents/pictures/						\
			$HOME/crystalfaeries.net/imgs/						\
			$HOME/crystalfaeries.net/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/*						\
			$HOME/crystalfaeries.net/src/.2[0-9][0-9][0-9]*				\
	| grep -v	$HOME/crystalfaeries.net/src/.href.internal.txt				\
	| grep -v	$HOME/.cache/thumbnails							\
			> /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/imgs/ $HOME/crystalfaeries.net/galleries/ -samefile		"${f}"	\
					| tee -a	${viewed}- > /tmp/$$.txt
					find ~/documents/pictures/ $HOME/crystalfaeries.net/imgs/ $HOME/crystalfaeries.net/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/imgs/ $HOME/crystalfaeries.net/galleries/ -samefile		"${f}"	\
					| tee -a	${viewed}- > /tmp/$$.txt
					find ~/documents/pictures/ $HOME/crystalfaeries.net/imgs/ $HOME/crystalfaeries.net/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
						nice ionice -c 3 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 deleted locally (e.g. in graphics viewer) so 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	$?
