# currently doing. Subshells keep the periodicity independent
# of response time to the script
#
-# (C) 2010 Dan White <dan@whiteaudio.com> under GPL
+# (C) 2010--2016 Dan White <dan@whiteaudio.com> under GPLv3
# idea from: http://wiki.43folders.com/index.php/Time_sampling
+#
+# Various ways to make a beep sound
+#
#BEEP="beep -f707 -n -f500"
#BEEP="beep -f707 -n -f500 -n -f707"
#BEEP="dcop knotify default notify notify Me notext KDE_Vox_Ahem.ogg nofile 1 0"
-#BEEP="aplay /home/dan/tmp/pop.wav"
-BEEP="play /home/dan/tmp/pop.wav"
+#BEEP="play /home/dan/tmp/pop.wav"
+BEEP="aplay /home/dan/tmp/pop.wav"
+
+#
+# Interval between popups
+#
MINUTES=6 #to give 10/hour
-#MAXJOBS=$((1*60/$MINUTES))
-#MAXJOBS=8
+
+#
+# Only allow this many popups active at a time. Overnight or long away-from-
+# computer intervals don't clog the UI.
+#MAXJOBS=$((1*60/$MINUTES)) #as number of hours
MAXJOBS=25
-MAXJOBS=$(($MAXJOBS-1))
+
+#
+# Append timeSamples to these files
+#
LOGFILE="$HOME/.timeSampler.$HOSTNAME"
BACKUPFILE="$HOME/.timeSampler.all"
+
+########################
+# End of configuration
+########################
+
+
+#index of the last buffer entry
+BUFFER_END=$(($MAXJOBS-1))
+
#put something in the buffer to start
-for i in $(seq 0 $MAXJOBS); do
+for i in $(seq 0 $BUFFER_END); do
buffer[$i]="$i"
done
+
+
+#
+# Get the last recorded activity tag text
+#
function lastActivity {
#python -c "print ' '.join(open('$LOGFILE').readlines()[-1].split()[2:])"
tail -1 $LOGFILE | cut -d' ' -f3-
}
-# popup without blocking main script
+
+
+#
+# Make a popup dialog pre-filled with the last answer.
+# This is blocking, but is run in a sub-shell in the background.
+#
function sampleTask {
DATE=$(date +"%F %R")
ACTIVITY=$(zenity --entry \
+#
# calculate the minutes to the next $MINUTES slot from top-of-hour
+#
function nexttime {
#remove leading zero to ensure we stay in base-10
nowmin=$(date '+%M' | sed 's/^0//')
-
-thispid=$$
-while true; do
- if [[ $(lastActivity) != "null" ]]; then
- $BEEP > /dev/null 2>&1
- sleep 0.8
- fi
- (sampleTask) &
- pid=$!
+#
+# push current PID in, return the oldest that got pushed out
+#
+function fifoPushKillOldest {
+ pid=$1
#FIFO of subshell PIDs
- # or i+=1, and buffer[i % $MAXJOBS]
+ # first entry is oldest, last entry is newest
oldest=${buffer[0]}
for i in $(seq 0 $(( ${#buffer[@]}-1 )) ); do
buffer[$i]=${buffer[$(($i+1))]}
done
- buffer[$MAXJOBS]=$pid
+ buffer[$BUFFER_END]=$pid
+ # Kill the oldest dialog box (which is runnng as a child of the oldest
+ # subshell, resulting in a "null" entry in the logfile.
for j in `jobs -p`; do
if [ "$j" == "$oldest" ]; then
for zenitypid in $(ps --no-headers --ppid $oldest -o pid); do
+ echo "zenity pid: $zenitypid"
kill -9 $zenitypid
done
fi
done
+}
+
+
+
+thispid=$$
+echo "$thispid" > ~/.timeSampler.pid
+
+while true; do
+ if [[ $(lastActivity) != "null" ]]; then
+ $BEEP > /dev/null 2>&1
+ sleep 0.8
+ fi
+ (sampleTask) &
+ pid=$!
+
+ # store PID in FIFO and kill the oldest
+ fifoPushKillOldest $pid
+
+
+ # Old way, sleep for a bit
+ #sleep $(($MINUTES*60 - 1))
+
+ # New way: stop, then send myself a continue at an exact MINUTES boundary
#send a continue signal to myself in the future
echo "kill -CONT $thispid" | at now + $(nexttime) minutes > /dev/null 2>&1
- #stop myself until continued
+
+ #stop myself, will resume when above "at" command fires
kill -SIGSTOP $thispid
- #sleep $(($MINUTES*60 - 1))
done