#!/bin/bash
# iRetiner 0.60
# Original idea: Ardu
# Thanks to ttwj for bashtrackr, used in iTunes downloading
# Coded by dxs

# Changelog
# -----===-----
# 0.1
# - Initial attempt
#
# 0.2
# - First semi-working version
#
# 0.3
# - Fully functional, uses iTunesArtwork
# - This is the version that was defaced by HackYouriPhone
# - Code cleanup
# - Console interface
#
# 0.4
# - More code cleanup
# - Added proper credits
# - AppTrackr API support (thanks to ttwj for bashtrackr)
# - Nice cosmetic touch-ups
# - Neat progress indicator instead of long list of apps
# - Commments are more readable because of indentation
# - Fixed bug where apps which already have Retina Icons were affected
# - Resizes iTunesArtwork using libjpeg, ImageMagick, and pincrush
# 
# 0.4b
# - Minor tweaks
# - Command line options
# 
# 0.5 (aka 0.4c)
# - Fixed stupid mistake that made downloading impossible
# - Fixed minor typo
# 
# 0.51
# - Nothing changed (fixed missing dependencies in Cydia)
# 
# 0.60
# - Fix for org.chronic-dev.animate conflict
# - Rewrote 80% of script
# - Downloading is slower, but code is much cleaner
# - Auto-adapt implemented; downloads only if iTunesArtwork is missing
# - Menu looks much better
# - Better everything
# 

