|
#!/bin/bash
##---------------------------------------------------------------------------##
# Script: find icons
# Author: Brian <genius@groupbcl.ca> :)
# Date: July 2018
#
# Locates files in directories whose path includes 'icon' or 'icons' and
# creates symlinks for them in $ICONS_DN/##x## (e.g $ICONS_DN/64x64) or
# $ICONS_DN/unspecified, and another symlink in $ICONS_DN/$ALL_ICONS_DN.
# Expects an extended regular expression describing icons to find (e.g.
# '\bedit\b' will find 'edit' but not 'editor' or 'credit'), but without
# one will find every icon it can on the system after confirming with the
# user.
##---------------------------------------------------------------------------##
# BUUS: this script is part of Brian's Useful Utilities Set
COUNT_BY=10
function create_icon_symlink {
local SOURCE_FN="$1" DIRNAME="$2" FILENAME="$3"
[ -d "$DIRNAME" ] || mkdir -p "$DIRNAME"
# Make the name of the symlink file easier to read
FILENAME="${FILENAME//-/ }" # Change '-' to ' '
FILENAME="${FILENAME//_/ }" # Change '_' to ' '
# If file already exists, create filename.1.xxx, filename.2.xxx, etc
if [ -L "$DIRNAME/$FILENAME" ]
then
P=$(( ${#FILENAME} - 4 )) # Assume a 3 character extension
[ ${FILENAME:$P:1} == '.' ] || P=$((P-1)) # Try 4
[ ${FILENAME:$P:1} == '.' ] || FILENAME='' # Give up
if [ "$FILENAME" ]
then
FN_STUB="${FILENAME:0:$P}"
FN_EXT="${FILENAME:$P}"
for ((i=1; i<1024; i++)); do [ -L "$DIRNAME/$FN_STUB.${i}$FN_EXT" ] || break; done
FILENAME="$FN_STUB.${i}$FN_EXT"
fi
fi
if [ "$FILENAME" ]
then
ln -s "$SOURCE_FN" "$DIRNAME/$FILENAME"
return 0
else
return 1
fi
}
function handle_file {
local FILE="$1" SIZE="$2"
BASE_FN="$(basename "$FILE")"
if create_icon_symlink "$FILE" "$ICONS_DN/$SIZE" "$BASE_FN"
then
[ "$FILTER" ] && create_icon_symlink "$FILE" "$ICONS_DN/$ALL_ICONS_DN" "$SIZE $BASE_FN"
COUNTER=$((COUNTER+1))
if [ $((COUNTER % COUNT_BY)) == 0 ]
then
echo -en " $COUNTER\r"
[ $COUNTER == 500 ] && COUNT_BY=100
fi
fi
}
##---------------------------------------------------------------------------##
# M A I N P R O C E S S I N G
##---------------------------------------------------------------------------##
FILTER=''
[ "$1" ] && FILTER=".*$1"
if [ ! "$FILTER" ]
then
echo "No regular expression was supplied."
echo -n "Are you sure you want to find all icons on the system [y/N]? "
read YES_NO
if [ "${YES_NO:0:1}" == 'y' -o "${YES_NO:0:1}" == 'Y' ]
then
echo "Searching for all icons"
COUNT_BY=100
else
echo "Cancelled"
exit
fi
fi
ICONS_DN="/tmp/icons-$USER"
ALL_ICONS_DN='all'
[ -d $ICONS_DN ] && rm -rf $ICONS_DN
mkdir $ICONS_DN
UNSIZED_LIST_FN="/tmp/find-icons.unsized-list.$$.tmp"
exec 3>$UNSIZED_LIST_FN
# Find icons and put them into directories by size
SIG_INT=false; trap SIG_INT=true INT
locate icon | egrep -i "\bicons?/" | egrep -i "$FILTER" | awk '
/\.(ico|bmp|gif|jpe?g|png)$/ {
size = ""
if (match($0, /([1-9]?[0-9][0-9]x[1-9]?[0-9][0-9])\//,a)) { size = a[1] }
print "SIZE=\"" size "\" FILE=\"" $0 "\""
}' | while read LINE
do
eval "$LINE"
[ -d "$FILE" ] && continue
# Icons with a known size can be placed immediately
if [ "$SIZE" ]
then
handle_file "$FILE" $SIZE
else
# Set aside icons with an unknown size for later processing
echo "\"$FILE\"" >&3
fi
$SIG_INT && break
done
trap INT
if $SIG_INT; then echo -e "\b(Search cancelled by ctrl-c)"; fi
# Now handle icon files that we have to examine to determine their size
exec 3>&- # Close FD 3
if [ -s $UNSIZED_LIST_FN ]
then
N="$(wc -l $UNSIZED_LIST_FN | cut -f1 -d' ')"
[ $N == 1 ] && FILE_S='file' || FILE_S='files'
echo "Examining $N icon $FILE_S to determine their size"
COUNT_BY=10
# ('sort' removes multi-image GIFs)
identify -format 'SIZE="%wx%h" FILE="%d/%f"\n' @$UNSIZED_LIST_FN |sort -u -k4 -t'"'|while read LINE
do
eval "$LINE" # Get FILE and SIZE from line
handle_file "$FILE" $SIZE
done
fi
rm -f $UNSIZE_LIST_FN
# Count the icons in each directory and add that informaton the directory name
cd $ICONS_DN
COUNT=$(find . -type l | grep -v "/$ALL_ICONS_DN/" | wc -l)
[ $COUNT == 1 ] && ICON_S='icon' || ICON_S='icons'
echo "$COUNT $ICON_S found"
if [ $COUNT -gt 0 ]
then
for DIR in $(ls --sort=version)
do
COUNT="$(ls $DIR | wc -l)"
ICON_S='icon'; [ $COUNT -gt 1 ] && ICON_S='icons'
[ "$DIR" != "$ALL_ICONS_DN" ] && echo " $DIR: $COUNT $ICON_S"
mv $DIR "$DIR ($COUNT $ICON_S)"
done
fi
ln -s "all ($COUNT icons)" all
# vim: tabstop=4
|