eww-config/scripts/track_anything.sh

165 lines
4.1 KiB
Bash

export ZERO="$0"
HELP="$ZERO: tracker [-1] [-v [-v ...]] [q [-q ...]]
-1 run once and exit
-v increase verbosity (default >= warn)
-q decrease verbosity
"
EXITING=0
trap 'EXITING=1' INT
trace() { (( LOG_LEVEL > 2 )) && (exec 1>&2; builtin echo "$@"|grep .||true); }
debug() { (( LOG_LEVEL > 1 )) && (exec 1>&2; builtin echo "$@"|grep .||true); }
info() { (( LOG_LEVEL > 0 )) && (exec 1>&2; builtin echo "$@"|grep .||true); }
warn() { (( LOG_LEVEL > -1 )) && (exec 1>&2; builtin echo "$@"|grep .||true); }
error() { (( LOG_LEVEL > -2 )) && (exec 1>&2; builtin echo "$@"|grep .||true); }
fatal() { (exec 1>&2; builtin echo "$@"|grep .||true); exit 4; }
log() { info "$@"; }
start() {
if ! options="$(getopt vq1 -- "$@")";then
fatal "$HELP"
fi
eval set "$options"
while [ $# -gt 0 ];do
case "$1" in
-1) shift;ONCE=1 ;;
-h) echo "requesting help" ; help; exit 0 ;;
-v) LOG_LEVEL=$(( LOG_LEVEL + 1 )) ;echo increased log level ;;
-q) LOG_LEVEL=$(( LOG_LEVEL - 1 )) ;;
--) shift;break;; # we're _explicitly_ done with options
*) break;; # we're done with options.
esac
shift
done
if [ $VALIDATION ];then
# fix up the validation regex to not search.
VALIDATION="${VALIDATION#^}"
VALIDATION="${VALIDATION%'$'}"
VALIDATION='^'"$VALIDATION"'$'
fi
info "Running with LOG_LEVEL=$LOG_LEVEL"
debug " VALIDATION: $VALIDATION"
debug " RATE_LIMIT: $RATE_LIMIT"
debug "POLL_INTERVAL: $POLL_INTERVAL"
debug " watch_cmd: $watch_cmd"
if [ $(echo "$POLL_INTERVAL < $RATE_LIMIT"|bc) -eq 1 ];then
warn "POLL_INTERVAL cannot be less than RATE_LIMIT."
info "increasing POLL_INTERVAL to $RATE_LIMIT."
POLL_INTERVAL=$RATE_LIMIT
fi
while ! (( EXITING ));do
(
_poll || exit $?
(( ONCE )) && EXITING=1
$watch_cmd | while ! (( EXITING ));do
sleep $RATE_LIMIT
# read with a maximum of the poll interval minus the previous rate limit.
# rounding _up_ to the nearest second. (bc floors when scale is unset.)
if read -t $( echo "$POLL_INTERVAL - $RATE_LIMIT + .5 " | bc );then
debug "received poll. removing other poll requests."
else
debug "reached the polling interval. forcing poll."
fi
N=0
while read -t 0;do read; N=$((N + 1));done
debug "removed $N extra events"
_poll
debug "sleeping for $RATE_LIMIT"
done
) | eval "$_filter"
(( EXITING == 0 )) && (warn "tracker died. restarting after $RATE_LIMIT seconds.";sleep $RATE_LIMIT)
done
info "bye"
}
_poll() {
NEWVAL="$(poll | head -1)"
local skipped=0
echo "$NEWVAL" | while read -r LINE;do
(( skipped )) && info "$LINE"
skipped=1
done
local failed=0
if [ $JQ_VALIDATION ];then
echo "$NEWVAL" | jq -e "$JQ_VALIDATION" > /dev/null || failed=1
fi
if [ $VALIDATION ];then
echo "$NEWVAL" | grep -qE "$VALIDATION" || failed=1
fi
if (( failed ));then
warn "$NEWVAL failed validation"
else
echo "$NEWVAL"
fi
}
# MODULE OPTIONS
RATE_LIMIT=.1
rate_limit() {
RATE_LIMIT=$1
}
POLL_INTERVAL=60
poll_interval() {
POLL_INTERVAL=$1
}
_filter=uniq
filter() {
_filter="$(printf " %q" "$@")"
}
# VALIDATORS
VALIDATION=.
output_integer() {
VALIDATION='^-?[0-9]+$'
}
output_boolean() {
VALIDATION='^true|false$'
}
output_string() {
VALIDATION="${1-.*}"
}
output_json() {
JQ_VALIDATION="${1-.}"
}
# EVENT HANDLERS
# each event source needs to emit a single _EMPTY_ line per event.
# poll will be called for each line.
on_volume() { on _on_volume; }
_on_volume() {
pactl subscribe | while read -r ;do
case "$REPLY" in
*change*) echo;;
esac
done
}
on_sway() { on _on_sway; }
_on_sway() {
swaymsg -t subscribe -m '[ "workspace", "window" ]' |
jq --unbuffered -c . |
while read -r;do
echo
done
}
on() { watch_cmd="$1"; }