cleanup() {
	[ -n "$TMP_APPLIST" ] && [ -f "$TMP_APPLIST" ] && rm -f "$TMP_APPLIST"
	printf "%$(($(tput cols)-1))s\r"
}
init_ansi() { # ANSI escape sequences (colors + font modifiers)
	ESC="$(echo -e '\0033\c')"
	
	# Font colors
	FC_BLACK="${ESC}[30m";		FC_RED="${ESC}[31m"
	FC_GREEN="${ESC}[32m";		FC_YELLOW="${ESC}[33m"
	FC_BLUE="${ESC}[34m"; 	FC_MAGENTA="${ESC}[35m"
	FC_CYAN="${ESC}[36m"; 	FC_WHITE="${ESC}[37m"
	FC_DEFAULT="${ESC}[39m";	FC_RESET="${ESC}[39m"
	
	# Highlights
	FH_BLACK="${ESC}[40m";		FH_RED="${ESC}[41m"
	FH_GREEN="${ESC}[42m";		FH_YELLOW="${ESC}[43m"
	FH_BLUE="${ESC}[44m"; 	FH_PURPLE="${ESC}[45m"
	FH_CYAN="${ESC}[46m"; 	FH_WHITE="${ESC}[47m"
	FH_DEFAULT="${ESC}[49m";	FH_RESET="${ESC}[49m"
	
	# Font modifiers
	F_BOLD_ON="${ESC}[1m";		F_BOLD_OFF="${ESC}[22m"
	F_FAINT_ON="${ESC}[2m"; 	F_FAINT_OFF="${ESC}[22m"
	F_ITALIC_ON="${ESC}[3m";	F_ITALIC_OFF="${ESC}[23m"
	F_UNDERLINE_ON="${ESC}[4m"; F_UNDERLINE_OFF="${ESC}[24m"
	F_BLINK_ON="${ESC}[5m"; 	F_BLINK_OFF="${ESC}[25m"
	F_INVERT_ON="${ESC}[7m";	F_INVERT_OFF="${ESC}[27m"
	F_INVISIBLE_ON="${ESC}[8m"; F_INVISIBILE_OFF="${ESC}[22m"
	F_NORMAL="${ESC}[0m"; 	F_RESET="${ESC}[0m"
	
	# Screen related stuff
	CLEARTOEND="${ESC}[K";		CLEARTOEOL="${ESC}[K"
	CLEARSCREEN="${ESC}[2J"
	
	# Cursor stuff
	C_HIDE="${ESC}[25l" # Hides cursor
	C_SHOW="${ESC}[25h" # Shows cursor
	
	C_UP="${ESC}[1A"	# ${ESC}[(n)A - Moves cursor up n lines
	C_DOWN="${ESC}[1B"	# ${ESC}[(n)B - Moves cursor down n lines
	C_RIGHT="${ESC}[1C" # ${ESC}[(n)C - Moves cursor forward n spaces
	C_LEFT="${ESC}[1D"	# ${ESC}[(n)D - Moves cursor back n spaces
	
	# ${ESC}[(LINE);(COL)H or ${ESC}[(LINE);(COL)f	# Moves cursor to line #, column #
}
menu() {
	while [ "${1:0:1}" == "-" ]; do
		case "$1" in
			-w | --width ) local disp_colw="$2"; shift;;
			--pad ) local npad="$2"; shift;;
			-p | --prompt ) local prompt="$2"; shift;;
			-- ) shift; break;;
		 esac
		shift
	done
	
	local screenw="$(tput cols)"
	local cols="$(($screenw/${disp_colw:-25}))"
	[ $cols -lt 1 ] || [ -z "$cols" ] && cols=1
	local colw="$((($screenw/$cols) - 3 - ${npad:-3}))"
	
	local i
	for ((i=1; i<="$#"; i++)); do
		printf " %-${npad:-3}.${npad:-3}s %-${colw}.${colw}s " "${i}." "${!i}"
		[ $(($i%$cols)) == 0 ] && printf "%$(($screenw-1))s\r"
	done
		
	printf "%$((screenw-1))s\r"
	read -p "${prompt:-Option(s) (space delimited): }" REPLY
}
prompt() { # Ask for yes/no input
	local d='[Y/n]'
	while [ "$#" -gt 0 ]; do
		case "$1" in
			-N )	d="[y/N]";;
			-s )	d="$2"; shift;;
			* ) 	break;;
		esac
		shift
	done
	
	read -p "$* $d: " REPLY
	REPLY="$(echo "$REPLY" | tr [:upper:] [:lower:] | sed -e s='yes'='y'=g -e s='no'='n'=g | tr -dc "$d")"
	
	[ -z "$REPLY" ] && REPLY="$(echo "$d" | tr -dc [:upper:] | tr [:upper:] [:lower:])"
	
	[ "$REPLY" == 'y' ] && [ "$d" == '[Y/n]' ] || [ "$d" == '[y/N]' ] && return 0
	[ "$REPLY" == 'n' ] && [ "$d" == '[Y/n]' ] || [ "$d" == '[y/N]' ] && return 1
}
pbar() { # Progress bar
	[ -z "$ESC" ] && ESC="$(echo -e '\0033\c')"
	
	[ -z "$COLUMNS" ] && tput cols &>/dev/null && COLUMNS="$(tput cols)"
	[ -z "$COLUMNS" ] && COLUMNS=80
	
	local i
	
	local current="${1:-0}"
	local full="${2:-100}"
	local percent=1
	local overall=''
	
	# local indicator="-o0O0o"
	local indicator=':. .'
	# local indicator="/-\|"
	# local indicator="_-+^ "
	# local indicator="c690@"
	# local indicator='->)>'
	
	# local barseg=">"
	local barseg=':'
	
	local eta=''
	local message=''
	local usablecols="$(($COLUMNS - 4))"
	
	while [ "$#" -gt 0 ]; do
		case "$1" in
			-c | --current ) current="$2"; shift;;
			-f | --full ) full="$2"; shift;;
			-np | --no-percent ) percent='';;
			-o | --overall ) overall=1;;
			-i | --indicator ) indicator="$2"; shift;;
			-e | --eta ) eta=1;;
			--old-eta ) eta=2;;
			--set-time ) __PBAR_ETA_START="$(date +%s)";;
			-m | --message ) message="$2 "; shift;;
		esac
		shift
	done
	
	# Percentage
	[ -n "$percent" ] && { percent="$(( ( $current * 100 ) / $full ))%% "; ((usablecols++)); }
	
	# Overall
	[ -n "$overall" ] && overall="($current/$full) "
	
	# ETA
	([ "$current" == 0 ] || [ -z "$__PBAR_ETA_START" ]) && __PBAR_ETA_START="$(date +%s)"
	if [ -n "$eta" ]; then
		local elapsed="$(($(date +%s) - $__PBAR_ETA_START))"
		if [ "$current" -lt "$full" ]; then
			[ "$current" -le 0 ] && eta="ETA:$(($elapsed * $full / 1 - $elapsed))s " || eta="ETA:$(($elapsed * $full / $current - $elapsed))s "
		else
			__PBAR_ETA_START=''
			eta="FIN:${elapsed}s "
		fi
	fi
	
	# Create the bar
	usablecols="$(($usablecols - ${#percent} - ${#overall} - ${#message} - ${#eta}))"
	local bar=''
	local numbars="$(( ($usablecols * $current) / $full ))" # Pun fully intended.
	[ "$current" -ge "$full" ] || [ -z "$indicator" ] && ((numbars++))
	for ((i=1; i<"$numbars"; i++)); do
		bar+="$barseg"
	done
	
	# Last bar segment: alive indicator
	[ -z $__PBAR_INDICATOR ] || [ $current == 0 ] && __PBAR_INDICATOR=0
	if [ -n "$indicator" ] && [ "$current" -lt "$full" ]; then
		[ "$__PBAR_INDICATOR" -ge "${#indicator}" ] && __PBAR_INDICATOR=0
		bar+="${indicator:$__PBAR_INDICATOR:1}"
		((__PBAR_INDICATOR++))
	fi
	
	# Print it!
	printf "${ESC}[25l\r ${percent}${overall}${eta}${message}[${bar}${ESC}[0m${ESC}[K${ESC}[99999C${ESC}[1D]${ESC}[25h"
	[ "$current" -ge "$full" ] && echo
}
help() {
	echo "$SCRIPT_NAME ($SCRIPT_VERSION)"
	echo "Coded by dxs"
	echo "Original idea: Ardu"
	echo "Thanks to ttwj for the bashtrackr library, used in the download method"
	echo
	echo "Report bugs to dxs444@gmail.com"
	echo "Adds Retina Display icons to AppStore apps"
	echo "As usual, use at your own risk."
	echo
	echo "You can run $SCRIPT_NAME from the command line with these arguments:"
	echo " -a, -adapt     Adapt all AppStore icons using auto-adapt"
	echo " -r, -revert    Revert all adapted icons"
	echo " -n, --never-resize  Never resize images with ImageMagick"
	echo "                Resulting icons will have a larger file size than necessary"
	echo "                It's faster than resizing, but don't use if you notice performance issues with this"
}

