#!/bin/bash
##
# whereispypanel by Katja (fly5.kapsi.fi)
#
# pypanel has a bad habit to crash. this is my fix for that. if pypanel
# is not running, this starts it again. you can also define it to start
# those applications that goes crazy without pypanel's tray.
#
# for usage, you can just leave it running on background and if you get
# curious what's happening, watch the log. if you wan't you can run it
# also on foreground.
#	e.g. (exempli gratia)
#	whereispypanel &; tail -f $HOME/.whereispypanel/loki.log
#
# if on foreground you can quit with ctrl + c, and you can always just
# send a kill signal to terminate it. please don't use SIGKILL (-9), or
# the lockfile can't be cleaned.. if you already did it, see the NOTE
#
# NOTE:
# if the script won't start and says it's already running and you are sure
# it isn't, double check it and rebuke yourself of killing it with unnecessary
# high signal, without giving script any change to clean up things.. after
# that you can fix the problem by removing the lockfile (lukko)
##

##
# SETTINGS
##

# directory for log and lockfile
hakemisto="$HOME/.whereispypanel"

# let's log something..
loki="$hakemisto/loki.log"

# list of programs to kill after crash, "just in case progs" or if they
# keep running in the background or anything.. for example gclip goes
# crazy without tray and docker is just too much with the pypanel.
# (yes i try to kill that dead pypanel also.. just in case :P)
prosessit="gclip docker pypanel"

# pelastettavat is the list of programs to save and launch after panel crash
# pypanel is already launched before these, so don't list it
pelastettavat="gclip"

# is everything ok? when nothing has happened yet i assume so..
# feel free to test what happens with 1 here..
mitenmeni=0

# lockfile used to check if it's already running
lukko="$hakemisto/lukko.lock"

# how many seconds to sleep before next check
nuku=10

##
# END OF SETTINGS
##

##
# don't edit below this if you don't know what you're doing
##

# create settings dir, if it doesn't exist
mkdir -p "$hakemisto" 2>&-
# permission problems?
if [ "$?" == "1" ]; then
	echo "Permission denied: $hakemisto"
	echo "Check the preferences and try again."
	exit 1
fi

# log file..
touch $loki
lokiexit=$?
sleep 0.5
if [ "$lokiexit" == "1" ]; then
	echo "Permission denied: $loki"
	echo "Check the preferences and try again."
	exit 1
# ..is it writable
elif [ ! -w "$loki" ]; then
	echo "Permission denied: $loki"
	echo "Check the preferences and try again."
	exit 1
fi

# for hourlog
tunti="`date +\"%H\"`"
viimetunti=$tunti

kokojuttu () {
# let's give new info..
paiva="`date +\"%Y-%m-%d %H:%M\"`"
skripti="$paiva - `basename $0`"
onkook=0

# while everything is ok..
while [ "$mitenmeni" == "0" ]; do # mainloop
	# hourlog
	tunti="`date +\"%H\"`"
	if [ "$tunti" != "$viimetunti" ]; then
		echo "$skripti - It's $tunti o'clock and all is well." >> $loki
		viimetunti=$tunti
	fi
	# we just want the exit status
	pidof -x pypanel > /dev/null
	# when everything isn't ok..
	if [ "$?" == "1" ]; then # exitcode
		echo "$skripti - GRR, it happened again.. " >> $loki
		kuolkaa="`pidof -x $prosessit`"
		# if there is something to kill, then we kill it
		if [ ! -z "$kuolkaa" ]; then # kuolkaa
			kill $kuolkaa 2>&- 1>&-
						# ^ they say deridecting to
						# /dev/null is ugly, so we just
						# close the file descriptor..
		fi # kuolkaa end
		sleep 1
		# finally we start it..
		pypanel 2>&- 1>&- &
		sleep 1
		if [ -z "`pidof -x pypanel`" ]; then # paneeli
			echo "$skripti - .. we lost pypanel!" >> $loki
			onkook=1
		else
			echo "$skripti - .. pypanel is safe!" >> $loki
			onkook=0
			# lets save our programs..
			for uhri in $pelastettavat; do # pelastus
				$uhri 2>&- 1>&- &
				sleep 0.5
				if [ ! -z "`pidof -x $uhri`" ]; then # uhri
					echo "$skripti - .. we saved $uhri." >> $loki
				else
					echo "$skripti - .. nooo, $uhri didn't survive." >> $loki
				fi # uhri end
			done # pelastus end
		fi # paneeli end
	fi # exitcode end
	
	# if error, sleep only second.. we want to re-run this ASAP
	if [ "$onkook" == "1" ]; then # error
		sleep 1
	else
		sleep $nuku
	fi # error end
done # mainloop end
# it shouldn't get this far, but just in case..
exit $mitenmeni
}

loppu() {
echo "`basename $0`: Ok then. BYE!"
echo "$skripti - Quit" >> $loki
rm -f $lukko
trap - EXIT
exit 0
}

paiva="`date +\"%Y-%m-%d %H:%M\"`"
skripti="$paiva - `basename $0`"

# trapping signals, one running script is enough.
# this also calls the function that does the "real job"
if [ ! -e "$lukko" ]; then
	trap loppu INT TERM EXIT
	echo "$skripti - Running [PID: $$]" >> $loki
	touch $lukko
	echo $$ > $lukko
	kokojuttu
	rm $lukko
	trap - INT TERM EXIT
else
	vanha="`cat $lukko`"
	echo "`basename $0` - Already running [PID: $vanha]"
	echo "$skripti - Already running [PID: $vanha]" >> $loki
	exit 1
fi

##
# 29.07.2007 - seems to work.
##