mirror of https://gitlab.com/dabruh/dotfiles.git
160 lines
3.7 KiB
Bash
Executable File
160 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# cmusctl
|
|
#
|
|
# Allows executing 'cmus-remote' commands and writes the currently
|
|
# playing song to a file so be consumed by e.g. i3status.
|
|
|
|
SCRIPT_NAME="$(basename -- "$0")"
|
|
|
|
function usage() {
|
|
echo "Usage: $SCRIPT_NAME [OPTIONS]"
|
|
echo
|
|
echo "Options:"
|
|
echo " -h Display help."
|
|
echo " -e [COUNT] Run forever, every [COUNT] seconds. Disabled (0) by default."
|
|
echo " -l Kill other $SCRIPT_NAME processes. Only allowed if running forever."
|
|
}
|
|
|
|
while getopts ":e:c:lh" arg; do
|
|
case $arg in
|
|
e) EVERY=$OPTARG ;;
|
|
c) COMMAND=$OPTARG ;;
|
|
l) AQUIRE_LEADER=true ;;
|
|
h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
:)
|
|
echo "$SCRIPT_NAME: Must supply an argument to -$OPTARG." >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
?)
|
|
echo "Invalid option: -${OPTARG}."
|
|
echo
|
|
usage
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
LOOP=false
|
|
EVERY="${EVERY:-0}"
|
|
[[ $EVERY -gt 0 ]] && LOOP=true
|
|
AQUIRE_LEADER="${AQUIRE_LEADER:-false}"
|
|
OUTPUT_FILE="/tmp/$SCRIPT_NAME.status"
|
|
PREV_STATUS=""
|
|
|
|
function multiple_instances_running() {
|
|
[[ "$(pgrep -f "$SCRIPT_NAME" | grep -cv "^$$$")" -gt 1 ]] || return 1
|
|
}
|
|
|
|
function aquire_leader() {
|
|
echo "Aquiring leadership"
|
|
|
|
if ! [[ "$EVERY" -gt 0 ]]; then
|
|
echo "ERROR: -e [COUNT] must be a positive integer for leader aquisition." 1>&2
|
|
exit 11
|
|
fi
|
|
|
|
while read -r pid; do
|
|
[[ "$pid" == "$$" ]] && continue
|
|
|
|
if ! kill "$pid"; then
|
|
echo "ERROR: Unable to kill $pid." 1>&2
|
|
exit 12
|
|
fi
|
|
done <<<"$(pgrep -f "$SCRIPT_NAME")"
|
|
|
|
echo "Leadership aquired."
|
|
}
|
|
|
|
function write_status() {
|
|
local status="$1"
|
|
|
|
# Don't write if there's no update
|
|
if [[ "$status" != "$PREV_STATUS" ]]; then
|
|
echo "$status" | tee "$OUTPUT_FILE"
|
|
killall -SIGUSR1 i3status
|
|
export PREV_STATUS="$status"
|
|
else
|
|
echo "NOCHG"
|
|
fi
|
|
|
|
! $LOOP && exit 0
|
|
sleep "$EVERY"
|
|
}
|
|
|
|
function get_field() {
|
|
local row
|
|
row="$(grep "^$1 " <<<"$QUERY_RESULT")"
|
|
echo "${row#"$1 "}"
|
|
}
|
|
|
|
function get_status() {
|
|
local tmp status
|
|
tmp="$(get_field status)"
|
|
status="$tmp"
|
|
[ "$tmp" == "playing" ] && status="▶"
|
|
[ "$tmp" == "paused" ] && status="⏸️"
|
|
[ "$tmp" == "stopped" ] && status="⏹️"
|
|
echo $status
|
|
}
|
|
|
|
function get_progress() {
|
|
local duration position
|
|
duration="$(get_field duration)"
|
|
position="$(get_field position)"
|
|
|
|
if [ -n "$duration" ] && [ -n "$position" ]; then
|
|
echo "$(((position * 100 / duration * 100) / 100))%"
|
|
fi
|
|
}
|
|
|
|
function get_artist_title() {
|
|
local tag_artist tag_title
|
|
tag_artist="$(get_field "tag artist")"
|
|
tag_title="$(get_field "tag title")"
|
|
if [ -n "$tag_artist" ] && [ -n "$tag_title" ]; then
|
|
echo "$tag_artist - $tag_title"
|
|
fi
|
|
}
|
|
|
|
function get_file_name() {
|
|
local fn
|
|
fn="$(get_field file)"
|
|
fn="${fn##*/}"
|
|
fn="${fn%.*}"
|
|
echo "$fn"
|
|
}
|
|
|
|
if $LOOP && multiple_instances_running; then
|
|
if $AQUIRE_LEADER; then
|
|
echo "Other instances have been detected."
|
|
aquire_leader
|
|
else
|
|
echo "ERROR: Other instances are running and leader aquisition not set." 1>&2
|
|
exit 10
|
|
fi
|
|
fi
|
|
|
|
# shellcheck disable=SC2086
|
|
[ -n "$COMMAND" ] && cmus-remote $COMMAND
|
|
|
|
while true; do
|
|
QUERY_RESULT="$(cmus-remote --query 2>/dev/null)"
|
|
[ -z "$QUERY_RESULT" ] && write_status "🎵❌" && continue
|
|
|
|
PROGRESS="$(get_progress)"
|
|
STATUS="$(get_status)"
|
|
NAME="$(get_artist_title)"
|
|
[ -z "$NAME" ] && NAME="$(get_file_name)"
|
|
|
|
OUT="${STATUS^}"
|
|
[ -n "$NAME" ] && OUT+=" $NAME"
|
|
[ -n "$PROGRESS" ] && [ "$STATUS" != "⏹️" ] && OUT+=" ($PROGRESS)"
|
|
|
|
write_status "$OUT"
|
|
done
|