# bashtrackr, apptrackr API bash library (by ttwj)
# http://hackulo.us/forums/index.php?/topic/98106-release-bashtrackr-apptrackr-api-library-in-bash/
# apptrackr API info as of Nov 2010
# Version 0.1, by ttwj
# Thanks to
# MadHouse - For JSON parsing methods and help with apptrackr API
# ajm2k - For JSON parsing methods
# People on #bash on freenode for helping
data_parse() {
        # data.fetch <string>
        # fetch the code
        code=$(echo "$1" | tr '{', '\n' | sed -n "2p" | sed -e 's/:/ /' | awk '{print $2}')
        if [ "${code:0:1}" != "2" ]; then
                # :(
                # echo "Error: response code $code was returned, please check http://hackulo.us/fo...-apptrackr-api/ for list of response codes"
                false
        else
                string=$(echo "$1" | tr '{', '\n' | sed -e '/"signature":\(.*\)/d;/"data":\(.*\)/d;/"signature":\(.*\)/d;/"code":\(.*\)/d' |sed -e 's/\\"//g;s/\\\\\\\//\//g;s/\\//g' | tr '}', '\n' | sed -e 's/"//' | sed '/^$/d')
                echo "$string"
        fi
}
request_send() {
        # array.send <string> <API Location (optional)>
        # quote string
        string=$(echo "$1" | sed -e 's/"/\\"/g')
        string='{"request":"'"$string"'"}'
        if [ "$2" ]; then
                api="$2"
        else
                api="http://api.apptrackr.org"
        fi
        output=$(curl -s -d "request=$string" "$api")
        echo "$output"
}
app_checkUpdates() {
        #app.checkUpdates <app ids>
        for i in ${@}; do
                appids=$((appids+1))
                if [ "$appids" -gt "100" ]; then
                        echo "Error, cannot check for more than 100 updates."
                        break
                        return 0
                fi
                if [ "$appids" -gt "1" ]; then
                        string="$string, $i"
                else
                        string="$i"
                fi
        done    
        json='{"object":"App","action":"checkUpdates","args":{"appids":['"$string"']}}'
        echo "$json"
}
app_getDetails() {
        # app_getDetails <app id> <fields>
        supported_list="appid scrapeid add_date last_modification itunesurl name seller category storeid size latest_version release_date copyright price rating icon57 icon75 icon100 icon175 description whatsnew requirements languages universal"
        for i in ${@:2}; do
                if [ "$(echo "$supported_list" | grep -w "$i")" ]; then
                                if [ ! "$field" ]; then
                                        field="\"$i\""
                                else
                                        field="$field, \"$i\""
                                fi
                        else
                                #echo "Error: unknown field requested, please check http://hackulo.us/fo...-apptrackr-api/ for a list of supported fields"
                                return 0
                fi
        done
        json='{"object":"App","action":"getDetails","args":{"app_id":'$1',"fields":['$field']}}'
        echo "$json"
}
app_getList() {
        #app.getList <appsPerPage> <sort> <page> <search (optional)> <category (optional)> <showPageCount (optional)> <deviceid (optional)>
        #do some checks..
        if [ ! "$1" ]; then echo "Error: Missing appsPerPage"; return 0; fi
        if [ ! "$2" ]; then echo "Error: Missing sort"; return 0; fi
        if [ ! "$3" ]; then echo "Error: Missing page"; return 0; fi
        if [ ! "$(echo '15 30 60 null' | grep -w "$1")" ]; then echo "Error: appsPerPage can only be 15, 30 or 60, please check the apptrackr API documentation for more info"; return 0; fi
        if [ ! "$(echo '0 1 2 null' | grep -w "$8")" ]; then echo "Error: deviceid can only be 0 (All), 1 (iPhone/iPod Touch) and 2 (iPad)."; return 0; fi
        if [ ! "$4" = "null" ]; then 
                string=", \"search\":\"$4\""
        else
                string=""
        fi
        if [ ! "$5" = "null" ]; then
                string="$string, \"category\":$5"
        fi
        if [ ! "$6" = "null" ]; then
                string="$string, \"showPageCount\":$6"
        fi
        if [ ! "$7" = "null" ]; then
                string="$string, \"deviceid\":$7"
        fi
        json='{"object": "App","action":"getList","args":{"appsPerPage":'$1',"sort":'$2',"page":'$3''$string'}}'
        echo "$json"
}
app_scrape() {
        #this part was the easiest to do :3
        #app.scrape <itunes url>
        if [[ ! "$1" = *http*://*itunes*.*apple*.*com* ]]; then
                echo "Error: Not a valid iTunes URL"
                return 0
        fi
        json='{"object":"App","action":"scrape","args":{"itunes_url":"'$1'"}}'
        echo "$json"
}
bundle_getItunesIDs() {
        # getItunesIDs <app ids>
        [ "${#@}" -le 0 ] && return 1

        local string="\"$1\""
        shift
        local appid=""
        for appid in ${@}; do
                string="$string, \"$appid\""
                shift
        done

        json="{\"object\":\"Bundle\",\"action\":\"getItunesIDs\",\"args\":{\"bundleList\":[$string]}}"
        echo "$json"
}
category_getList() {
        json='{"object": "Category","action": "getList"}'
        echo "$json"
}
link_get() {
        #link.get <appid>
        if [ ! "$1" ]; then echo "Error: Please input an appid"; return 0; fi
        json='{"object": "Link","action": "get","args": {"app_id": '$1'}}'
        echo "$json"
}
screenshot_get() {
        #screenshot.get <appid>
        if [ ! "$1" ]; then echo "Error: Please input an appid"; return 0; fi
        json='{"object": "Screenshot","action": "get","args": {"app_id": '$1'}}'
        echo "$json"
}
user_checkAuth() {
        #user.checkAuth <username> <passhash>
        if [ ! "$1" ]; then echo "Error: Please input a username"; return 0; fi
        if [ ! "$2" ]; then echo "Error: Please input a passhash"; return 0; fi
        json='{"object": "User","action": "checkAuth","auth": {"username": "'$1'","passhash": "'$2'"}}'
        echo "$json"
}
# end bashtrackr code

# Constants
ICONCACHE_DIR="/var/mobile/Library/Caches/com.apple.IconsCache"
RETINA_SIZE="114x114"
SANDBOX_ROOTS="/var/mobile/Applications"
SCRIPT_NAME="iRetiner.sh"
SCRIPT_VERSION="0.60"
OPERATION=0
IMAGEMAGICK=1
GUI=0

trap "cleanup; exit" ABRT EXIT HUP INT TERM QUIT

# ----====== Interface begins here ======----
clear
init_ansi
echo "${FC_GREEN}$SCRIPT_NAME ($SCRIPT_VERSION)${F_RESET}"
echo

# Compatibility checks
if [ "$(dpkg --list | cut -f3 -d ' ' | grep '^org.chronic-dev.animate')" ]; then
	echo "${FC_YELLOW}Animated Bootlogo (org.chronic-dev.animate) compatiblity mode is enabled, features involving ImageMagick won't work for you${F_RESET}"
	IMAGEMAGICK=0
fi
if [ "$(deviceinfo -c | grep -i -e M68AP -e N82AP -e N88AP -e N45AP -e N72AP -e N18AP)" ]; then
	echo "${FC_YELLOW}Notice:${F_RESET}"
	echo "${FC_YELLOW}  Your device doesn't have a Retina capable screen${F_RESET}"
	echo "${FC_YELLOW}  $SCRIPT_NAME won't affect your device${F_RESET}"
	echo "${FC_YELLOW}      ...but you're always${F_RESET}"
	echo "${FC_YELLOW}         free to try ;)${F_RESET}"
	echo
	RETINA_SIZE="57x57"
fi

while [ "$#" -gt 0 ]; do
	case "$1" in
		-r | -revert )	GUI=1;	OPERATION=1;;
		-a | -adapt )	GUI=1;	OPERATION=2;; # Uses auto-adapt
		-n | --never-resize )	IMAGEMAGICK=0;;
	esac
	shift
