Files
sxmo-utils/scripts/core/sxmo_status.sh
ArenM f630b2bbdb sxmo_status.sh add locking
Watch was spitting out no such file or directory errors, that I think
were caused by a race between updating the status bar, and removing
items.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
2023-03-31 19:29:15 +02:00

160 lines
2.7 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# A pretty generic status content generator
# It aggregate all file content present in a folder
# It sort file elements numerically
# It can watch file events to stdout new content
ROOT="$XDG_RUNTIME_DIR/sxmo_status/${SXMO_STATUS_NAME:-default}"
mkdir -p "$ROOT"
exec 3> "$XDG_RUNTIME_DIR/sxmo_status/sxmo_status.lock"
_sorted_components_name() {
find "$ROOT" -mindepth 1 -exec 'basename' '{}' ';' | sort -n
}
lock_ex() {
flock -x 3
}
lock_sh() {
flock -s 3
}
free() {
flock -u 3
}
usage() {
printf "Usage: %s [ACTIONS]\n" "$(basename "$0")" >&2
printf "ACTIONS:\n" >&2
printf " -s: the status content (default action)\n" >&2
printf " -w: file events and stdout status content\n" >&2
printf " -a <id> <priority> <content>: add a bar component\n" >&2
printf " -d <id>: remove a bar component\n" >&2
printf " -r: remove all bar components\n" >&2
printf " -D: the status content explained\n" >&2
printf " -h: this message\n" >&2
}
add() {
id=
priority=
value=
lock_ex
while [ -n "$*" ]; do
arg="$1"
shift
case "$arg" in
"-f"|"-b"|"-t"|"-e")
shift # we shallow this
;;
*)
if [ -z "$id" ]; then
id="$arg"
elif [ -z "$priority" ]; then
priority="$arg"
elif [ -z "$value" ]; then
value="$arg"
fi
;;
esac
done
if [ -z "$id" ] || [ -z "$priority" ]; then
printf "usage: %s -a <id> <priority> <value>\n" "$(basename "$0")" >&2
exit 1
fi
del "$id"
id="$priority-$id"
if [ -n "$value" ]; then
printf "%s" "$value" > "$ROOT"/"$id"
fi
free
}
del() {
lock_ex
id="$1"
shift
if [ -z "$id" ]; then
printf "usage: %s -d <id>\n" "$(basename "$0")" >&2
exit 1
fi
_sorted_components_name | grep -m1 "\-$id$" | xargs -rI{} rm -f "$ROOT"/"{}"
free
}
show() {
lock_sh
_sorted_components_name | while read -r id; do
tr '\n' ' ' < "$ROOT/$id"
printf " "
done | head -c -1 | tr '\n' '\0' | xargs -0 -n1 printf "%s\n"
free
}
debug() {
lock_sh
_sorted_components_name | while read -r id; do
printf "%s\n>" "$id"
tr '\n' ' ' < "$ROOT/$id"
printf "<\n"
done
free
}
watch() {
FIFO="$(mktemp -u)"
mkfifo "$FIFO"
inotifywait -mq -e "close_write,move,delete" "$ROOT" >> "$FIFO" &
NOTIFYPID=$!
# shellcheck disable=SC2317
finish() {
kill "$NOTIFYPID"
rm "$FIFO"
exit 0
}
trap 'finish' TERM INT
show
# shellcheck disable=SC2034
while read -r _; do
show
done < "$FIFO"
}
reset() {
lock_ex
find "$ROOT" -mindepth 1 -delete
free
}
if [ -n "$*" ]; then
action="$1"
shift
fi
case "$action" in
""|"-s") show ;;
"-w") watch "$@" ;;
"-r") reset "$@" ;;
"-a") add "$@" ;;
"-d") del "$@" ;;
"-D") debug "$@" ;;
"-h") usage ;;
esac