add track_anything.sh and use it for volume and mute
This commit is contained in:
parent
269bbad218
commit
124acaa789
80
README.md
80
README.md
|
@ -3,3 +3,83 @@
|
|||
My personal eww config.
|
||||
|
||||
Install by linking or cloning to ~/.config/eww
|
||||
|
||||
## `track_anything.sh`
|
||||
|
||||
This config includes a helper bash source which may be used
|
||||
to setup trackers of values. It requires an on_event emitter
|
||||
to already exist and should have one of the three output
|
||||
formats: integer, boolean, and string.
|
||||
|
||||
When specifying a string output, you may include a custom regex
|
||||
which will not be searched (it will be wrapped in `^`...`$`).
|
||||
|
||||
### `poll`
|
||||
|
||||
In addition to the configuration, you must provide a poll function.
|
||||
|
||||
Your provided poll function must return a valid output as its first
|
||||
line and may provide log data on subsequent lines which will be
|
||||
emitted at the info level (stderr, single -v).
|
||||
|
||||
A simple example is the pulseaudio mute state poller:
|
||||
|
||||
```bash
|
||||
poll() {
|
||||
pamixer --get-mute
|
||||
}
|
||||
```
|
||||
|
||||
### `Configuration`
|
||||
|
||||
Options:
|
||||
|
||||
- rate_limit
|
||||
- seconds to wait between running poll
|
||||
(default: `1`)
|
||||
|
||||
- poll_interval
|
||||
- seconds to wait for an update before forcing a poll
|
||||
(default: `60`)
|
||||
- NOTE: must satisfy poll_interval >= rate_limit
|
||||
|
||||
- filter: an arbitrary command to filter the total output of the poller in a loop
|
||||
(default: `uniq`)
|
||||
- NOTE: all arguments are collected and executed with eval.
|
||||
- Example: `cat` will allow duplicates. `uniq` will filter them.
|
||||
|
||||
Event Emitters:
|
||||
|
||||
- `on_volume`
|
||||
- emits on changes to pulseaudio sinks
|
||||
|
||||
- `on_sway`
|
||||
- emits on changes to sway windows or workspaces
|
||||
|
||||
- `on`
|
||||
- uses your own function to trigger an event
|
||||
which should be passed as the only argument to `on`
|
||||
- NOTE: the function in question _must_ emit events
|
||||
as newlines with no text. multiple events may be
|
||||
emitted in general safety if `rate_limit` is > 0
|
||||
|
||||
|
||||
Outputs:
|
||||
|
||||
- `output_integer`
|
||||
- output a decimal integer
|
||||
|
||||
- `output_boolean`
|
||||
- output a boolean (true, false)
|
||||
|
||||
- `output_string`
|
||||
- output an arbitrary string, validated by a regex
|
||||
- args:
|
||||
- a validation regex string as the first argument
|
||||
(default: `.*`)
|
||||
|
||||
- `output_json`
|
||||
- output an arbitrary json value, validated by jq
|
||||
- args:
|
||||
- a validation jq query which must not fail or return null
|
||||
(default: `.`)
|
164
scripts/track_anything.sh
Normal file
164
scripts/track_anything.sh
Normal file
|
@ -0,0 +1,164 @@
|
|||
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"; }
|
|
@ -1,7 +1,16 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pactl subscribe | while read -r ;do
|
||||
case "$REPLY" in
|
||||
*change*) pamixer --get-mute ;;
|
||||
esac
|
||||
done
|
||||
. "$(dirname "$0")/track_anything.sh"
|
||||
|
||||
|
||||
poll() {
|
||||
pamixer --get-mute
|
||||
}
|
||||
|
||||
rate_limit .1
|
||||
poll_interval 60
|
||||
on_volume
|
||||
output_boolean
|
||||
filter uniq
|
||||
|
||||
start "$@"
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
. "$(dirname "$0")/track_anything.sh"
|
||||
|
||||
poll() {
|
||||
pamixer --get-volume | grep -E '^[0-9]+$'
|
||||
pamixer --get-volume
|
||||
}
|
||||
|
||||
pactl subscribe | while read -r ;do
|
||||
case "$REPLY" in
|
||||
*change*) poll ;;
|
||||
esac
|
||||
done
|
||||
on_volume
|
||||
output_integer
|
||||
poll_interval 10
|
||||
rate_limit .1
|
||||
|
||||
start "$@"
|
||||
|
|
Loading…
Reference in New Issue
Block a user