done

TMP_APPLIST="/tmp/$SCRIPT_NAME-$RANDOM.tmp"
if [ "$GUI" == 0 ]; then
	menu -p "Enter a number: " -w "$(tput cols)" "Auto-adapt (recommended)" "Adapt using local files only" "Adapt downloading from iTunes only (slowest)" "Revert icons" "Help/About" "Exit"
	case "$REPLY" in
		1 ) OPERATION=2;;
		2 ) OPERATION=3;;
		3 ) OPERATION=4;;
		4 ) OPERATION=1;;
		5 ) help; exit 0;;
		6 ) exit 0;;
		* ) echo "${FC_RED}That's not an option!${F_RESET}"; exit 1;;
	esac
	echo
	
	menu -p "Enter a number: " -w "$(tput cols)" "Select all AppStore apps for me" "I want to choose specific app(s)"
	echo
	case "$REPLY" in
		1 )	ls -1 -d --indicator-style=none "$SANDBOX_ROOTS/"* > "$TMP_APPLIST";;
		2 ) OLDIFS="$IFS"; IFS=$'\n'
			a=( $(ls -1 -d --indicator-style=none "$SANDBOX_ROOTS/"*/*.app | awk -F'/' '{ print $NF"/"$0 }' | sort -bdft'/' | cut -d'/' -f2-) )
			menu "${a[@]##*/}"
			IFS="$OLDIFS"
			for i in $REPLY; do
				[ -n "${a[$(($i-1))]%/*}" ] && echo "${a[$(($i-1))]%/*}" >> "$TMP_APPLIST" || echo "${FC_YELLOW}Warning: $i is not a valid selection${F_RESET}"
			done
			echo
			;;
		* ) echo "${FC_RED}That's not an option!${F_RESET}"; exit 1;;
	esac
