tojam/tojam

349 lines
13 KiB
Bash
Executable File

#!/usr/bin/env bash
# Dialog accessibility
export DIALOGOPTS='--no-lines --visit-items'
# Functions
help() {
echo "${0##*/}"
echo -e "Released under the terms of the WTFPL License: http://www.wtfpl.net\n"
echo -e "Usage:\n"
echo "With no arguments, open recent servers list."
for i in "${!command[@]}" ; do
echo "-${i/:/ <parameter>}: ${command[${i}]}"
done | sort
exit 0
}
# Array of command line arguments
declare -A command=(
[a]="Add a server."
[c]="Configure ${0##*/}."
[d]="Delete a server."
[h]="This help screen."
[T]="Dedication."
)
add_server() {
# Have to validate the form
local errorMessage
local valid="false"
while [[ "${valid}" != "true" ]]; do
valid="true"
serverInfo="$(dialog --backtitle "Tojam" --title "Add Server" \
--form "\nEnter Server Information:\n\nUse up and down to move between fields, enter to accept, or escape to cancel." 25 60 16 \
"Server Name:" 1 1 "" 1 25 25 50 \
"Server Address:" 2 1 "" 2 25 25 50 \
"Server Port:" 4 1 "2049" 4 25 6 6 --stdout)"
mapfile -t serverInfo < <(echo "${serverInfo//^$/}")
if [[ "${#serverInfo[0]}" -le 1 ]]; then
errorMessage+="Server name was missing.\n"
valid="false"
fi
if [[ "${#serverInfo[1]}" -le 1 ]]; then
errorMessage+="Server address was missing.\n"
valid="false"
fi
if ! [[ "${serverInfo[2]}" =~ ^[1-9][0-9]*$ ]]; then
errorMessage+="Port must be numeric.\n"
valid="false"
fi
for i in "${!servers[@]}" ; do
if [[ "$i" == "${serverInfo[0]}" ]]; then
errorMessage+="Server name \"$i\" is already in use.\n"
valid="false"
fi
if [[ "${servers[${i}]}" == "${serverInfo[1]}" ]]; then
errorMessage+="Server address \"$i\" is already added.\n"
valid="false"
fi
done
if [[ "${valid}" == "false" ]]; then
dialog --msgbox "${errorMessage}" -1 -1
errorMessage=""
fi
done
echo "[${serverInfo[0]}]=\"${serverInfo[1]}:${serverInfo[2]}\"" >> "${config}/servers.conf" || exit 2
dialog --msgbox "Server \"${serverInfo[0]}\" added. Please relaunch ${0##*/} to use the updated server list." -1 -1
exit 0
}
delete_server() {
# Get servers into an array.
mapfile -t lines < "${config}/servers.conf"
for i in "${lines[@]}" ; do
j="${i#\[}"
j="${j/\]=\"/: }"
j="${j%\"}"
menuList+=("$i" "${j}")
done
server="$(dialog --clear \
--backtitle "Tojam" \
--no-tags \
--ok-label "Delete" \
--menu "Select a Ninjam server to be deleted" -1 -1 -1 "${menuList[@]}" --stdout)"
menuCode=$?
if [ ${menuCode} -eq 1 -o ${menuCode} -eq 255 ]; then
exit 0
fi
tmpFile="$(mktemp -t XXXXXX)"
grep -vF "$server" "${config}/servers.conf" > "${tmpFile}" || exit 3
mv "${tmpFile}" "${config}/servers.conf" || exit 4
dialog --msgbox "Server deleted." -1 -1
exit 0
}
configure_ninjam() {
local menuCode=0
while [[ $menuCode -ne 1 ]]; do
settings=(
"anonymous" "Login in anonymously: ($anonymous)"
"save local wavs" "Save Individual Tracks: (${saveLocalWavs})"
"save mixdown" "Save Mixdown: (${saveMixdown})"
"save source files" "Save Source Files: (${saveSourceFiles/-nosavesourcefiles/false recommended})"
"sound driver" "Sound Driver: (${soundDriver%% *})"
"username" "Set User Name: (${userName#*anonymous:})"
)
setting="$(dialog --backtitle "Tojam" \
--no-tags \
--cancel-label "Close" \
--menu "Select a setting" -1 -1 -1 "${settings[@]}" --stdout)"
menuCode=$?
if [ ${menuCode} -eq 1 -o ${menuCode} -eq 255 ]; then
exit 0
fi
case "${setting}" in
"anonymous")
anonymous="$(dialog --yesno "Login anonymously? (You still have a username but password is not required.)" -1 -1 --stdout)"
anonymous=$?
[[ ${anonymous} -eq 255 ]] && continue
anonymous="${anonymous/0/true}"
anonymous="${anonymous/1/false}"
sed -i "s/^anonymous=.*/anonymous=\"${anonymous}\"/" "${config}/config" &&
dialog --msgbox "Anonymous login set to ${anonymous}." -1 -1
;;
"save local wavs")
saveLocalWavs="$(dialog --yesno "Save individual tracks? (Output is in wav format.)" -1 -1 --stdout)"
saveLocalWavs=$?
[[ ${saveLocalWavs} -eq 255 ]] && continue
saveLocalWavs="${saveLocalWavs/0/true}"
saveLocalWavs="${saveLocalWavs/1/false}"
sed -i "s/^saveLocalWavs=.*/saveLocalWavs=\"${saveLocalWavs}\"/" "${config}/config" &&
dialog --msgbox "Save individual tracks set to ${saveLocalWavs}." -1 -1
;;
"save mixdown")
saveMixdown="$(dialog --yes-label "disabled" \
--extra-button \
--extra-label "ogg" \
--no-label "wav" \
--yesno "Select a Mixdown Format" -1 -1 --stdout)"
saveMixdown=$?
[[ ${saveMixdown} -eq 255 ]] && continue
saveMixdown="${saveMixdown/0/disabled}"
saveMixdown="${saveMixdown/1/wav}"
saveMixdown="${saveMixdown/3/ogg}"
if [[ "${saveMixdown}" == "disabled" ]] || [[ "${saveMixdown}" == "wav" ]]; then
sed -i "s/^saveMixdown=.*/saveMixdown=\"${saveMixdown}\"/" "${config}/config" &&
dialog --msgbox "Save mixdown: ${saveMixdown}" -1 -1
continue
fi
local bitrates=(
"64" "64" "off"
"96" "96" "off"
"128" "128" "on"
"160" "160" "off"
"192" "192" "off"
"224" "224" "off"
"256" "256" "off"
)
oggBitrate="$(dialog --backtitle "Tojam" \
--no-tags \
--radiolist "Select Bitrate" -1 -1 -1 "${bitrates[@]}" --stdout)"
menuCode=$?
if [ ${menuCode} -eq 1 -o ${menuCode} -eq 255 ]; then
exit 0
fi
sed -i -e "s/^saveMixdown=.*/saveMixdown=\"${saveMixdown}\"/" -e "s/^oggBitrate=.*/oggBitrate=\"${oggBitrate}\"/" "${config}/config" &&
dialog --msgbox "Save mixdown: ${saveMixdown}" -1 -1
;;
"sound driver")
soundDriver="$(dialog --yes-label "alsa" \
--no-label "jack" \
--yesno "Select a sound driver" -1 -1 --stdout)"
soundDriver=$?
[[ ${soundDriver} -eq 255 ]] && continue
soundDriver="${soundDriver/0/alsa}"
soundDriver="${soundDriver/1/jack}"
if [[ "${soundDriver}" == "jack" ]]; then
sed -i 's/^soundDriver=.*/soundDriver="jack"/' "${config}/config" &&
dialog --msgbox "Sound driver set to jack." -1 -1
continue
fi
mapfile -t cardList < <(aplay -l | grep -E '^card [0-9]+: [[:alnum:]]+ \[' | cut -f1 -d '[' | uniq)
declare -a soundcards
for i in "${cardList[@]}" ; do
soundcards+=("${i##*: }" "${i}")
done
soundcard="$(dialog --backtitle "Tojam" \
--no-tags \
--menu "Select the sound card Ninjam should use" -1 -1 -1 "${soundcards[@]}" --stdout)"
menuCode=$?
if [ ${menuCode} -eq 1 -o ${menuCode} -eq 255 ]; then
continue
fi
soundDriver="$(dialog --backtitle "Tojam" --title "Alsa Configuration" \
--form "\nEnter alsa parameters:\n\nUse up and down to move between fields, enter to accept, or escape to cancel.\nSane defaults are used, but if it doesn't work, you will need to consult the documentation for your sound card." 25 60 16 \
"nblock:" 1 1 "16" 1 25 25 50 \
"bsize:" 2 1 "256" 2 25 25 50 \
"bps:" 4 1 "16" 4 25 6 6 \
"srate:" 5 1 "48000" 5 25 6 6 \
"nch:" 6 1 "2" 6 25 6 6 \
"in:" 7 1 "${soundcard}" 7 25 25 25 \
"out:" 8 1 "${soundcard}" 8 25 25 25 --stdout)"
if [ ${menuCode} -eq 1 -o ${menuCode} -eq 255 ]; then
continue
fi
mapfile -t alsaParameters < <(echo "${soundDriver}")
alsaParameters[0]="nblock ${alsaParameters[0]}"
alsaParameters[1]="bsize ${alsaParameters[1]}"
alsaParameters[2]="bps ${alsaParameters[2]}"
alsaParameters[3]="srate ${alsaParameters[3]}"
alsaParameters[4]="nch ${alsaParameters[4]}"
alsaParameters[5]="in hw:${alsaParameters[5]}"
alsaParameters[6]="out hw:${alsaParameters[6]}"
soundDriver="alsa"
alsaParameters="${alsaParameters[*]}"
sed -i -e "s/^soundDriver=.*/soundDriver=\"${soundDriver}\"/" -e "s/^alsaParameters=.*/alsaParameters=\"${alsaParameters}\"/" "${config}/config" &&
dialog --msgbox "Sound driver set to alsa." -1 -1
;;
"username")
userName="$(dialog --backtitle "Tojam" \
--inputbox "Enter User Name (letters, numbers, dash, and underscore accepted):" -1 -1 "${userName#*anonymous:}" --stdout)"
menuCode=$?
[[ ${menuCode} -ne 0 ]] && continue
sed -i "s/^userName=.*/userName='${userName}'/" "${config}/config" &&
dialog --msgbox "Username set to \"${userName#*anonymous:}\"." -1 -1
;;
esac
done
dialog --msgbox "Please relaunch ${0##*/} to continue." -1 -1
exit 0
}
save_files() {
if [[ "${saveMixdown}" == "disabled" ]]; then
return
elif [[ "${saveMixdown}" == "wav" ]]; then
echo "-writewav"
else
echo "-writeogg ${oggBitrate}"
fi
}
# Configuration stuff
config="${XDG_CONFIG_HOME:-${HOME}/.config}/tojam"
sessiondir="${HOME}/tojam-sessions"
mkdir -p "${config}"
if ! [[ -r "${config}/config" ]]; then
# Write initial config file
{ echo 'alsaParameters=""';
echo 'anonymous="true"';
echo 'oggBitrate="128"';
echo 'saveLocalWavs="false"';
echo 'saveMixdown="disabled"';
echo 'saveSourceFiles="false"';
echo 'soundDriver="jack"';
echo "userName='Tojam$(date '+%S')'"; } >> "${config}/config"
fi
source "${config}/config"
# Fix up username if anonymous is true
if [[ "${anonymous}" == "true" ]]; then
userName="anonymous:${userName}"
fi
# Fix up the source files setting
if [[ "${saveSourceFiles}" == "false" ]]; then
saveSourceFiles="-nosavesourcefiles"
else
saveSourceFiles=" "
fi
# Convert the keys of the associative array to a format usable by getopts
args="${!command[*]}"
args="${args//[[:space:]]/}"
while getopts "${args}" i ; do
case "$i" in
a) add_server ;;
c) configure_ninjam ;;
d) delete_server ;;
h) help ;;
T)
echo "For Tony, because he's awesome!"
exit 0
;;
esac
done
declare -A servers=(
[Ninjamer 1]="ninjamer.com"
[Ninjamer 2]="ninjamer.com:2050"
[Ninjamer 3]="ninjamer.com:2051"
[Ninjamer 4]="ninjamer.com:2052"
)
if [[ -r "${config}/servers.conf" ]]; then
while IFS="=" read -r key value; do
if [[ "$key" =~ ^\[.*\]$ && "$value" =~ ^\".*\"$ ]]; then
key="${key#[}"
key="${key%]}"
value="${value#\"}"
value="${value%\"}"
servers["$key"]="$value"
else
echo "Error: invalid format in ${config}/servers.conf" >&2
exit 1
fi
done < <(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' "${config}/servers.conf")
fi
# Server menu
declare -a menuList
for i in "${!servers[@]}" ; do
menuList+=("${servers[$i]}" "${i}")
done
server="$(dialog --clear \
--backtitle "Tojam" \
--no-tags \
--extra-button \
--extra-label "Add Server" \
--ok-label "Connect" \
--cancel-label "Exit" \
--help-button \
--help-label "Settings" \
--menu "Select a Ninjam server" -1 -1 -1 "${menuList[@]}" --stdout)"
menuCode=$?
case ${menuCode} in
1|255) exit 0;;
2) configure_ninjam;;
3) add_server;;
esac
ninjam="$(command -v cninjam 2> /dev/null)"
[[ ${#ninjam} -le 3 ]] && { echo "Could not find cninjam."; exit 1; }
if [[ "${soundDriver}" == "jack" ]]; then
$ninjam "${server}" -user "${userName}" -jack -sessiondir "${sessiondir}" ${saveSourceFiles} $(save_files)
else
$ninjam "${server}" -user "${userName}" -alsaconfig "${alsaParameters}" -sessiondir "${sessiondir}" ${saveSourceFiles} $(save_files)
fi