Files
bananarchy/overlay/rootfs/usr/bin/sxmo_status.sh
T

214 lines
3.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 aggregates all file content present in a folder
# It sorts file elements numerically by zero-padded priority prefix
# It watches file events to stdout new content
ROOT="${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo_status/${SXMO_STATUS_NAME:-default}"
mkdir -p "$ROOT"
lock_ex() {
:
}
lock_sh() {
:
}
free() {
:
}
usage() {
printf "Usage: %s [ACTIONS]\n" "${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=
while [ "$#" -gt 0 ]; do
arg="$1"
shift
case "$arg" in
"-f"|"-b"|"-t"|"-e"|"-o")
[ "$#" -gt 0 ] && shift
;;
*)
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" "${0##*/}" >&2
exit 1
fi
mkdir -p "$ROOT"
padded_prio="$(printf '%03d' "$priority" 2>/dev/null || printf '%s' "$priority")"
target="$ROOT/$padded_prio-$id"
lock_ex
# Remove any old file for this id with a different priority prefix
for f in "$ROOT"/*-"$id"; do
[ -e "$f" ] || continue
if [ "$f" != "$target" ]; then
rm -f "$f"
fi
done
if [ -z "$value" ]; then
rm -f "$target"
free
return
fi
if [ -r "$target" ]; then
old_val=""
read -r old_val < "$target" 2>/dev/null || true
if [ "$old_val" = "$value" ]; then
free
return
fi
fi
printf "%s\n" "$value" > "${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo_status/.tmp.$$"
mv -f "${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo_status/.tmp.$$" "$target"
free
}
del() {
id="$1"
if [ -z "$id" ]; then
printf "usage: %s -d <id>\n" "${0##*/}" >&2
exit 1
fi
lock_ex
for f in "$ROOT"/*-"$id"; do
[ -e "$f" ] || continue
rm -f "$f"
done
free
}
show() {
lock_sh
out=""
for f in "$ROOT"/*; do
[ -f "$f" ] || continue
val=""
read -r val < "$f" 2>/dev/null || true
[ -n "$val" ] || continue
if [ -z "$out" ]; then
out="$val"
else
out="$out $val"
fi
done
printf "%s\n" "$out"
free
}
debug() {
lock_sh
for f in "$ROOT"/*; do
[ -f "$f" ] || continue
val=""
read -r val < "$f" 2>/dev/null || true
printf "%s\n>%s<\n" "${f##*/}" "$val"
done
free
}
watch() {
FIFO="$(mktemp -u)"
mkfifo "$FIFO"
NOTIFYPID=
# shellcheck disable=SC2317
finish() {
[ -n "$NOTIFYPID" ] && kill "$NOTIFYPID" 2>/dev/null || true
rm -f "$FIFO"
exit 0
}
trap 'finish' TERM INT
while true; do
mkdir -p "$ROOT"
inotifywait -mq -e "close_write,move,delete,delete_self,move_self" "$ROOT" >> "$FIFO" &
NOTIFYPID=$!
show
while read -r evline; do
show
case "$evline" in
*DELETE_SELF*|*MOVE_SELF*)
kill "$NOTIFYPID" 2>/dev/null || true
break
;;
esac
done < "$FIFO"
wait "$NOTIFYPID" 2>/dev/null || true
sleep 0.1
done
}
reset() {
lock_ex
mkdir -p "$ROOT"
rm -f "$ROOT"/*
free
}
action=""
while [ "$#" -gt 0 ]; do
case "$1" in
"-o")
shift 2 2>/dev/null || shift
;;
"-s"|"-w"|"-r"|"-a"|"-d"|"-D"|"-h")
action="$1"
shift
break
;;
*)
action="$1"
shift
break
;;
esac
done
case "$action" in
""|"-s") show ;;
"-w") watch "$@" ;;
"-r") reset "$@" ;;
"-a") add "$@" ;;
"-d") del "$@" ;;
"-D") debug "$@" ;;
"-h") usage ;;
esac