elif [ "$GUI" == 1 ]; then
	ls -1 -d --indicator-style=none "$SANDBOX_ROOTS/"* > "$TMP_APPLIST"
fi

[ ! -f "$TMP_APPLIST" ] || [ ! -s "$TMP_APPLIST" ] && { echo "${FC_RED}No apps selected${F_RESET}"; exit 1; }
pg_c=0 && pg_f="$(wc -l < "$TMP_APPLIST")"

# Adapt to retina display
echo "${FC_GREEN}Scanning $pg_f app(s)${F_RESET}"
cat "$TMP_APPLIST" | while read path_box; do
	s="$(basename "$path_box/"*.app)"
	[ "$GUI" == 0 ] && { ((pg_c++)); pbar -o -c "$pg_c" -f "$pg_f"; }
	
	iTunesArtwork="$path_box/iTunesArtwork"
	path_app="$path_box/$s"
	Info_plist="$path_app/Info.plist"
	
	[ ! -f "$Info_plist" ] && continue # This is not an app!
	
	CFBundleIconFile="$path_app/$(plutil -key CFBundleIconFile "$Info_plist" 2>/dev/null)"
	[ "$CFBundleIconFile" == "$path_app/" ] && CFBundleIconFile="$path_app/$(plutil -key CFBundleIconFiles "$Info_plist" 2>/dev/null | grep \" | grep -v -i '@2x' | cut -d\" -f2 | head -n1)"
	[ "$CFBundleIconFile" == "$path_app/" ] && CFBundleIconFile="$(find "$path_app" -iname Icon.png 2>/dev/null)"
	[ -z "$CFBundleIconFile" ] && CFBundleIconFile="$path_app/Icon.png" # Default
	
	# Skip if there's already a retina icon
	s="$(basename "$CFBundleIconFile" | sed 's/\(.*\)\..*/\1/')"
	[ -f "$(find "$path_app" -iname "${s}@2x.png")" ] && continue
	[ -f "${CFBundleIconFile}.orig" ] && [ "$OPERATION" != 1 ] && continue
	
	# Make a backup
	if [ ! -f "${CFBundleIconFile}.orig" ] && [ -f "$CFBundleIconFile" ]; then
		cp -p "$CFBundleIconFile" "${CFBundleIconFile}.orig"
	fi
	
	# OK, lets go!
	[ -f "$CFBundleIconFile" ] && rm -f "$CFBundleIconFile"
	
	# ...iSmoothProject, you're still a degenerate son of a bitch ;) shame on you for credit-stealing free code, and shame on you for not even removing this message
	
	# Revert to original icons
	if [ "$OPERATION" == 1 ]; then
		[ -f "${CFBundleIconFile}.orig" ] && mv -f "${CFBundleIconFile}.orig" "$CFBundleIconFile"
		
		if [ ! -f "$CFBundleIconFile" ]; then
			s="$(find "$path_app" -iname "Icon.png.orig")"
			[ -f "$s" ] && mv -f "$s" "${s%.orig}"
		fi
		
		[ ! -f "$CFBundleIconFile" ] && [ -f "$iTunesArtwork" ] && cp "$iTunesArtwork" "$CFBundleIconFile"
		chmod 755 "$CFBundleIconFile"
		chown mobile:mobile "$CFBundleIconFile"
		continue
	fi
	
	# Download from iTunes
	# Uses bashtrackr library by ttwj
	if ([ "$OPERATION" == 2 ] && [ ! -f "$iTunesArtwork" ]) || [ "$OPERATION" == 4 ]; then
		iTunesMetadata="$path_box/iTunesMetadata.plist"
		
		if [ -f "$iTunesMetadata" ]; then
			iTunesID="$(plutil -key itemId "$iTunesMetadata")"
		else
			CFBundleIdentifier="$(plutil -key CFBundleIdentifier "$Info_plist")"
			iTunesID="$(data_parse "$(request_send "$(bundle_getItunesIDs "$CFBundleIdentifier")")" | cut -d: -f2-)"
		fi
		
		[ -n "$iTunesID" ] && iTunesURL="$(data_parse "$(request_send "$(app_getDetails "$iTunesID" itunesurl)")" | grep 'itunesurl:' | cut -d: -f2-)"
		[ -n "$iTunesURL" ] && IconURL="$(data_parse "$(request_send "$(app_scrape "$iTunesURL")")" | grep 'icon-175:' | cut -d: -f2-)"
		[ -n "$IconURL" ] && wget -q --output-document="$iTunesArtwork" "$IconURL"
		
		if [ ! -f "$iTunesArtwork" ] || [ ! -s "$iTunesArtwork" ]; then
			echo -e "\r${CLEARTOEOL}\n${FC_RED}Failed to download iTunesArtwork for ${path_app##*/}"
			rm -f "$iTunesArtwork"
			echo "${FC_RED}iTunesID: $iTunesID${F_RESET}"
			echo "${FC_RED}CFBundleIdentifier: $CFBundleIdentifier${F_RESET}"
			echo "${FC_RED}iTunesURL: $iTunesURL${F_RESET}"
			echo "${FC_RED}IconURL: $IconURL${F_RESET}"
			echo
		fi
	fi
	
	# Local files method, imagemagick used
	if [ "$IMAGEMAGICK" == 1 ] && [ -f "$iTunesArtwork" ]; then
		tmpicon="/tmp/$SCRIPT_NAME-$RANDOM.jpg"
		djpeg -outfile "$tmpicon" "$iTunesArtwork"
		convert "$tmpicon" -resize "$RETINA_SIZE" "${tmpicon}.png"
		pincrush "${tmpicon}.png" "$CFBundleIconFile"
		rm -f "$tmpicon" "$tmpicon.png"
		[ ! -f "$CFBundleIconFile" ] && rm -f "$iTunesArtwork" # Corrupt iTunesArtwork!?  Remove it just in case.. we can redownload later
	fi
	
	# Local files method, no imagemagick
	# This is a catch-all; compatibility mode and pincrush failure are included
	if ([ ! -f "$CFBundleIconFile" ] || [ ! -s "$CFBundleIconFile" ]) && [ -f "$iTunesArtwork" ]; then
		cp "$iTunesArtwork" "$CFBundleIconFile"
	fi
	
	# ...everything failed!?
	[ ! -f "$CFBundleIconFile" ] && [ -f "${CFBundleIconFile}.orig" ] && mv -f "${CFBundleIconFile}.orig" "$CFBundleIconFile"
	
	chmod 755 "$CFBundleIconFile"
	chown mobile:mobile "$CFBundleIconFile"
done

echo "Clearing the icon cache"
rm -rf "$ICONCACHE_DIR"/*

if [ "$GUI" == 0 ]; then
	prompt "Respring now"
	if [ "$REPLY" == n ]; then
		echo "A respring/reboot should be performed later"
	elif [ "$REPLY" == y ]; then  
		echo "Performing respring"
		cleanup
		killall SpringBoard
	fi
else
	killall SpringBoard
fi

# That is all.
exit 0
