#!/bin/sh # mbuzzer - bot suit notification interface # FIXME # can't get socat to work properly # faulty # $ ( socat 'unix-listen:test.sock,reuseaddr,fork' - | while read line; do echo 123 $line; done )& # $ for i in $(seq 1 10); do echo $i; sleep 1; done | socat - 'unix-connect:test.sock' # desired # $ socat 'unix-listen:test.sock,reuseaddr,fork' - | while read line; do echo 123 $line; done # $ for i in $(seq 1 10); do echo $i; sleep 1; done | socat - 'unix-connect:test.sock' CONFIGPATH="${HOME}/.config/manacore" PIDFILE="${CONFIGPATH}/pid/mbuzzer.pid" MBSOCKET="${CONFIGPATH}/ipc/mbuzzer.socket" SOUNDPATH="${HOME}/.sound/event" # see mbuzzer man page for example of ALSA asoundrc config audiodev="manavol" festlang="british" playbin="play -q" notify_agent="/usr/bin/notify-send -t 2000 %t %b" notify_display="DISPLAY=:0" help() { cat << EOF mbuzzer -- bot suit notification interface -t STRING -- send event of STRING type -f FILE -- send file as event -b STRING -- send speach to festival -i -- ignore abandoned socket -n STRING -- send notification string { start | status | stop } -- operate listening server EOF } error() { echo >&2 $* ; } errcmd() { error "Incorrect command line" ; help; exit 1; } check_jq() { if ! command -v jq >/dev/null 2>&1; then error "jq (JSON parser) not found"; exit 1 fi } ignore_socket= OPTIND=1 while getopts ht:f:n:b: opt; do case "${opt}" in h) help; exit 0 ;; i) ignore_socket=1 ;; t) echo "{\"msg\":\"snd\",\"type\":\"${OPTARG}\"}" | socat - "unix-connect:${MBSOCKET}" 2>/dev/null return 0 ;; f) echo "{\"msg\":\"snd\",\"file\":\"${OPTARG}\"}" | socat - "unix-connect:${MBSOCKET}" 2>/dev/null return 0 ;; n) echo {} | jq -c -M --arg text "${OPTARG}" '.+{"text":$text,"msg":"ntf"}' | socat - "unix-connect:${MBSOCKET}" 2>/dev/null return 0 ;; b) echo {} | jq -c -M --arg text "${OPTARG}" '.+{"text":$text,"msg":"snd"}' | socat - "unix-connect:${MBSOCKET}" 2>/dev/null return 0 ;; *) errcmd ;; esac done shift $(( ${OPTIND} - 1 )) status() { if [ -f "${PIDFILE}" ]; then read pgid < "${PIDFILE}" if ps -${pgid} >/dev/null 2>&1 ; then error "Server is running" else error "Server crashed. Restart manually!" fi return 1 fi } [ -n "$2" -o -z "$1" ] && errcmd case "$1" in start) check_jq if status; then if [ -f "${MBSOCKET}" ]; then if [ -z "${ignore_socket}" ]; then error "Remove abandoned socket file ${MBSOCKET} or use -i flag" return 1 else rm "${MBSOCKET}" fi fi ( sleep 1 socat "unix-listen:${MBSOCKET},reuseaddr,fork" - | { while read line; do target= title= case "${line}" in *\"msg\":\"snd\"*) case "${line}" in *\"type\":*) target="${SOUNDPATH}/"$(printf "%s\n" "${line}" | jq -c -M -r '.type | if (type|. == "string") then . else empty end' 2>/dev/null ) if [ -n "${target}" ]; then eval ${audiodev:+AUDIODEV=${audiodev}} ${playbin} \ \"${target}\" >/dev/null 2>&1 & fi ;; *\"file\":*) target=$(printf "%s\n" "${line}" | jq -c -M -r '.file | if (type|. == "string") then . else empty end' 2>/dev/null ) if [ -n "${target}" ]; then eval ${audiodev:+AUDIODEV=${audiodev}} ${playbin} \ \"${target}\" >/dev/null 2>&1 & fi ;; *\"text\":*) target=$( printf "%s\n" "${line}" | jq -c -M -r '.text | if (type|.=="string") then . else empty end' 2>/dev/null ) if [ -n "${target}" ]; then printf "%s\n" "${target}" | festival --language "${festlang}" --tts fi ;; esac ;; *\"msg\":\"ntf\"*) title=$( printf "%s\n" "${line}" | jq -c -M -r '.title | if (type|. == "string") then . else empty end' 2>/dev/null | sed "s/'/'\"'\"'/g;s|[\/&]|\\\\&|g;s/$/\\\\/" ) target=$( printf "%s\n" "${line}" | jq -c -M -r '.text | if (type|. == "string") then . else empty end' 2>/dev/null | sed "s/'/'\"'\"'/g;s|[\/&]|\\\\&|g;s/$/\\\\/" ) if [ -n "${target}" ]; then nfagent=$( printf "%s\n" "${notify_agent}" | \ sed "s/%t/'${title:-TMW sWatcher}'/;s/%b/'${target}'/" ) eval "${notify_display}" "${nfagent}" >/dev/null 2>&1 fi ;; esac done } ) >/dev/null 2>&1 & pgid=$( ps -o pgid= $! ) if [ -z "${pgid}" ]; then error "Run failed" else printf "%s\n" "${pgid}" > "${PIDFILE}" fi else return 1 fi ;; stop) if [ -f "${PIDFILE}" ]; then read pgid < "${PIDFILE}" if kill -- -${pgid} >/dev/null 2>&1; then rm -f "${PIDFILE}" # "${SOUNDSOCKET}" else error "Can't kill pgid ${pid}; remove socket and pid file ${PIDFILE} manually" fi fi ;; status) status && error "No server running" : ;; *) errcmd ;; esac