#!/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 : add a bar component\n" >&2 printf " -d : 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 \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 \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