349 lines
13 KiB
Bash
Executable File
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
|