forked from buttstuf/soapdish
Initial commit
This commit is contained in:
commit
44037c85a0
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
App: soapdish
|
||||||
|
Author: buttstuf@tilde.club
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(END)
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Playlist created date:
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Playlist tracks:
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# MAIN: CRON ACTIVATE
|
||||||
|
# Copy code to cront-show_gateway file
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# HEREDOC the script into a file named "cron-show_gateway"
|
||||||
|
cat <<-'EOF' > ${APPLICATION_ROOT}/var/main-cron_gateway
|
||||||
|
#!/bin/bash
|
||||||
|
${APPLICATION_ROOT}/scripts/main/main-stream_files
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Echo result
|
||||||
|
confirmation_message "[A] Activating main stream cron (CRON ON)"
|
||||||
|
echo "";
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SHOW: CRON DEACTIVATE
|
||||||
|
# Empty cron-show_gateway file
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Deactivate cron job by emptying contents of cron-gateway
|
||||||
|
sudo cat /dev/null > ${APPLICATION_ROOT}/var/main-cron_gateway
|
||||||
|
|
||||||
|
|
||||||
|
# Echo result
|
||||||
|
confirmation_message "[D] Deactivating main stream cron (CRON OFF)"
|
||||||
|
echo "";
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# MAIN: CRON STATUS
|
||||||
|
# Check if cron-main_gateway is empty
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if cron-gateway is NOT empty
|
||||||
|
if [ -s ${APPLICATION_ROOT}/var/main-cron_gateway ]
|
||||||
|
then
|
||||||
|
# Echo if cron-gateway is empty (cron job is active)
|
||||||
|
confirmation_message "[S] Cron main stream status: ON / ACTIVE";
|
||||||
|
echo "";
|
||||||
|
|
||||||
|
else
|
||||||
|
# Echo if cron-gateway is not empty (cron job is inactive!)
|
||||||
|
confirmation_message "[S] Cron main stream status: OFF / INACTIVE";
|
||||||
|
echo "";
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# MAIN: CREATE/UPDATE PLAYLIST
|
||||||
|
# Creates and/or updates a playlist to reflect what's in main-audio_queued folder
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# If playlist exists, delete it.
|
||||||
|
if test -f "$PLAYLIST_PATH"; then
|
||||||
|
sudo rm "$PLAYLIST_PATH";
|
||||||
|
fi
|
||||||
|
sudo touch "$PLAYLIST_PATH";
|
||||||
|
|
||||||
|
|
||||||
|
# Create array of directory files
|
||||||
|
declare -a FILES_ARRAY=()
|
||||||
|
for FILE in "$AUDIO_QUEUED_DIRECTORY"/*.mp3 ; do
|
||||||
|
FILES_ARRAY+=("$FILE")
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Check if array is empty, then construct accordingly
|
||||||
|
if (( ${#FILES_ARRAY[@]} )); then
|
||||||
|
|
||||||
|
# If files: Append header
|
||||||
|
CURRENT_DATE=$(date +"%D %T")
|
||||||
|
echo "# Playlist created date:" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "# $CURRENT_DATE" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "#" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
|
||||||
|
# Then append tracks
|
||||||
|
echo "# Playlist tracks:" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
for TRACK in "${FILES_ARRAY[@]}" ; do
|
||||||
|
echo "$TRACK" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# If no files: Append header
|
||||||
|
CURRENT_DATE=$(date +"%D %T")
|
||||||
|
echo "# Playlist date created:" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "# $CURRENT_DATE" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "#" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
|
||||||
|
# Then append empty tracklist
|
||||||
|
echo "# Playlist tracks:" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "# (((--- PLAYLIST EMPTY ---)))" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "#" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
echo "#" | sudo tee -a "$PLAYLIST_PATH" >/dev/null
|
||||||
|
error_message
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Set permissions after file creation
|
||||||
|
sudo chmod 755 "$PLAYLIST_PATH";
|
||||||
|
sudo chown "$APPLICATION_FILE_OWNER" "$PLAYLIST_PATH";
|
||||||
|
|
||||||
|
|
||||||
|
# Echo result
|
||||||
|
confirmation_message "[C] Playlist create: Playlist created."
|
||||||
|
echo ""
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SHOW: EDIT PLAYLIST
|
||||||
|
# Opens show playlist for editing in nano
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Check file exists, then reset permissions to ensure editing
|
||||||
|
if [[ -z $PLAYLIST_PATH ]]; then
|
||||||
|
sudo chmod 755 $PLAYLIST_PATH ;
|
||||||
|
sudo chown $PLAYLIST_PATH ;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Edit playlist
|
||||||
|
sudo nano $PLAYLIST_PATH;
|
||||||
|
|
||||||
|
|
||||||
|
# Confirm after editing
|
||||||
|
confirmation_message "[E] Main Stream Playlist Editing Completed"
|
||||||
|
echo "";
|
||||||
|
|
|
@ -0,0 +1,411 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# MAIN: PLAYLIST VIEW
|
||||||
|
# Displays Playlist, with details such as time and commented out tracks
|
||||||
|
|
||||||
|
|
||||||
|
# $PLAYLIST_PATH
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Arrays Declarations
|
||||||
|
MASTER_USABLE_FILE_CONTENTS_ARRAY=()
|
||||||
|
|
||||||
|
|
||||||
|
# FUNCTION: Sum Times
|
||||||
|
function sum_times {
|
||||||
|
|
||||||
|
|
||||||
|
# Receive parmeters
|
||||||
|
INBOUND_ARRAY_FOR_SUMMING=("$@")
|
||||||
|
|
||||||
|
# Get array length
|
||||||
|
INBOUND_ARRAY_FOR_SUMMING_LENGTH=${#INBOUND_ARRAY_FOR_SUMMING[@]}
|
||||||
|
|
||||||
|
|
||||||
|
# Sum - Centiseconds in array
|
||||||
|
|
||||||
|
for ((i=0; i<INBOUND_ARRAY_FOR_SUMMING_LENGTH; i++));
|
||||||
|
do
|
||||||
|
# ECHOVAR=$((i+1));
|
||||||
|
TIMECS=${INBOUND_ARRAY_FOR_SUMMING[${i}]};
|
||||||
|
TIMECS=${TIMECS:9};
|
||||||
|
if [[ ${TIMECS:0:1} == "0" ]] ; then TIMECS="${TIMECS:1}"; fi # If time has leading zero, remove to prevent token fault
|
||||||
|
# echo $TIMECS # Debug
|
||||||
|
TOTAL_ARRAY_TIME_CS=$((TOTAL_ARRAY_TIME_CS+TIMECS));
|
||||||
|
done
|
||||||
|
# echo "Total Time in MS: ${TOTAL_ARRAY_TIME_MS}" # DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
# Sum - Seconds only in array
|
||||||
|
|
||||||
|
for ((i=0; i<INBOUND_ARRAY_FOR_SUMMING_LENGTH; i++));
|
||||||
|
do
|
||||||
|
# ECHOVAR=$((i+1));
|
||||||
|
TIMES=${INBOUND_ARRAY_FOR_SUMMING[${i}]};
|
||||||
|
TIMES=${TIMES:6};
|
||||||
|
TIMES=${TIMES::-3};
|
||||||
|
if [[ ${TIMES:0:1} == "0" ]] ; then TIMES="${TIMES:1}"; fi # If time has leading zero, remove to prevent token fault
|
||||||
|
# echo $TIMES # Debug
|
||||||
|
TOTAL_ARRAY_TIME_S=$((TOTAL_ARRAY_TIME_S+TIMES));
|
||||||
|
done
|
||||||
|
# echo "Total Time in S: ${TOTAL_ARRAY_TIME_S}" # DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
# Sum - Minutes only in array
|
||||||
|
|
||||||
|
for ((i=0; i<INBOUND_ARRAY_FOR_SUMMING_LENGTH; i++));
|
||||||
|
do
|
||||||
|
# ECHOVAR=$((i+1));
|
||||||
|
TIMEM=${INBOUND_ARRAY_FOR_SUMMING[${i}]};
|
||||||
|
TIMEM=${TIMEM:3};
|
||||||
|
TIMEM=${TIMEM::-6};
|
||||||
|
if [[ ${TIMEM:0:1} == "0" ]] ; then TIMEM="${TIMEM:1}"; fi # If time has leading zero, remove to prevent token fault
|
||||||
|
# echo $TIMEM # Debug
|
||||||
|
TOTAL_ARRAY_TIME_M=$((TOTAL_ARRAY_TIME_M+TIMEM));
|
||||||
|
done
|
||||||
|
# echo "Total Time in M: ${TOTAL_ARRAY_TIME_M}" # DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
# Sum - Hours only in array
|
||||||
|
|
||||||
|
for ((i=0; i<INBOUND_ARRAY_FOR_SUMMING_LENGTH; i++));
|
||||||
|
do
|
||||||
|
# ECHOVAR=$((i+1));
|
||||||
|
TIMEH=${INBOUND_ARRAY_FOR_SUMMING[${i}]};
|
||||||
|
TIMEH=${TIMEH:0};
|
||||||
|
TIMEH=${TIMEH::-9};
|
||||||
|
if [[ ${TIMEH:0:1} == "0" ]] ; then TIMEH="${TIMEH:1}"; fi # If time has leading zero, remove to prevent token fault
|
||||||
|
# echo $TIMEH # Debug
|
||||||
|
TOTAL_ARRAY_TIME_H=$((TOTAL_ARRAY_TIME_H+TIMEH));
|
||||||
|
done
|
||||||
|
# echo "Total Time in H: ${TOTAL_ARRAY_TIME_H}" # DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
# Assign intermediary variables the totals for further processing
|
||||||
|
|
||||||
|
TEMPTOTAL_CS=${TOTAL_ARRAY_TIME_CS}
|
||||||
|
TEMPTOTAL_S=${TOTAL_ARRAY_TIME_S}
|
||||||
|
TEMPTOTAL_M=${TOTAL_ARRAY_TIME_M}
|
||||||
|
TEMPTOTAL_H=${TOTAL_ARRAY_TIME_H}
|
||||||
|
|
||||||
|
|
||||||
|
# Calculation of modolo values to assmenble friendly time:
|
||||||
|
|
||||||
|
# Milliseconds - modolo and carryover calculation
|
||||||
|
|
||||||
|
TT_CS_MOD=$((TEMPTOTAL_CS%100));
|
||||||
|
TT_CS_DIV=$((TEMPTOTAL_CS/100));
|
||||||
|
TT_CS_DIV=${TT_CS_DIV%.*} # Get rid of decimal
|
||||||
|
# echo "ms - "${TEMPTOTAL_MS} "(modolo of:" ${TT_CS_MOD}"), and div of: "${TT_CS_DIV}; #DEBUG
|
||||||
|
FRIENDLY_CS=${TT_CS_MOD};
|
||||||
|
TEMPTOTAL_S=$((TEMPTOTAL_S + TT_CS_DIV));
|
||||||
|
|
||||||
|
# Seconds - modolo and carryover calculation
|
||||||
|
|
||||||
|
TT_S_MOD=$((TEMPTOTAL_S%60));
|
||||||
|
TT_S_DIV=$((TEMPTOTAL_S/60));
|
||||||
|
TT_S_DIV=${TT_S_DIV%.*}; # Get rid of decimal
|
||||||
|
# echo "s - "${TEMPTOTAL_S} "(modolo of:" ${TT_S_MOD}"), and a div of: "${TT_S_DIV}; #DEBUG
|
||||||
|
FRIENDLY_S=${TT_S_MOD};
|
||||||
|
TEMPTOTAL_M=$((TEMPTOTAL_M + TT_S_DIV));
|
||||||
|
|
||||||
|
# Minutes - modolo and carryover calculation
|
||||||
|
|
||||||
|
TT_M_MOD=$((TEMPTOTAL_M%60));
|
||||||
|
TT_M_DIV=$((TEMPTOTAL_M/60));
|
||||||
|
TT_M_DIV=${TT_M_DIV%.*}; # Get rid of decimal
|
||||||
|
# echo "m - "${TEMPTOTAL_M} "(modolo of:" ${TT_M_MOD}"), and a div of: "${TT_M_DIV}; #DEBUG
|
||||||
|
FRIENDLY_M=${TT_M_MOD};
|
||||||
|
TEMPTOTAL_H=$((TEMPTOTAL_H + TT_M_DIV));
|
||||||
|
|
||||||
|
# Hours - modolo (no carryover, because days are not calculated)
|
||||||
|
|
||||||
|
TT_H_MOD=$((TEMPTOTAL_H%24));
|
||||||
|
TT_H_DIV=$((TEMPTOTAL_H/24));
|
||||||
|
TT_H_DIV=${TT_H_DIV%.*}; # Get rid of decimal
|
||||||
|
# echo "h - "${TEMPTOTAL_H} "(modolo of:" ${TT_H_MOD}"), and a div of: "${TT_H_DIV}; #DEBUG
|
||||||
|
FRIENDLY_H=${TEMPTOTAL_H};
|
||||||
|
|
||||||
|
|
||||||
|
# Display Friendly Time:
|
||||||
|
SUM_FUNCTION_RETURN="${FRIENDLY_H}h ${FRIENDLY_M}m ${FRIENDLY_S}.${FRIENDLY_CS}s"
|
||||||
|
echo "$SUM_FUNCTION_RETURN"
|
||||||
|
|
||||||
|
# Unset Variables
|
||||||
|
FRIENDLY_H=""
|
||||||
|
FRIENDLY_M=""
|
||||||
|
FRIENDLY_S=""
|
||||||
|
FRIENDLY_CS=""
|
||||||
|
TOTAL_ARRAY_TIME_MS=""
|
||||||
|
TOTAL_ARRAY_TIME_S=""
|
||||||
|
TOTAL_ARRAY_TIME_M=""
|
||||||
|
TOTAL_ARRAY_TIME_H=""
|
||||||
|
SUM_FUNCTION_RETURN=""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_ffprobe_time {
|
||||||
|
|
||||||
|
|
||||||
|
# Capture value pass
|
||||||
|
TIME_CHECK_INPUT=$1
|
||||||
|
|
||||||
|
# Use ffprobe and various text stream actions to pull time value
|
||||||
|
FF_OUTPUT=$(ffprobe "$TIME_CHECK_INPUT" 2>&1 | grep "Duration");
|
||||||
|
FF_OUTPUT=${FF_OUTPUT:12};
|
||||||
|
FF_OUTPUT=${FF_OUTPUT::-36};
|
||||||
|
|
||||||
|
# Return value
|
||||||
|
echo $FF_OUTPUT;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function calculate_playlist_time {
|
||||||
|
|
||||||
|
|
||||||
|
# Instsantiate Array
|
||||||
|
MASTER_USABLE_FILE_CONTENTS_ARRAY=()
|
||||||
|
|
||||||
|
# Read playlist file contents
|
||||||
|
while IFS= read -r PLAYLIST_FILE_LINE
|
||||||
|
do
|
||||||
|
|
||||||
|
# Remove leading spaces
|
||||||
|
PLAYLIST_LINE_NO_LEADING_SPACES=$(echo -e "${PLAYLIST_FILE_LINE}" | sed -e 's/^[[:space:]]*//')
|
||||||
|
|
||||||
|
# If file line is not empty and ends in .mp3
|
||||||
|
if [[ "$PLAYLIST_LINE_NO_LEADING_SPACES" != "" && $PLAYLIST_LINE_NO_LEADING_SPACES == *.mp3 ]]; then
|
||||||
|
|
||||||
|
|
||||||
|
# Add file to master file contents array, get length
|
||||||
|
MASTER_USABLE_FILE_CONTENTS_ARRAY+=("$PLAYLIST_LINE_NO_LEADING_SPACES")
|
||||||
|
|
||||||
|
# Master usable array length
|
||||||
|
MASTER_USABLE_ARRAY_LENGTH=${#MASTER_USABLE_FILE_CONTENTS_ARRAY[@]}
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done < "$PLAYLIST_PATH"
|
||||||
|
|
||||||
|
|
||||||
|
# Create arrays for both commented and non commented lines
|
||||||
|
ARRAY_OF_QUEUED_TIMES=()
|
||||||
|
ARRAY_OF_ALL_TIMES=()
|
||||||
|
|
||||||
|
for LINE_FOR_HASH_CHECK in "${MASTER_USABLE_FILE_CONTENTS_ARRAY[@]}"; do
|
||||||
|
|
||||||
|
|
||||||
|
# If first character beings with hash
|
||||||
|
if [[ ${LINE_FOR_HASH_CHECK:0:1} = "#" ]]; then
|
||||||
|
|
||||||
|
|
||||||
|
# Remove Hash
|
||||||
|
# LINE_FOR_HASH_CHECK=$(echo $LINE_FOR_HASH_CHECK | sed -e "s/\#//")
|
||||||
|
LINE_FOR_HASH_CHECK=$(echo -e "${LINE_FOR_HASH_CHECK}" | sed -e 's/^[#| ]*//')
|
||||||
|
LINE_FOR_HASH_CHECK=$(echo -e "${LINE_FOR_HASH_CHECK}" | sed -e 's/^[[:space:]]*//')
|
||||||
|
|
||||||
|
# Run get_ffprobe_time for value
|
||||||
|
FF_PROBE_RESULT=$(get_ffprobe_time "${LINE_FOR_HASH_CHECK}")
|
||||||
|
|
||||||
|
# Add to arrays (both, in this case)
|
||||||
|
ARRAY_OF_ALL_TIMES=( "${ARRAY_OF_ALL_TIMES[@]}" "$FF_PROBE_RESULT" )
|
||||||
|
|
||||||
|
|
||||||
|
# Else if line doesn't start with hash
|
||||||
|
else
|
||||||
|
|
||||||
|
|
||||||
|
# Run get_ffprobe_time for value
|
||||||
|
FF_PROBE_RESULT=$(get_ffprobe_time "${LINE_FOR_HASH_CHECK}")
|
||||||
|
|
||||||
|
# # Add to all array only
|
||||||
|
ARRAY_OF_QUEUED_TIMES=( "${ARRAY_OF_QUEUED_TIMES[@]}" "$FF_PROBE_RESULT" )
|
||||||
|
ARRAY_OF_ALL_TIMES=( "${ARRAY_OF_ALL_TIMES[@]}" "$FF_PROBE_RESULT" )
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Render Results
|
||||||
|
printf "${COLOR_GREEN}[V] Playlist view:${COLOR_DEFAULT}\n";
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " ${FONT_BOLD}PLAYLIST FILES (HH:MM:SS.MS)${FONT_DEFAULT}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Numbmering Indexes (the printable ones)
|
||||||
|
FRIENDLY_INDEX=1;
|
||||||
|
COMPLETE_INDEX=1;
|
||||||
|
|
||||||
|
# Create Array
|
||||||
|
ARRAY_OF_QUEUED_TRACKS=()
|
||||||
|
|
||||||
|
for (( i = 0; i < $MASTER_USABLE_ARRAY_LENGTH; i++ )); do
|
||||||
|
|
||||||
|
|
||||||
|
# Prepare Filename to Echo
|
||||||
|
FILENAME_TO_ECHO=${MASTER_USABLE_FILE_CONTENTS_ARRAY[$i]}
|
||||||
|
FILENAME_TO_ECHO=$(sed -e s/"^.*queued\/"// <<< ${FILENAME_TO_ECHO})
|
||||||
|
|
||||||
|
# check if line begins with #
|
||||||
|
if [[ ${MASTER_USABLE_FILE_CONTENTS_ARRAY[$i]:0:1} == "#" ]]; then
|
||||||
|
|
||||||
|
if [[ ${MASTER_USABLE_FILE_CONTENTS_ARRAY[$i]:0:1} == "#" ]]; then
|
||||||
|
|
||||||
|
# Prepare "printable complete index"
|
||||||
|
if [[ ${#COMPLETE_INDEX} = 1 ]]; then
|
||||||
|
printf " ${COLOR_GRAY}[0$COMPLETE_INDEX] ${ARRAY_OF_ALL_TIMES[$i]} – # ${FILENAME_TO_ECHO}${COLOR_DEFAULT}\n"
|
||||||
|
else
|
||||||
|
printf " ${COLOR_GRAY}[$COMPLETE_INDEX] ${ARRAY_OF_ALL_TIMES[$i]} – # ${FILENAME_TO_ECHO}${COLOR_DEFAULT}\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Else if line doesn't start with #
|
||||||
|
else
|
||||||
|
|
||||||
|
# If does not start with #
|
||||||
|
if [[ ${#FRIENDLY_INDEX} = 1 ]]; then
|
||||||
|
printf " 0$FRIENDLY_INDEX"
|
||||||
|
else
|
||||||
|
printf " $FRIENDLY_INDEX"
|
||||||
|
fi
|
||||||
|
FRIENDLY_INDEX=$((FRIENDLY_INDEX+1))
|
||||||
|
|
||||||
|
# Prepare "printable complete index" (later gets indexed outside loop)
|
||||||
|
if [[ ${#COMPLETE_INDEX} = 1 ]]; then
|
||||||
|
printf " $SYMBOL_RAQUO [0$COMPLETE_INDEX] "
|
||||||
|
else
|
||||||
|
printf " $SYMBOL_RAQUO [$COMPLETE_INDEX] "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Echo Time
|
||||||
|
echo -e " ${ARRAY_OF_ALL_TIMES[$i]} – ${FILENAME_TO_ECHO}"
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Index "complete index"
|
||||||
|
COMPLETE_INDEX=$((COMPLETE_INDEX+1))
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Deincrement friendly index, because increment happens in loop after it's printed
|
||||||
|
FRIENDLY_INDEX=$(("$FRIENDLY_INDEX-1")) # Get final count of queued times
|
||||||
|
FINAL_COUNT_OF_QUEUED_ITEMS=${#ARRAY_OF_QUEUED_TIMES[@]}
|
||||||
|
|
||||||
|
# Unsetariables and get sum of time arrays (for all files and queued files)
|
||||||
|
SUM_OF_QUEUED_TIMES=""
|
||||||
|
# SUM_OF_NT_OF_ALL_ITEMS=${#ARRAY_OF_ALL_TIMES[@]}ALL_TIMES=""
|
||||||
|
SUM_OF_QUEUED_TIMES=$(sum_times "${ARRAY_OF_QUEUED_TIMES[@]}")
|
||||||
|
SUM_OF_ALL_TIMES=$(sum_times "${ARRAY_OF_ALL_TIMES[@]}")
|
||||||
|
|
||||||
|
# Echo Output
|
||||||
|
echo -e ""
|
||||||
|
echo -e " ${FONT_BOLD}Total (${FINAL_COUNT_OF_QUEUED_ITEMS}/${MASTER_USABLE_ARRAY_LENGTH} tracks): $SUM_OF_QUEUED_TIMES / $SUM_OF_ALL_TIMES${FONT_DEFAULT}\n"
|
||||||
|
echo -e ""
|
||||||
|
echo -e ""
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_playlist_integrity() {
|
||||||
|
|
||||||
|
|
||||||
|
# Clear Array
|
||||||
|
INTEGRITY_CHECK_FILE_LINES_ARRAY=()
|
||||||
|
|
||||||
|
# Declare integrity check flag
|
||||||
|
INTEGRITY_CHECK_FLAG="true"
|
||||||
|
|
||||||
|
# Read playlist file contents
|
||||||
|
while IFS= read -r PLAYLIST_FILE_LINE
|
||||||
|
do
|
||||||
|
|
||||||
|
# Remove leading spaces
|
||||||
|
PLAYLIST_LINE_WITH_NO_LEADING_SPACES=$(echo -e "${PLAYLIST_FILE_LINE}" | sed -e 's/^[[:space:]]*//')
|
||||||
|
|
||||||
|
# If line isn't blank
|
||||||
|
if [[ -n $PLAYLIST_LINE_WITH_NO_LEADING_SPACES ]];
|
||||||
|
then
|
||||||
|
|
||||||
|
# If ends in .mp3
|
||||||
|
if [[ "$PLAYLIST_LINE_WITH_NO_LEADING_SPACES" == *.mp3 ]]; then
|
||||||
|
|
||||||
|
# remove pound
|
||||||
|
PLAYLIST_LINE_WITH_NO_LEADING_POUND=$(echo -e "${PLAYLIST_LINE_WITH_NO_LEADING_SPACES}" | sed -e 's/^[#| ]*//')
|
||||||
|
|
||||||
|
# Add file to master file contents array, get length
|
||||||
|
INTEGRITY_CHECK_FILE_LINES_ARRAY+=("$PLAYLIST_LINE_WITH_NO_LEADING_POUND")
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If line is blank (then don't add to array / continue)
|
||||||
|
else
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done < "$PLAYLIST_PATH"
|
||||||
|
|
||||||
|
# Check that a file exists for each playlist line
|
||||||
|
for INTEGRITY_CHECK_ITEM in "${INTEGRITY_CHECK_FILE_LINES_ARRAY[@]}"
|
||||||
|
do
|
||||||
|
|
||||||
|
# If doesn't exist then throw notice
|
||||||
|
if [[ ! -f "$INTEGRITY_CHECK_ITEM" ]];
|
||||||
|
|
||||||
|
then
|
||||||
|
|
||||||
|
# Flag as failed
|
||||||
|
INTEGRITY_CHECK_FLAG="false"
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
echo $INTEGRITY_CHECK_FLAG
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# If playlist file exists, then do routine
|
||||||
|
if test -f "$PLAYLIST_PATH";
|
||||||
|
|
||||||
|
# Execute calcualte_playlist_time
|
||||||
|
then
|
||||||
|
|
||||||
|
MASTER_PLAYLIST_INTEGRITY_CHECK=$(verify_playlist_integrity)
|
||||||
|
if [[ "$MASTER_PLAYLIST_INTEGRITY_CHECK" == "true" ]];
|
||||||
|
|
||||||
|
# If playlist integrity check passed
|
||||||
|
then
|
||||||
|
echo "Calculating playlist time..."
|
||||||
|
calculate_playlist_time
|
||||||
|
|
||||||
|
# else error
|
||||||
|
else
|
||||||
|
error_message "[V] View playlist: playlist contains invalid refs. Please edit or recreate for summary."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# else if playlist file doesn't exist
|
||||||
|
else
|
||||||
|
error_message "[V] View playlist: playlist file not found. Run \"C\" to create.";
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SHOW: CREATE/UPDATE PLAYLIST
|
||||||
|
# Creates and/or updates a playlist to reflect what's in openmic-audio_queued folder
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "$APPLICATION_ROOT/scripts/system/system-functions"
|
||||||
|
source "$APPLICATION_ROOT/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if directory is empty
|
||||||
|
if [[ $(ls "$AUDIO_QUEUED_DIRECTORY") ]]; then
|
||||||
|
|
||||||
|
# If not empty, render list
|
||||||
|
echo -e "${COLOR_GREEN}[Q] \"audio_queued\" folder contents (${i} items):${COLOR_DEFAULT}"
|
||||||
|
echo -e ""
|
||||||
|
echo -e ""
|
||||||
|
echo -e " ${FONT_BOLD}SHOW QUEUED FOLDER CONTENTS${FONT_DEFAULT}"
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
# Cycle through openmic audio queued directory, and print each line (just filename)
|
||||||
|
i=1
|
||||||
|
for FILE in "$AUDIO_QUEUED_DIRECTORY"/*; do
|
||||||
|
|
||||||
|
|
||||||
|
# Check i's length. If less than 10, add zero to front
|
||||||
|
STRLENGTH=${#i}
|
||||||
|
if [[ $STRLENGTH == 1 ]]; then
|
||||||
|
LEADING_ZERO_INSERTION="0"
|
||||||
|
else
|
||||||
|
LEADING_ZERO_INSERTION=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Render line (FILE printout) with number in front
|
||||||
|
JUST_FILENAME=$(echo "$FILE" | sed "s/.*\///")
|
||||||
|
echo -e " $LEADING_ZERO_INSERTION$i: \"$JUST_FILENAME\""
|
||||||
|
|
||||||
|
# Increment i
|
||||||
|
i=$((i+1));
|
||||||
|
|
||||||
|
done
|
||||||
|
FILE_COUNT=$((i-1))
|
||||||
|
echo -e "";
|
||||||
|
echo -e " ${FONT_BOLD}[${FILE_COUNT} Files Found]${FONT_DEFAULT}\n"
|
||||||
|
echo -e "";
|
||||||
|
echo -e "";
|
||||||
|
echo -e "";
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# If directory is empty
|
||||||
|
error_message "[Q] The \"audio_queued\" directory is empty. Add audio files.";
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SHOW: STREAM FILES
|
||||||
|
# Streams files as indexed in show-playlist.m3u (which is based on show-audio_queud)
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Get active config name, construct path to streamable config file (for validation)
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_NAME=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
STREAMABLE_CONFIG_FILE_PATH="$CONFIG_DIRECTORY/config-$CURRENTLY_ACTIVE_CONFIG_NAME.json"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if config file exists
|
||||||
|
if [[ -f "$STREAMABLE_CONFIG_FILE_PATH" ]];
|
||||||
|
|
||||||
|
# If exists
|
||||||
|
then
|
||||||
|
|
||||||
|
# Parse JSON config file for each variable
|
||||||
|
v1='main_host'
|
||||||
|
MAIN_HOST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v1//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v2='main_port'
|
||||||
|
MAIN_PORT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v2//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v3='main_user'
|
||||||
|
MAIN_USER=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v3//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v4='main_password'
|
||||||
|
MAIN_PASSWORD=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v4//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v5='main_mount'
|
||||||
|
MAIN_MOUNT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v5//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v6='playlist_url'
|
||||||
|
PLAYLIST_URL=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v6//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v7='randomize_playlist_files'
|
||||||
|
RANDOMIZE_PLAYLIST_FILES=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v7//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v8='hardware_audio_frame_size'
|
||||||
|
HARDWARE_AUDIO_FRAME_SIZE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v8//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure all configuration files are not blank
|
||||||
|
if [ -z "${MAIN_HOST}" ] || [ -z "${MAIN_PORT}" ] || [ -z "${MAIN_USER}" ] || [ -z "${MAIN_PASSWORD}" ] || [ -z "${MAIN_MOUNT}" ] || [ -z "${PLAYLIST_URL}" ] || [ -z "${RANDOMIZE_PLAYLIST_FILES}" ] || [ -z "${HARDWARE_AUDIO_FRAME_SIZE}" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
# Fault if config variable is blank
|
||||||
|
printf "${COLOR_RED}[F] Stream Files (to Main): Streaming failed. Check your playlist, files, and/or settings.${COLOR_DEFAULT}\n\n";
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf "${COLOR_GREEN}[F] Stream Files (to Main):${COLOR_DEFAULT}\n";
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[STARTING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
printf "${COLOR_MAGENTA}"
|
||||||
|
|
||||||
|
# Launch Liquidsoap using variables
|
||||||
|
# liquidsoap 'set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE'); output.icecast(%mp3,host="'$MAIN_HOST'",port='$MAIN_PORT',user="'$MAIN_USER'",password="'$MAIN_PASSWORD'",mount="'$MAIN_MOUNT'",mksafe(playlist.once(random='$MAIN_RANDOMIZE_PLAYLIST_FILES',on_done=shutdown,"'$PLAYLIST_URL'")))';
|
||||||
|
liquidsoap '
|
||||||
|
set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE');
|
||||||
|
|
||||||
|
stream_master_source = output.icecast(
|
||||||
|
%mp3,
|
||||||
|
host="'$MAIN_HOST'",
|
||||||
|
port='$MAIN_PORT',
|
||||||
|
user="'$MAIN_USER'",
|
||||||
|
password="'$MAIN_PASSWORD'",
|
||||||
|
mount="'$MAIN_MOUNT'",
|
||||||
|
fallible=true,
|
||||||
|
on_stop=shutdown,
|
||||||
|
playlist.once(
|
||||||
|
random='$RANDOMIZE_PLAYLIST_FILES',
|
||||||
|
"'$PLAYLIST_URL'"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
stream_master_source
|
||||||
|
'
|
||||||
|
|
||||||
|
printf ${COLOR_DEFAULT}
|
||||||
|
printf "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[EXITING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no config file exists
|
||||||
|
else
|
||||||
|
error_message "[F] Stream Files (to Main): No config file specified. To stream, please assign a config."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SHOW: STREAM LIVE
|
||||||
|
# Streams show live from input/ALSA
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Get active config name, construct path to streamable config file (for validation)
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_NAME=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
STREAMABLE_CONFIG_FILE_PATH="$CONFIG_DIRECTORY/config-$CURRENTLY_ACTIVE_CONFIG_NAME.json"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if config file exists
|
||||||
|
if [[ -f "$STREAMABLE_CONFIG_FILE_PATH" ]];
|
||||||
|
|
||||||
|
# If exists
|
||||||
|
then
|
||||||
|
|
||||||
|
# Parse JSON config file for each crucial streaming variable
|
||||||
|
v1='main_host'
|
||||||
|
MAIN_HOST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v1//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v2='main_port'
|
||||||
|
MAIN_PORT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v2//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v3='main_user'
|
||||||
|
MAIN_USER=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v3//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v4='main_password'
|
||||||
|
MAIN_PASSWORD=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v4//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v5='main_mount'
|
||||||
|
MAIN_MOUNT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v5//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v6='playlist_url'
|
||||||
|
PLAYLIST_URL=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v6//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v7='randomize_playlist_files'
|
||||||
|
RANDOMIZE_PLAYLIST_FILES=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v7//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v8='hardware_audio_frame_size'
|
||||||
|
HARDWARE_AUDIO_FRAME_SIZE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v8//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
|
||||||
|
# Parse JSON config file for each metadata streaming variable
|
||||||
|
v9='main_metadata_artist'
|
||||||
|
MAIN_METADATA_ARTIST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v9//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
# MAIN_METADATA_ARTIST="${MAIN_METADATA_ARTIST// /\+}"
|
||||||
|
vA='main_metadata_title'
|
||||||
|
MAIN_METADATA_TITLE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$vA//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
# MAIN_METADATA_TITLE="${MAIN_METADATA_TITLE// /\+}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure all configuration files are not blank
|
||||||
|
if [ -z "${MAIN_HOST}" ] || [ -z "${MAIN_PORT}" ] || [ -z "${MAIN_USER}" ] || [ -z "${MAIN_PASSWORD}" ] || [ -z "${MAIN_MOUNT}" ] || [ -z "${PLAYLIST_URL}" ] || [ -z "${RANDOMIZE_PLAYLIST_FILES}" ] || [ -z "${HARDWARE_AUDIO_FRAME_SIZE}" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
# Fault if config variable is blank
|
||||||
|
error_message "[L] Stream ALSA (to Main): Streaming failed. Please check your configuration settings.";
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Notice of Execution
|
||||||
|
confirmation_message "${COLOR_GREEN}[L] Stream ALSA (to Main):${COLOR_DEFAULT}";
|
||||||
|
|
||||||
|
|
||||||
|
# Encode and Submit Metadata Change (Hack: two requests to get changes to take)
|
||||||
|
CONVERTED_MAIN_METADATA_TITLE=$(url_encode_string "$MAIN_METADATA_TITLE")
|
||||||
|
CONVERTED_MAIN_METADATA_ARTIST=$(url_encode_string "$MAIN_METADATA_ARTIST")
|
||||||
|
curl "http://$MAIN_USER:$MAIN_PASSWORD@$MAIN_HOST:$MAIN_PORT/admin/metadata?mode=updinfo&mount=/&title='$CONVERTED_MAIN_METADATA_TITLE'&artist='$CONVERTED_MAIN_METADATA_ARTIST'"
|
||||||
|
sleep 5
|
||||||
|
curl "http://$MAIN_USER:$MAIN_PASSWORD@$MAIN_HOST:$MAIN_PORT/admin/metadata?mode=updinfo&mount=/&title='$CONVERTED_MAIN_METADATA_TITLE'&artist='$CONVERTED_MAIN_METADATA_ARTIST'"
|
||||||
|
|
||||||
|
|
||||||
|
# Liquidsoap Log
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[STARTING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
echo -e "${COLOR_MAGENTA}"
|
||||||
|
|
||||||
|
|
||||||
|
# Launch Liquidsoap using variables
|
||||||
|
# liquidsoap 'set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE'); output.icecast(%mp3,host="'$MAIN_HOST'",port='$MAIN_PORT',user="'$MAIN_USER'",password="'$MAIN_PASSWORD'",mount="'$MAIN_MOUNT'",mksafe(playlist.once(random='$MAIN_RANDOMIZE_PLAYLIST_FILES',on_done=shutdown,"'$PLAYLIST_URL'")))';
|
||||||
|
liquidsoap '
|
||||||
|
set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE');
|
||||||
|
|
||||||
|
stream_master_source = output.icecast(
|
||||||
|
%mp3(bitrate=192,samplerate=44100),
|
||||||
|
host="'$MAIN_HOST'",
|
||||||
|
port='$MAIN_PORT',
|
||||||
|
user="'$MAIN_USER'",
|
||||||
|
password="'$MAIN_PASSWORD'",
|
||||||
|
mount="'$MAIN_MOUNT'",
|
||||||
|
input.alsa(bufferize = true)
|
||||||
|
)
|
||||||
|
|
||||||
|
stream_master_source
|
||||||
|
'
|
||||||
|
|
||||||
|
printf ${COLOR_DEFAULT}
|
||||||
|
printf "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[EXITING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# If no config file exists
|
||||||
|
else
|
||||||
|
error_message "[L] Stream ALSA (to Main): No config file specified. To stream, please assign a config."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# TESTING: STREAM FILES
|
||||||
|
# Streams files as indexed in openmic-playlist.m3u (which is based on openmic-audio_queud)
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Get active config name, construct path to streamable config file (for validation)
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_NAME=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
STREAMABLE_CONFIG_FILE_PATH="$CONFIG_DIRECTORY/config-$CURRENTLY_ACTIVE_CONFIG_NAME.json"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if config file exists
|
||||||
|
if [[ -f "$STREAMABLE_CONFIG_FILE_PATH" ]];
|
||||||
|
|
||||||
|
# If exists
|
||||||
|
then
|
||||||
|
|
||||||
|
# Parse JSON config file for each variable
|
||||||
|
v1='testing_host'
|
||||||
|
TESTING_HOST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v1//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v2='testing_port'
|
||||||
|
TESTING_PORT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v2//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v3='testing_user'
|
||||||
|
TESTING_USER=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v3//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v4='testing_password'
|
||||||
|
TESTING_PASSWORD=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v4//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v5='testing_mount'
|
||||||
|
TESTING_MOUNT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v5//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v6='playlist_url'
|
||||||
|
PLAYLIST_URL=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v6//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v7='randomize_playlist_files'
|
||||||
|
RANDOMIZE_PLAYLIST_FILES=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v7//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
v8='hardware_audio_frame_size'
|
||||||
|
HARDWARE_AUDIO_FRAME_SIZE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v8//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure all configuration files are not blank
|
||||||
|
if [ -z "${TESTING_HOST}" ] || [ -z "${TESTING_PORT}" ] || [ -z "${TESTING_USER}" ] || [ -z "${TESTING_PASSWORD}" ] || [ -z "${TESTING_MOUNT}" ] || [ -z "${PLAYLIST_URL}" ] || [ -z "${RANDOMIZE_PLAYLIST_FILES}" ] || [ -z "${HARDWARE_AUDIO_FRAME_SIZE}" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
# Fault if config variable is blank
|
||||||
|
error_message "[f] Stream Files (to Testing): Streaming failed. Check your playlist, files, and/or settings.${COLOR_DEFAULT}";
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
confirmation_message "[f] Stream Files (to Testing):";
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo -e "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[STARTING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
echo -e "${COLOR_MAGENTA}"
|
||||||
|
|
||||||
|
|
||||||
|
# Launch Liquidsoap using variables
|
||||||
|
# liquidsoap 'set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE'); output.icecast(%mp3,host="'$TESTING_HOST'",port='$TESTING_PORT',user="'$TESTING_USER'",password="'$TESTING_PASSWORD'",mount="'$TESTING_MOUNT'",mksafe(playlist.once(random='$RANDOMIZE_PLAYLIST_FILES',on_done=shutdown,"'$PLAYLIST_URL'")))';
|
||||||
|
liquidsoap '
|
||||||
|
set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE');
|
||||||
|
|
||||||
|
stream_master_source = output.icecast(
|
||||||
|
%mp3,
|
||||||
|
host="'$TESTING_HOST'",
|
||||||
|
port='$TESTING_PORT',
|
||||||
|
user="'$TESTING_USER'",
|
||||||
|
password="'$TESTING_PASSWORD'",
|
||||||
|
mount="'$TESTING_MOUNT'",
|
||||||
|
fallible=true,
|
||||||
|
on_stop=shutdown,
|
||||||
|
playlist.once(
|
||||||
|
random='$RANDOMIZE_PLAYLIST_FILES',
|
||||||
|
"'$PLAYLIST_URL'"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
stream_master_source
|
||||||
|
'
|
||||||
|
|
||||||
|
echo -e ${COLOR_DEFAULT}
|
||||||
|
echo -e "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[EXITING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "\n"
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# If no config file exists
|
||||||
|
else
|
||||||
|
error_message "[f] Stream Files (to Testing): No config file specified. To stream, please assign a config."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# OPENMIC: STREAM LIVE
|
||||||
|
# Streams openmic live from input/ALSA
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Get active config name, construct path to streamable config file (for validation)
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_NAME=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
STREAMABLE_CONFIG_FILE_PATH="$CONFIG_DIRECTORY/config-$CURRENTLY_ACTIVE_CONFIG_NAME.json"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if config file exists
|
||||||
|
if [[ -f "$CURRENTLY_ACTIVE_CONFIG_NAME" ]];
|
||||||
|
|
||||||
|
# If exists
|
||||||
|
then
|
||||||
|
|
||||||
|
# Parse JSON config file for each crucial streaming variable
|
||||||
|
v1='testing_host'
|
||||||
|
TESTING_HOST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v1//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v2='testing_port'
|
||||||
|
TESTING_PORT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v2//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v3='testing_user'
|
||||||
|
TESTING_USER=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v3//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v4='testing_password'
|
||||||
|
TESTING_PASSWORD=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v4//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v5='testing_mount'
|
||||||
|
TESTING_MOUNT=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v5//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v6='playlist_url'
|
||||||
|
PLAYLIST_URL=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v6//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v7='randomize_playlist_files'
|
||||||
|
RANDOMIZE_PLAYLIST_FILES=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v7//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
v8='hardware_audio_frame_size'
|
||||||
|
HARDWARE_AUDIO_FRAME_SIZE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v8//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
|
||||||
|
# Parse JSON config file for each metadata streaming variable
|
||||||
|
v9='testing_metadata_artist'
|
||||||
|
TESTING_METADATA_ARTIST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$v9//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
# TESTING_METADATA_ARTIST="${TESTING_METADATA_ARTIST// /\+}"
|
||||||
|
vA='testing_metadata_title'
|
||||||
|
TESTING_METADATA_TITLE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$vA//p" $CURRENTLY_ACTIVE_CONFIG_NAME))
|
||||||
|
# TESTING_METADATA_TITLE="${TESTING_METADATA_TITLE// /\+}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure all configuration files are not blank
|
||||||
|
if [ -z "${TESTING_HOST}" ] || [ -z "${TESTING_PORT}" ] || [ -z "${TESTING_USER}" ] || [ -z "${TESTING_PASSWORD}" ] || [ -z "${TESTING_MOUNT}" ] || [ -z "${PLAYLIST_URL}" ] || [ -z "${RANDOMIZE_PLAYLIST_FILES}" ] || [ -z "${HARDWARE_AUDIO_FRAME_SIZE}" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
# Fault if config variable is blank
|
||||||
|
error_message "[l] Stream ALSA (to Testing): Streaming failed. Please check your configuration settings."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Notice of Execution
|
||||||
|
confirmation_message "${COLOR_GREEN}[l] Stream ALSA (to Testing):${COLOR_DEFAULT}";
|
||||||
|
|
||||||
|
|
||||||
|
# Encode and Submit Metadata Change (Hack: two requests to get changes to take)
|
||||||
|
CONVERTED_TESTING_METADATA_TITLE=$(url_encode_string "$TESTING_METADATA_TITLE")
|
||||||
|
CONVERTED_TESTING_METADATA_ARTIST=$(url_encode_string "$TESTING_METADATA_ARTIST")
|
||||||
|
curl "http://$TESTING_USER:$TESTING_PASSWORD@$TESTING_HOST:$TESTING_PORT/admin/metadata?mode=updinfo&mount=/&title='$CONVERTED_TESTING_METADATA_TITLE'&artist='$CONVERTED_TESTING_METADATA_ARTIST'"
|
||||||
|
sleep 5
|
||||||
|
curl "http://$TESTING_USER:$TESTING_PASSWORD@$TESTING_HOST:$TESTING_PORT/admin/metadata?mode=updinfo&mount=/&title='$CONVERTED_TESTING_METADATA_TITLE'&artist='$CONVERTED_TESTING_METADATA_ARTIST'"
|
||||||
|
|
||||||
|
|
||||||
|
# Liquidsoap Log
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[STARTING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
echo -e "${COLOR_MAGENTA}"
|
||||||
|
|
||||||
|
|
||||||
|
# Launch Liquidsoap using variables
|
||||||
|
# liquidsoap 'set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE'); output.icecast(%mp3,host="'$TESTING_HOST'",port='$TESTING_PORT',user="'$TESTING_USER'",password="'$TESTING_PASSWORD'",mount="'$TESTING_MOUNT'",mksafe(playlist.once(random='$RANDOMIZE_PLAYLIST_FILES',on_done=shutdown,"'$PLAYLIST_URL'")))';
|
||||||
|
liquidsoap '
|
||||||
|
set("frame.audio.size",'$HARDWARE_AUDIO_FRAME_SIZE');
|
||||||
|
|
||||||
|
stream_master_source = output.icecast(
|
||||||
|
%mp3(bitrate=192,samplerate=44100),
|
||||||
|
host="'$TESTING_HOST'",
|
||||||
|
port='$TESTING_PORT',
|
||||||
|
user="'$TESTING_USER'",
|
||||||
|
password="'$TESTING_PASSWORD'",
|
||||||
|
mount="'$TESTING_MOUNT'",
|
||||||
|
input.alsa(bufferize = true)
|
||||||
|
)
|
||||||
|
|
||||||
|
stream_master_source
|
||||||
|
'
|
||||||
|
|
||||||
|
echo -e ${COLOR_DEFAULT}
|
||||||
|
echo -e "${COLOR_LIGHT_MAGENTA}${FONT_BOLD}[EXITING LIQUIDSOAP]${FONT_DEFAULT}${COLOR_DEFAULT}\n"
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "\n"
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no config file exists
|
||||||
|
else
|
||||||
|
error_message "[l] Stream ALSA (to Testing): No config file specified. To stream, please assign a config."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: ALSA MIXER
|
||||||
|
# Launch alsamixer
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# If playlist exists, delete it.
|
||||||
|
sudo alsamixer
|
||||||
|
|
||||||
|
|
||||||
|
# Echo result
|
||||||
|
confirmation_message "[M] ALSA mixer visitation completed"
|
||||||
|
echo "";
|
||||||
|
|
|
@ -0,0 +1,356 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Options
|
||||||
|
# Edit System Configuration (.json) file
|
||||||
|
|
||||||
|
# COPY HAS VALIDATION BUGS
|
||||||
|
# RENAME IS NOT YET DONE
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Refresh Config File Reference Array
|
||||||
|
# Creates two new arrays in parallel of availalble configurations
|
||||||
|
# Array 1 - $CONFIG_PROFILES_ARRAY : list of profile names
|
||||||
|
# Array 2 - $CONFIG_PROFILES_PATHS_ARRAY : list of profile paths
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function refresh_config_file_reference_array () {
|
||||||
|
|
||||||
|
|
||||||
|
# Empty Arrays
|
||||||
|
unset CONFIG_PROFILES_ARRAY
|
||||||
|
unset CONFIG_PROFILES_PATHS_ARRAY
|
||||||
|
|
||||||
|
|
||||||
|
# If Config Directory is empty
|
||||||
|
if [ -z "$(ls -A $CONFIG_DIRECTORY)" ]; then
|
||||||
|
|
||||||
|
echo - "Config directory is currently empty. Please create a new config file using option 'n'."
|
||||||
|
|
||||||
|
|
||||||
|
# Else if Config Directory is not empty
|
||||||
|
else
|
||||||
|
|
||||||
|
|
||||||
|
# Instantiate counter, then read directory (declared in file 'system-declarations')
|
||||||
|
for CONFIG_DIRECTORY_ITEM in "$CONFIG_DIRECTORY"/*; do
|
||||||
|
|
||||||
|
# If file is of type json, proceed
|
||||||
|
if [[ $CONFIG_DIRECTORY_ITEM == *.json ]]; then
|
||||||
|
|
||||||
|
# if file is of pitfall condition, rename with timestamp
|
||||||
|
CONFIG_NAME=$(echo "${CONFIG_DIRECTORY_ITEM}" | sed "s|$CONFIG_DIRECTORY/||")
|
||||||
|
if [[ $CONFIG_NAME == "config-.json" ]] || [[ $CONFIG_NAME == "config.json" ]]; then
|
||||||
|
|
||||||
|
# Create hex value of 6 length, and rename violating files
|
||||||
|
RANDOM_HEX_VALUE=$( generate_random_hex_value 6 )
|
||||||
|
CONFIG_NAME_RENAMED="config-${RANDOM_HEX_VALUE}.json"
|
||||||
|
mv "$CONFIG_DIRECTORY/$CONFIG_NAME" "$CONFIG_DIRECTORY/$CONFIG_NAME_RENAMED"
|
||||||
|
|
||||||
|
# Declare chaneges for main name and directory variable (then alert)
|
||||||
|
CONFIG_DIRECTORY_ITEM="$CONFIG_DIRECTORY/$CONFIG_NAME_RENAMED"
|
||||||
|
warning_message "[Alert] Unnamed config \"$CONFIG_NAME\" renamed \"$CONFIG_NAME_RENAMED\" "
|
||||||
|
CONFIG_NAME="$CONFIG_NAME_RENAMED"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Full File Path, and sed a Display Name (ennumerated)
|
||||||
|
CONFIG_NAME_TRUNCATED=$(echo "${CONFIG_NAME}" | sed "s|config-||" | sed "s/.json//")
|
||||||
|
|
||||||
|
# Apply to master arrays
|
||||||
|
CONFIG_PROFILES_ARRAY+=("$CONFIG_NAME_TRUNCATED")
|
||||||
|
CONFIG_PROFILES_PATHS_ARRAY+=("$CONFIG_DIRECTORY_ITEM")
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# # Debug:
|
||||||
|
# echo "CONFIG PROFILES ARRAY: ${CONFIG_PROFILES_ARRAY[*]}"
|
||||||
|
# echo "CONFIG PROFILES PATHS ARRAY: ${CONFIG_PROFILES_PATHS_ARRAY[*]}"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: List existing config files
|
||||||
|
# Echos a list of available profile names (called in render_config_menu)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function list_existing_config_files {
|
||||||
|
|
||||||
|
# Get active file name
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_FILE=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
|
||||||
|
# List menu section heading
|
||||||
|
echo -e " ${COLOR_WHITE}${FONT_BOLD}CONFIG PROFILES & META:${FONT_DEFAULT}${COLOR_DEFAULT}";
|
||||||
|
|
||||||
|
|
||||||
|
if (( ${#CONFIG_PROFILES_ARRAY[@]} )); then
|
||||||
|
|
||||||
|
# If config array does exist
|
||||||
|
PROFILE_COUNTER=0
|
||||||
|
for i in ${CONFIG_PROFILES_ARRAY[*]}
|
||||||
|
|
||||||
|
|
||||||
|
do :
|
||||||
|
|
||||||
|
# Check if active profile name is current 'for' item
|
||||||
|
if [[ $i == "$CURRENTLY_ACTIVE_CONFIG_FILE" ]]; then
|
||||||
|
|
||||||
|
# Render profile name
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}${SYMBOL_RAQUO}${COLOR_DEFAULT}${FONT_DEFAULT} $i ${COLOR_CYAN}(using)${COLOR_DEFAULT}"
|
||||||
|
|
||||||
|
# Render profile metadata
|
||||||
|
JSON_FIELD_NAME_META_ARTIST='main_metadata_artist'
|
||||||
|
MAIN_METADATA_ARTIST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$JSON_FIELD_NAME_META_ARTIST//p" ${CONFIG_PROFILES_PATHS_ARRAY[$PROFILE_COUNTER]}))
|
||||||
|
# MAIN_METADATA_ARTIST="${MAIN_METADATA_ARTIST// /\+}"
|
||||||
|
echo -e " Artist: \"$MAIN_METADATA_ARTIST\"";
|
||||||
|
JSON_FIELD_NAME_META_TITLE='main_metadata_title'
|
||||||
|
MAIN_METADATA_TITLE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$JSON_FIELD_NAME_META_TITLE//p" ${CONFIG_PROFILES_PATHS_ARRAY[$PROFILE_COUNTER]}))
|
||||||
|
# MAIN_METADATA_TITLE="${MAIN_METADATA_TITLE// /\+}"
|
||||||
|
echo -e " Title: \"$MAIN_METADATA_TITLE\"";
|
||||||
|
|
||||||
|
# Empty metadata display variables
|
||||||
|
MAIN_METADATA_ARTIST=""
|
||||||
|
MAIN_METADATA_TITLE=""
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Render profile name
|
||||||
|
echo -e " $i"
|
||||||
|
|
||||||
|
# Render profile metadata
|
||||||
|
JSON_FIELD_NAME_META_ARTIST='main_metadata_artist'
|
||||||
|
MAIN_METADATA_ARTIST=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$JSON_FIELD_NAME_META_ARTIST//p" ${CONFIG_PROFILES_PATHS_ARRAY[$PROFILE_COUNTER]}))
|
||||||
|
# MAIN_METADATA_ARTIST="${MAIN_METADATA_ARTIST// /\+}"
|
||||||
|
echo -e " Artist: \"$MAIN_METADATA_ARTIST\"";
|
||||||
|
JSON_FIELD_NAME_META_TITLE='main_metadata_title'
|
||||||
|
MAIN_METADATA_TITLE=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/$JSON_FIELD_NAME_META_TITLE//p" ${CONFIG_PROFILES_PATHS_ARRAY[$PROFILE_COUNTER]}))
|
||||||
|
# MAIN_METADATA_TITLE="${MAIN_METADATA_TITLE// /\+}"
|
||||||
|
echo -e " Title: \"$MAIN_METADATA_TITLE\"";
|
||||||
|
|
||||||
|
# Empty metadata display variables
|
||||||
|
MAIN_METADATA_ARTIST=""
|
||||||
|
MAIN_METADATA_TITLE=""
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increment Counter
|
||||||
|
PROFILE_COUNTER=$((PROFILE_COUNTER+1))
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo -e " ${COLOR_RED}${FONT_BOLD}[Empty! - run \"n\" to create a profile!]${FONT_DEFAULT}${COLOR_DEFAULT}"
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Empty variables
|
||||||
|
PROFILE_COUNTER=0
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Verify Configuration Filename Characters
|
||||||
|
# Verifies inbound string against specified $REGEX, returning true or false match
|
||||||
|
# Returns a true or false confirmation
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function verify_configuration_filename_characters()
|
||||||
|
{
|
||||||
|
|
||||||
|
REGEX="^[a-zA-Z0-9\ \_-]+$"
|
||||||
|
if [[ "$*" =~ ${REGEX} ]]
|
||||||
|
then
|
||||||
|
TEMP="true"
|
||||||
|
else
|
||||||
|
TEMP="false"
|
||||||
|
fi
|
||||||
|
echo $TEMP
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Convert Spaces to Underscores
|
||||||
|
# Converts inbound string's spaces to underscores, returns converted string
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function convert_spaces_to_underscores() {
|
||||||
|
TEMP=${*// /_}
|
||||||
|
echo "$TEMP"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Render Config Menu
|
||||||
|
# Renders main configuration menu (option "J" from main menu)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function render_config_menu {
|
||||||
|
|
||||||
|
list_existing_config_files
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Mini HR
|
||||||
|
printf " "
|
||||||
|
render_mini_horizontal_rule
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Render
|
||||||
|
echo -e " ${COLOR_WHITE}${FONT_BOLD}CONFIG OPTIONS:${FONT_DEFAULT}${COLOR_DEFAULT}";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}e${FONT_DEFAULT}${COLOR_DEFAULT} : edit";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}n${FONT_DEFAULT}${COLOR_DEFAULT} : new";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}d${FONT_DEFAULT}${COLOR_DEFAULT} : delete";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}c${FONT_DEFAULT}${COLOR_DEFAULT} : copy";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}r${FONT_DEFAULT}${COLOR_DEFAULT} : rename";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}x${FONT_DEFAULT}${COLOR_DEFAULT} : empty deleted trash";
|
||||||
|
echo -e ""
|
||||||
|
echo -e " ${COLOR_WHITE}${FONT_BOLD}CONFIG ACTIVATION:${FONT_DEFAULT}${COLOR_DEFAULT}";
|
||||||
|
echo -e " ${COLOR_CYAN}${FONT_BOLD}u${FONT_DEFAULT}${COLOR_DEFAULT} : use";
|
||||||
|
echo -e ""
|
||||||
|
echo -e ""
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Process Config Menu Selection
|
||||||
|
# Processes main input from config menu
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function process_config_menu_selection() {
|
||||||
|
|
||||||
|
# Case Switch
|
||||||
|
case $1 in
|
||||||
|
|
||||||
|
e) # Edit JSON Streaming Profile:
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_edit" ;;
|
||||||
|
n) # New JSON Streaming Profile:
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_new" ;;
|
||||||
|
d) # Delete JSON Streaming Profile:
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_delete" ;;
|
||||||
|
c) # Copy Profile
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_copy" ;;
|
||||||
|
r) # Rename Profile
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_rename" ;;
|
||||||
|
u) # Use Profile
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_use" ;;
|
||||||
|
x) # Empty Trash
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-config_empty_trash" ;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Main Program Function
|
||||||
|
# Master program run routine (and run execution)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function execute_config_routine {
|
||||||
|
|
||||||
|
|
||||||
|
# Refresh Array of Available Configs and render menu
|
||||||
|
printf "${COLOR_GREEN}[J] Config Options menu:${COLOR_DEFAULT}\n";
|
||||||
|
echo -e ""
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Declare, localize, and refresh arrays
|
||||||
|
unset CONFIG_PROFILES_ARRAY
|
||||||
|
declare -a CONFIG_PROFILES_ARRAY=() >/dev/null
|
||||||
|
local $CONFIG_PROFILES_ARRAY >/dev/null
|
||||||
|
unset CONFIG_PROFILES_PATHS_ARRAY
|
||||||
|
declare -a CONFIG_PROFILES_PATHS_ARRAY=() >/dev/null
|
||||||
|
local $CONFIG_PROFILES_PATHS_ARRAY >/dev/null
|
||||||
|
|
||||||
|
|
||||||
|
# Refresh config file list and render menu
|
||||||
|
refresh_config_file_reference_array
|
||||||
|
render_config_menu
|
||||||
|
|
||||||
|
|
||||||
|
# Read Command Input
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
|
||||||
|
|
||||||
|
# Declare, localize, and refresh arrays
|
||||||
|
unset CONFIG_PROFILES_ARRAY
|
||||||
|
declare -a CONFIG_PROFILES_ARRAY=() >/dev/null
|
||||||
|
local $CONFIG_PROFILES_ARRAY >/dev/null
|
||||||
|
unset CONFIG_PROFILES_PATHS_ARRAY
|
||||||
|
declare -a CONFIG_PROFILES_PATHS_ARRAY=() >/dev/null
|
||||||
|
local $CONFIG_PROFILES_PATHS_ARRAY >/dev/null
|
||||||
|
|
||||||
|
|
||||||
|
# Refresh config file list
|
||||||
|
refresh_config_file_reference_array
|
||||||
|
|
||||||
|
|
||||||
|
# Refresh config list array and read input
|
||||||
|
MENU_NAME=`echo -e "${COLOR_CYAN}[Config Menu]${COLOR_DEFAULT}"`
|
||||||
|
read -p "$MENU_NAME Choice? (RETURN main menu, or \"J\" config options menu): " CONFIG_MENU_INPUT;
|
||||||
|
|
||||||
|
|
||||||
|
# If "J" entered
|
||||||
|
if [[ $CONFIG_MENU_INPUT == "J" ]]; then
|
||||||
|
|
||||||
|
# Refresh Array of Available Configs and render menu
|
||||||
|
printf "${COLOR_GREEN}[J] Config options menu.${COLOR_DEFAULT}\n"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
refresh_config_file_reference_array
|
||||||
|
render_config_menu
|
||||||
|
|
||||||
|
|
||||||
|
# If no key entered
|
||||||
|
elif [[ -z $CONFIG_MENU_INPUT ]]; then
|
||||||
|
|
||||||
|
printf "${COLOR_GREEN}[RETURN] Main menu.${COLOR_DEFAULT}\n"
|
||||||
|
echo ""
|
||||||
|
refresh_config_file_reference_array
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
# Evaluate Character entered
|
||||||
|
else
|
||||||
|
|
||||||
|
refresh_config_file_reference_array
|
||||||
|
process_config_menu_selection $CONFIG_MENU_INPUT
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
execute_config_routine
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Copy
|
||||||
|
|
||||||
|
|
||||||
|
# If profiles exist
|
||||||
|
if (( ${#CONFIG_PROFILES_ARRAY[@]} ));
|
||||||
|
then
|
||||||
|
|
||||||
|
# Read input
|
||||||
|
read -p "Profile to Copy?: " PROFILE_NAME_TO_COPY
|
||||||
|
|
||||||
|
# Input validate (check if empty)
|
||||||
|
if [[ -z "$PROFILE_NAME_TO_COPY" ]]; then
|
||||||
|
error_message "[c] Config (copy): Input blank. No file identied for copying."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_")
|
||||||
|
elif [[ "$PROFILE_NAME_TO_COPY" =~ [^a-zA-Z0-9_-] ]]; then
|
||||||
|
|
||||||
|
# Validate response: Invalid characters
|
||||||
|
error_message "[c] Config (copy): Filenames are alphanum only (no spaces). Try again."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Check if in array of available files. If not, then create new.
|
||||||
|
if [[ "${CONFIG_PROFILES_ARRAY[*]}" =~ ${PROFILE_NAME_TO_COPY} ]]; then
|
||||||
|
|
||||||
|
# Read Input
|
||||||
|
read -p "New name for Copy?: " PROFILE_COPY_NAME
|
||||||
|
|
||||||
|
# Input validate (check if empty)
|
||||||
|
if [[ -z "$PROFILE_COPY_NAME" ]]; then
|
||||||
|
error_message "[c] Config (copy): No filename provide for new copy."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_")
|
||||||
|
elif [[ "$PROFILE_COPY_NAME" =~ [^a-zA-Z0-9_-] ]]; then
|
||||||
|
error_message "[c] Config (copy): New filenames are alphanum only (no spaces). Try again."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Proceed with copy procedure
|
||||||
|
sudo cp "$CONFIG_DIRECTORY/config-$PROFILE_NAME_TO_COPY.json" "$CONFIG_DIRECTORY/config-$PROFILE_COPY_NAME.json"
|
||||||
|
confirmation_message "[c] Config (copy): Copy \"$PROFILE_COPY_NAME\" created from \"$PROFILE_NAME_TO_COPY\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
error_message "[c] Config (copy): No file \"$PROFILE_NAME_TO_COPY\" exists to copy."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# If no profiles exist
|
||||||
|
else
|
||||||
|
|
||||||
|
error_message "[c] Config (copy): No config profiles to Copy. Create with \"new\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Delete
|
||||||
|
|
||||||
|
|
||||||
|
# If profiles exist
|
||||||
|
if (( ${#CONFIG_PROFILES_ARRAY[@]} ));
|
||||||
|
then
|
||||||
|
|
||||||
|
# Read input
|
||||||
|
read -p "Name of profile to Delete? (spaces allowable): " CONFIG_PROFILE_TO_DELETE
|
||||||
|
|
||||||
|
# Input validate (check if empty)
|
||||||
|
if [[ -z "$CONFIG_PROFILE_TO_DELETE" ]]
|
||||||
|
then
|
||||||
|
error_message "[d] Config (delete): Input blank. No file identied for deletion deleted."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_ ")
|
||||||
|
elif [[ "$CONFIG_PROFILE_TO_DELETE" =~ [^a-zA-Z0-9_-] ]]
|
||||||
|
then
|
||||||
|
error_message "[n] Config (delete): Filenames are alphanum only (spaces OK). Try again."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Proceed with profile deletion
|
||||||
|
else
|
||||||
|
|
||||||
|
|
||||||
|
# Check if name exists, and if so mark flag
|
||||||
|
PROFILE_EXISTS_FLAG="false"
|
||||||
|
for FILE_TO_DELETE_NAME in "${CONFIG_PROFILES_ARRAY[@]}"
|
||||||
|
do
|
||||||
|
|
||||||
|
if [[ "${FILE_TO_DELETE_NAME}" == ${CONFIG_PROFILE_TO_DELETE} ]]
|
||||||
|
then
|
||||||
|
PROFILE_EXISTS_FLAG="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Perform final action based on flag
|
||||||
|
if [[ $PROFILE_EXISTS_FLAG == "true" ]]
|
||||||
|
then
|
||||||
|
|
||||||
|
# Reference $CURRENTLY_ACTIVE_CONFIG_FILE to see if deleting is current in use
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_FILE=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
if [[ ${CONFIG_PROFILE_TO_DELETE} == "$CURRENTLY_ACTIVE_CONFIG_FILE" ]]
|
||||||
|
|
||||||
|
# If to delete is in use
|
||||||
|
then
|
||||||
|
|
||||||
|
# Delete file (move to trash)
|
||||||
|
TIMESTAMP=$(date +%Y-%m-%d--%H-%M-%S)
|
||||||
|
mv "$CONFIG_DIRECTORY/config-$CONFIG_PROFILE_TO_DELETE.json" "$CONFIG_DIRECTORY/trash/config-$CONFIG_PROFILE_TO_DELETE.json_(DELETED_${TIMESTAMP})"
|
||||||
|
|
||||||
|
# Delete config file identifier
|
||||||
|
truncate -s 0 "$CONFIG_FILE_IDENTIFIER_PATH"
|
||||||
|
|
||||||
|
# Confirmation / Alert
|
||||||
|
warning_message "[WARNING]: Config file no longer specified. Please specify one to stream."
|
||||||
|
confirmation_message "[d] Config (delete): Deletion of \"$CONFIG_PROFILE_TO_DELETE\" completed (file moved to trash)."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
# If to delete is not in use
|
||||||
|
else
|
||||||
|
TIMESTAMP=$(date +%Y-%m-%d--%H-%M-%S)
|
||||||
|
mv "$CONFIG_DIRECTORY/config-$CONFIG_PROFILE_TO_DELETE.json" "$CONFIG_DIRECTORY/trash/config-$CONFIG_PROFILE_TO_DELETE.json_(DELETED_${TIMESTAMP})"
|
||||||
|
confirmation_message "[d] Config (delete): Deletion of \"$CONFIG_PROFILE_TO_DELETE\" completed (file moved to trash)."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unset currently actie config file variable
|
||||||
|
unset CURRENTLY_ACTIVE_CONFIG_FILE
|
||||||
|
|
||||||
|
|
||||||
|
# If profile doesn't exist
|
||||||
|
else
|
||||||
|
error_message "[d] Config (delete): No Config named \"$CONFIG_PROFILE_TO_DELETE\" to delete."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unset Flag
|
||||||
|
unset PROFILE_EXISTS_FLAG
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# If no profiles exist
|
||||||
|
else
|
||||||
|
|
||||||
|
error_message "[d] Config (delete): No config profiles to delete. Create with \"new\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Edit
|
||||||
|
# Edit System Configuration (.json) file
|
||||||
|
|
||||||
|
|
||||||
|
# If profiles exist
|
||||||
|
if (( ${#CONFIG_PROFILES_ARRAY[@]} ));
|
||||||
|
then
|
||||||
|
|
||||||
|
# Read Input
|
||||||
|
read -p "Profile Name to Edit?: " CONFIG_PROFILE_TO_EDIT
|
||||||
|
|
||||||
|
# Input validate (check if empty)
|
||||||
|
if [[ -z "$CONFIG_PROFILE_TO_EDIT" ]]
|
||||||
|
then
|
||||||
|
error_message "[e] Config (edit): Input blank. No file specified for editing."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_ "), convert spaces to underscores
|
||||||
|
elif [[ "$CONFIG_PROFILE_TO_EDIT" =~ [^a-zA-Z0-9_-] ]]
|
||||||
|
then
|
||||||
|
error_message "[e] Config (edit): Files are alphanum characters only. No spaces."
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Precautionary Convert Spaces to Understores
|
||||||
|
UNDERSCORED_PROFILE_NAME_INPUT=$(convert_spaces_to_underscores "$CONFIG_PROFILE_TO_EDIT")
|
||||||
|
|
||||||
|
# Check if in array of available files. If so, process
|
||||||
|
if [[ " ${CONFIG_PROFILES_ARRAY[*]} " =~ ${UNDERSCORED_PROFILE_NAME_INPUT} ]]
|
||||||
|
then
|
||||||
|
|
||||||
|
|
||||||
|
sudo nano "$CONFIG_DIRECTORY/config-$UNDERSCORED_PROFILE_NAME_INPUT.json"
|
||||||
|
TIMESTAMP=$(date +%Y-%m-%d" ("%H"h "%M"m "%S"s)")
|
||||||
|
sed -i "s/\/\/ Last modified.*/\/\/ Last modified: $TIMESTAMP/" "$CONFIG_DIRECTORY/config-$UNDERSCORED_PROFILE_NAME_INPUT.json"
|
||||||
|
confirmation_message "[e] Config (edit): Editing of \"$CONFIG_PROFILE_TO_EDIT\" completed."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
error_message "[e] Config (edit): No config \"$CONFIG_PROFILE_TO_EDIT\" to edit."
|
||||||
|
echo -e ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no profiles exist
|
||||||
|
else
|
||||||
|
|
||||||
|
error_message "[e] Config (edit): No config profiles to edit. Create with \"new\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Empty Trash (rm all deleted config profiles in trash can)
|
||||||
|
|
||||||
|
|
||||||
|
# Get number of files in folder
|
||||||
|
TRASH_FILES_COUNT=$(ls "$CONFIG_DIRECTORY/trash/" | wc -l)
|
||||||
|
|
||||||
|
|
||||||
|
# Delete Routine
|
||||||
|
if [[ "$TRASH_FILES_COUNT" == 0 ]]
|
||||||
|
|
||||||
|
then
|
||||||
|
echo -e "[x] Empty Trash (deleted config files): Trash empty / no files to delete."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
elif [[ "$TRASH_FILES_COUNT" == 1 ]]
|
||||||
|
|
||||||
|
then
|
||||||
|
sudo rm -r "$CONFIG_DIRECTORY/trash/"*
|
||||||
|
confirmation_message "[x] Empty Trash (deleted config files): Completed. $TRASH_FILES_COUNT file deleted."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
sudo rm -r "$CONFIG_DIRECTORY/trash/"*
|
||||||
|
confirmation_message "[x] Empty Trash (deleted config files): Completed. $TRASH_FILES_COUNT files deleted."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,66 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG New
|
||||||
|
# Edit System Configuration (.json) file
|
||||||
|
|
||||||
|
|
||||||
|
# Read input
|
||||||
|
read -p "New Profile Name?: " NEW_PROFILE_NAME
|
||||||
|
|
||||||
|
# Input validate (check if empty)
|
||||||
|
if [[ -z "$NEW_PROFILE_NAME" ]]
|
||||||
|
then
|
||||||
|
error_message "[n] Config (new): Input blank. No new file created."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_ "), convert spaces to underscores
|
||||||
|
elif [[ "$NEW_PROFILE_NAME" =~ [^a-zA-Z0-9_-] ]]
|
||||||
|
then
|
||||||
|
error_message "[n] Config (new): Filenames are alphanum only (no spaces). No file created."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Proceed with profile creation
|
||||||
|
else
|
||||||
|
|
||||||
|
|
||||||
|
# Check if name exists, and if so mark flag
|
||||||
|
PROFILE_EXISTS_FLAG="false"
|
||||||
|
for NEW_NAME_CHECK_LOOPED in "${CONFIG_PROFILES_ARRAY[@]}"
|
||||||
|
do
|
||||||
|
|
||||||
|
if [[ "${NEW_NAME_CHECK_LOOPED}" == ${NEW_PROFILE_NAME} ]]
|
||||||
|
then
|
||||||
|
PROFILE_EXISTS_FLAG="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Perform final action based on flag
|
||||||
|
if [[ $PROFILE_EXISTS_FLAG == "true" ]]
|
||||||
|
|
||||||
|
|
||||||
|
# If profile exists
|
||||||
|
then
|
||||||
|
error_message "[n] Config (new): config profile named \"$NEW_PROFILE_NAME\" already exist."
|
||||||
|
echo -e""
|
||||||
|
|
||||||
|
# If profile doesn't exist
|
||||||
|
else
|
||||||
|
sudo cp "$CONFIG_TEMPLATE_DIRECTORY/config-sample.json" "$CONFIG_DIRECTORY/config-$NEW_PROFILE_NAME.json"
|
||||||
|
TIMESTAMP=$(date +%Y-%m-%d" ("%H"h "%M"m "%S"s)")
|
||||||
|
sed -i "s/%%%%config_name%%%%/$NEW_PROFILE_NAME/" "$CONFIG_DIRECTORY/config-$NEW_PROFILE_NAME.json"
|
||||||
|
sed -i "s/%%%%creation_date%%%%/$TIMESTAMP/" "$CONFIG_DIRECTORY/config-$NEW_PROFILE_NAME.json"
|
||||||
|
sed -i "s/%%%%last_modified%%%%/$TIMESTAMP/" "$CONFIG_DIRECTORY/config-$NEW_PROFILE_NAME.json"
|
||||||
|
confirmation_message "[n] Config (new): Blank config profile \"$NEW_PROFILE_NAME\" created."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unset Flag
|
||||||
|
unset PROFILE_EXISTS_FLAG
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Rename
|
||||||
|
|
||||||
|
|
||||||
|
# If profiles exist
|
||||||
|
if (( ${#CONFIG_PROFILES_ARRAY[@]} ));
|
||||||
|
|
||||||
|
# Main Rename Routine
|
||||||
|
then
|
||||||
|
|
||||||
|
# Read input
|
||||||
|
read -p "Profile to Rename?: " PROFILE_TO_RENAME
|
||||||
|
|
||||||
|
# Input validate (check if empty)
|
||||||
|
if [[ -z "$PROFILE_TO_RENAME" ]]; then
|
||||||
|
error_message "[r] Config (rename): Input blank. No file identied for renaming."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_")
|
||||||
|
elif [[ "$PROFILE_TO_RENAME" =~ [^a-zA-Z0-9_-] ]]; then
|
||||||
|
error_message "[r] Config (rename): Filenames are alphanum only (no spaces). Try again."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Check if file exists
|
||||||
|
if [[ "${CONFIG_PROFILES_ARRAY[*]}" =~ ${PROFILE_TO_RENAME} ]]; then
|
||||||
|
|
||||||
|
# Read input
|
||||||
|
read -p "New name for file?: " PROFILE_NEW_NAME
|
||||||
|
|
||||||
|
# Input Validate (check if empty)
|
||||||
|
if [[ -z "$PROFILE_NEW_NAME" ]]; then
|
||||||
|
error_message "[r] Config (rename): New file name is blank."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_")
|
||||||
|
elif [[ "$PROFILE_NEW_NAME" =~ [^a-zA-Z0-9_-] ]]; then
|
||||||
|
|
||||||
|
error_message "[r] Config (rename): Filenames are alphanum only (no spaces). Try again."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Input validate (check for alphanum & "-_")
|
||||||
|
if [[ "${CONFIG_PROFILES_ARRAY[*]}" =~ ${PROFILE_NEW_NAME} ]]; then
|
||||||
|
error_message "[r] Config (rename): New name for file already exists."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Renaming routine
|
||||||
|
else
|
||||||
|
|
||||||
|
# Get name of current config
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_FILE=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
|
||||||
|
if [[ "$CURRENTLY_ACTIVE_CONFIG_FILE" == "$PROFILE_TO_RENAME" ]];
|
||||||
|
|
||||||
|
# If profile being renamed is the currently used profile
|
||||||
|
then
|
||||||
|
|
||||||
|
# Rename/mv file and change internal name
|
||||||
|
sudo mv "$CONFIG_DIRECTORY/config-$PROFILE_TO_RENAME.json" "$CONFIG_DIRECTORY/config-$PROFILE_NEW_NAME.json"
|
||||||
|
sed -i "s/\/\/ Config name.*/\/\/ Config name: $PROFILE_NEW_NAME/" "$CONFIG_DIRECTORY/config-$PROFILE_NEW_NAME.json"
|
||||||
|
|
||||||
|
# Delete config file identifier contents and push new name
|
||||||
|
truncate -s 0 "$CONFIG_FILE_IDENTIFIER_PATH"
|
||||||
|
echo "$PROFILE_NEW_NAME" >> $CONFIG_FILE_IDENTIFIER_PATH
|
||||||
|
|
||||||
|
# Confirm
|
||||||
|
confirmation_message "[r] Config (rename): Config file \"$PROFILE_TO_RENAME\" renamed to \"$PROFILE_NEW_NAME\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
# If profile being renamed is NOT the currently used profile
|
||||||
|
else
|
||||||
|
|
||||||
|
# Rename/mv file and change internal name
|
||||||
|
sudo mv "$CONFIG_DIRECTORY/config-$PROFILE_TO_RENAME.json" "$CONFIG_DIRECTORY/config-$PROFILE_NEW_NAME.json"
|
||||||
|
sed -i "s/\/\/ Config name.*/\/\/ Config name: $PROFILE_NEW_NAME/" "$CONFIG_DIRECTORY/config-$PROFILE_NEW_NAME.json"
|
||||||
|
|
||||||
|
# Confirm
|
||||||
|
confirmation_message "[r] Config (rename): Config file \"$PROFILE_TO_RENAME\" renamed to \"$PROFILE_NEW_NAME\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
error_message "[r] Config (Rename): No file named \"$PROFILE_TO_RENAME\" to rename."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# No profiles exist
|
||||||
|
else
|
||||||
|
error_message "[r] Config (rename): No config profiles to rename. Create with \"new\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: CONFIG Use
|
||||||
|
|
||||||
|
|
||||||
|
# If profiles exist
|
||||||
|
if (( ${#CONFIG_PROFILES_ARRAY[@]} ));
|
||||||
|
|
||||||
|
# Main Use Routine
|
||||||
|
then
|
||||||
|
|
||||||
|
# Read input
|
||||||
|
read -p "Profile to use?: " PROFILE_NAME_TO_USE
|
||||||
|
|
||||||
|
# Check if empty
|
||||||
|
if [[ -z $PROFILE_NAME_TO_USE ]]; then
|
||||||
|
error_message "[u] Config (use): No filename entered."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Validate: If input not alphanum/underscore
|
||||||
|
elif [[ "$PROFILE_NAME_TO_USE" =~ [^a-zA-Z0-9_-] ]]; then
|
||||||
|
error_message "[u] Config (use): Filename must be alphanum or underscored."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
# Check if in array
|
||||||
|
elif [[ "${CONFIG_PROFILES_ARRAY[*]}" =~ ${PROFILE_NAME_TO_USE} ]]; then
|
||||||
|
|
||||||
|
# Empty active config declaration file, and copy new name to it
|
||||||
|
sudo truncate -s 0 $CONFIG_FILE_IDENTIFIER_PATH
|
||||||
|
echo "$PROFILE_NAME_TO_USE" >> $CONFIG_FILE_IDENTIFIER_PATH
|
||||||
|
confirmation_message "[u] Config (use): Now using profile \"$PROFILE_NAME_TO_USE\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
error_message "[u] Config (use): No config named \"$PROFILE_NAME_TO_USE\" to use."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# No profiles exist
|
||||||
|
else
|
||||||
|
error_message "[u] Config (use): No config profiles to use. Create with \"new\"."
|
||||||
|
echo -e ""
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,68 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM DECLARATIONS
|
||||||
|
# "Global" variables used in program (this document sourced in anonradio)
|
||||||
|
|
||||||
|
|
||||||
|
# PERMISSIONS OWNER (chown)
|
||||||
|
APPLICATION_FILE_OWNER="pi"
|
||||||
|
|
||||||
|
# APPLICATION DIRECTORIES
|
||||||
|
DECLARATIONS_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
APPLICATION_ROOT=$(realpath "$DECLARATIONS_DIRECTORY/../..")
|
||||||
|
AUDIO_QUEUED_DIRECTORY="$APPLICATION_ROOT/audio_queued"
|
||||||
|
PLAYLIST_PATH="$APPLICATION_ROOT/playlists/playlist.m3u"
|
||||||
|
FLAGS_DIRECTORY="$APPLICATION_ROOT/.flags"
|
||||||
|
CONFIG_DIRECTORY="$APPLICATION_ROOT/config"
|
||||||
|
CONFIG_TEMPLATE_DIRECTORY="$APPLICATION_ROOT/var/templates"
|
||||||
|
CONFIG_FILE_IDENTIFIER_PATH="$APPLICATION_ROOT/var/active_config_name"
|
||||||
|
LOG_FOLDER_PATH="$APPLICATION_ROOT/var/log/"
|
||||||
|
|
||||||
|
# DEPENDENCIES
|
||||||
|
DEPENDENCIES=("liquidsoap" "alsamixer" "ffprobe" "bc")
|
||||||
|
|
||||||
|
# COLOR DECLARATIONS
|
||||||
|
COLOR_DEFAULT='\033[39m'
|
||||||
|
COLOR_BLACK='\033[30m'
|
||||||
|
COLOR_RED='\033[31m'
|
||||||
|
COLOR_GREEN='\033[32m'
|
||||||
|
COLOR_YELLOW='\033[33m'
|
||||||
|
COLOR_BLUE='\033[34m'
|
||||||
|
COLOR_MAGENTA='\033[35m'
|
||||||
|
COLOR_CYAN='\033[36m'
|
||||||
|
COLOR_GRAY='\033[90m'
|
||||||
|
COLOR_LIGHT_GRAY='\033[37m'
|
||||||
|
COLOR_LIGHT_RED='\033[91m'
|
||||||
|
COLOR_LIGHT_GREEN='\033[92m'
|
||||||
|
COLOR_LIGHT_YELLOW='\033[93m'
|
||||||
|
COLOR_LIGHT_BLUE='\033[94m'
|
||||||
|
COLOR_LIGHT_MAGENTA='\033[95m'
|
||||||
|
COLOR_LIGHT_CYAN='\033[96m'
|
||||||
|
COLOR_WHITE='\033[97m'
|
||||||
|
|
||||||
|
# FONT STYLE
|
||||||
|
FONT_DEFAULT=$(tput sgr0) #Turn off all attributes
|
||||||
|
FONT_BOLD=$(tput bold) #Start bold text
|
||||||
|
FONT_UNDERLINE=$(tput smul) #Start underlined text
|
||||||
|
FONT_REMOVE_UNDERLINE=$(tput rmul) #End underlined text
|
||||||
|
FONT_REVERSE=$(tput rev) #Start reverse video
|
||||||
|
FONT_BLINK=$(tput blink) #Start blinking text
|
||||||
|
FONT_INVISIBLE=$(tput invis) #Start invisible text
|
||||||
|
FONT_STANDOUT=$(tput smso) #Start "standout" mode
|
||||||
|
FONT_REMOVE_STANDOUT=$(tput rmso) #End "standout" mode
|
||||||
|
FONT_STRIKETHROUGH='\e[9' #Start Strikethrough
|
||||||
|
FONT_REMOVE_STRIKETHROUGH='\e[0m' #End Strikethrough
|
||||||
|
FONT_UNDERLINE='\e[4' #Start Strikethrough
|
||||||
|
FONT_REMOVE_UNDERLINE='\e[0m' #End Strikethrough
|
||||||
|
SET_FOREGROUND_COLORS_=$(tput setaf) # <value> Set foreground color
|
||||||
|
SET_BACKGROUND_COLORS=$(tput setab) # <value> Set background color
|
||||||
|
|
||||||
|
|
||||||
|
# UNICODE BOX DRAWING AND SYMBOLS
|
||||||
|
SYMBOL_DOUBLE_DOT='\u205A'
|
||||||
|
SYMBOL_QUADRUPLE_DOT='\u205E'
|
||||||
|
SYMBOL_DOUBLE_PIPE='\u254E'
|
||||||
|
SYMBOL_RAQUO='\u00BB'
|
||||||
|
BORDER_VERTICAL='\u2502'
|
||||||
|
SYMBOL_HAZARD='\u25B2'
|
||||||
|
SYMBOL_CHECKMARK='\u2713'
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Functions
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# FUNCTION: Git Keep (touch routine)
|
||||||
|
# Touch .gitkeep files to create folders where they might not exist
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function git_keep_touch_routine() {
|
||||||
|
|
||||||
|
sudo touch \
|
||||||
|
"$APPLICATION_ROOT/audio_queued/.gitkeep" \
|
||||||
|
"$APPLICATION_ROOT/config/.gitkeep" \
|
||||||
|
"$APPLICATION_ROOT/config/trash/.gitkeep" \
|
||||||
|
"$APPLICATION_ROOT/playlists/.gitkeep" \
|
||||||
|
"$APPLICATION_ROOT/var/log/.gitkeep" \
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# FUNCTION: Verify Dependencies
|
||||||
|
# Check to make sure that all dependencies are installed, else quit
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function check_for_missing_dependencies() {
|
||||||
|
|
||||||
|
# Dependencies to check for ($DEPENDENCIES defined in system-declarations)
|
||||||
|
MISSING_DEPENDENCIES=0
|
||||||
|
|
||||||
|
# Iterate and check for missing
|
||||||
|
for DEPENDENCY_NAME in "${DEPENDENCIES[@]}"; do :
|
||||||
|
|
||||||
|
# If missing, then flag as missing exists
|
||||||
|
if ! command -v "$DEPENDENCY_NAME" &> /dev/null; then
|
||||||
|
MISSING_DEPENDENCIES=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# if missing exist, list and exit
|
||||||
|
if [[ $MISSING_DEPENDENCIES == 1 ]]; then
|
||||||
|
|
||||||
|
echo -e "The following missing dependencies are required for soapdish (v${VERSION}):"
|
||||||
|
for DEPENDENCY_NAME in "${DEPENDENCIES[@]}"; do :
|
||||||
|
|
||||||
|
if ! command -v "$DEPENDENCY_NAME" &> /dev/null; then
|
||||||
|
printf "%s$DEPENDENCY_NAME "
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
echo -e "\nPlease install and try again."
|
||||||
|
|
||||||
|
# Exit
|
||||||
|
exit
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# FUNCTION: Verify Config File Identifier Validity
|
||||||
|
# Check to make sure that all dependencies are installed, else quit
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function verify_config_file_identifier_validity() {
|
||||||
|
|
||||||
|
echo -e "Verifying config file identifier validity (WIP)"
|
||||||
|
|
||||||
|
# Get value of identifier and act accordingly (if blank or not)
|
||||||
|
CURRENT_CONFIG_FILE_IDENTIFIER_VALUE=$(<$CONFIG_FILE_IDENTIFIER_PATH)
|
||||||
|
if [[ $CURRENT_CONFIG_FILE_IDENTIFIER_VALUE != "" ]]
|
||||||
|
|
||||||
|
then
|
||||||
|
echo -e "Config File Identifier Value == $CURRENT_CONFIG_FILE_IDENTIFIER_VALUE"
|
||||||
|
echo -e "Here is where you compare flag to each config file"
|
||||||
|
echo -e "constuct array of all config names"
|
||||||
|
echo -e "cycle through to verify flag matches"
|
||||||
|
echo -e "if no match, then wipe flag"
|
||||||
|
echo -e "make sure flag in main menu updates AFTER you wipe flag"
|
||||||
|
echo -e "(run this function before anythign else runs)"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# FUNCTION: Render Horizontal Rule
|
||||||
|
# Renders an 80-character horizontal rule
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function render_horizontal_rule() {
|
||||||
|
|
||||||
|
# # HR style alternaties (uncomment desired style)
|
||||||
|
# HR_PIECE="\u2504"
|
||||||
|
# HR_PIECE="\u2508"
|
||||||
|
HR_PIECE="\u2500"
|
||||||
|
# HR_PIECE="–"
|
||||||
|
|
||||||
|
# Render
|
||||||
|
for i in {1..80}
|
||||||
|
do
|
||||||
|
printf "$HR_PIECE"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# FUNCTION: Generate Random Hex Value
|
||||||
|
# Renders an a hex string of $1 character length
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function generate_random_hex_value {
|
||||||
|
|
||||||
|
HEX_NUMBER_COMPILED=$(tr -dc 'A-F0-9' < /dev/urandom | head -c$1)
|
||||||
|
echo "$HEX_NUMBER_COMPILED"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Render Mini Horizontal Rule
|
||||||
|
# Renders an 20-character horizontal rule
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function render_mini_horizontal_rule() {
|
||||||
|
|
||||||
|
# # HR style alternaties (uncomment desired style)
|
||||||
|
# HR_PIECE="\u2504"
|
||||||
|
# HR_PIECE="\u2508"
|
||||||
|
HR_PIECE="\u2500"
|
||||||
|
# HR_PIECE="–"
|
||||||
|
|
||||||
|
# Render
|
||||||
|
for i in {1..20}
|
||||||
|
do
|
||||||
|
printf "$HR_PIECE"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTION: Reset Permissions
|
||||||
|
# Recursively resets permissions within application
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function reset_permissions() {
|
||||||
|
|
||||||
|
# Specify target directory ($DIR declared in system-declarations), and reset permissions
|
||||||
|
DIR=${APPLICATION_ROOT}
|
||||||
|
CURRENT_CHOWN_USER=$(whoami)
|
||||||
|
sudo chown -R "$CURRENT_CHOWN_USER" "$DIR"
|
||||||
|
sudo chmod 755 -R "$DIR"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTIONS: Alert Messages
|
||||||
|
# Styles input string according to message type (red:error, yellow:warning, green:alert)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function error_message() {
|
||||||
|
echo -e "${COLOR_RED}$1${COLOR_DEFAULT}"
|
||||||
|
}
|
||||||
|
function warning_message() {
|
||||||
|
echo -e "${COLOR_YELLOW}$1${COLOR_DEFAULT}"
|
||||||
|
}
|
||||||
|
function confirmation_message() {
|
||||||
|
echo -e "${COLOR_GREEN}$1${COLOR_DEFAULT}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FUNCTIONS: Encode URL
|
||||||
|
# Converts string to url-friendly (encoded) string
|
||||||
|
#
|
||||||
|
#
|
||||||
|
function url_encode_string () {
|
||||||
|
tab="`echo -en "\x9"`"
|
||||||
|
i="$@"
|
||||||
|
i=${i//%/%25} ; i=${i//' '/%20} ; i=${i//$tab/%09}
|
||||||
|
i=${i//!/%21} ; i=${i//'"'/%22} ; i=${i//#/%23}
|
||||||
|
i=${i//\$/%24} ; i=${i//\&/%26} ; i=${i//\'/%27}
|
||||||
|
i=${i//(/%28} ; i=${i//)/%29} ; i=${i//\*/%2a}
|
||||||
|
i=${i//+/%2b} ; i=${i//,/%2c} ; i=${i//-/%2d}
|
||||||
|
i=${i//\./%2e} ; i=${i//\//%2f} ; i=${i//:/%3a}
|
||||||
|
i=${i//;/%3b} ; i=${i//</%3c} ; i=${i//=/%3d}
|
||||||
|
i=${i//>/%3e} ; i=${i//\?/%3f} ; i=${i//@/%40}
|
||||||
|
i=${i//\[/%5b} ; i=${i//\\/%5c} ; i=${i//\]/%5d}
|
||||||
|
i=${i//\^/%5e} ; i=${i//_/%5f} ; i=${i//\`/%60}
|
||||||
|
i=${i//\{/%7b} ; i=${i//|/%7c} ; i=${i//\}/%7d}
|
||||||
|
i=${i//\~/%7e}
|
||||||
|
echo "$i"
|
||||||
|
i=""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: KILL STREAM PROCESSES
|
||||||
|
# Kill all processes with name of liquidsoap
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Kill Show
|
||||||
|
sudo pkill "liquidsoap";
|
||||||
|
|
||||||
|
|
||||||
|
# Wait and restart liquidsoap
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
|
||||||
|
# Attempt to restart liquidsoap as a service (if possible)
|
||||||
|
if RESULT=$(sudo systemctl restart liquidsoap 2>&1)
|
||||||
|
|
||||||
|
then
|
||||||
|
STDOUT="$RESULT"
|
||||||
|
confirmation_message "[K] Killall and Restart liquidsoap: executed";
|
||||||
|
echo "";
|
||||||
|
|
||||||
|
else
|
||||||
|
# Error code (not used)
|
||||||
|
RC=$?
|
||||||
|
# echo "code $RC"
|
||||||
|
# Error message (not used)
|
||||||
|
STDERR=$RESULT
|
||||||
|
# echo "THIS: $STDERR ok?"
|
||||||
|
|
||||||
|
echo "Liquidsoap killed, not restarted as a service (liquidsoap not a service)."
|
||||||
|
confirmation_message "[K] Killall and Restart liquidsoap: Liquidsoap killed.";
|
||||||
|
echo "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Echo result
|
|
@ -0,0 +1,92 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SYSTEM: UPDATE AUDIO FRAME SIZE
|
||||||
|
# Run debug then search log for instance of frame size. Assgn to variable then write to anonradio-config.json
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting, and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Kill process (as a safeguard)
|
||||||
|
sudo pkill "liquidsoap";
|
||||||
|
|
||||||
|
|
||||||
|
# Get active config name, construct path to streamable config file (for validation)
|
||||||
|
CURRENTLY_ACTIVE_CONFIG_NAME=$(<"$CONFIG_FILE_IDENTIFIER_PATH")
|
||||||
|
STREAMABLE_CONFIG_FILE_PATH="$CONFIG_DIRECTORY/config-$CURRENTLY_ACTIVE_CONFIG_NAME.json"
|
||||||
|
|
||||||
|
|
||||||
|
# Check if config file exists
|
||||||
|
if [[ -f "$STREAMABLE_CONFIG_FILE_PATH" ]];
|
||||||
|
|
||||||
|
# If exists
|
||||||
|
then
|
||||||
|
|
||||||
|
# Set up timestamp formatting, path, then create file and set permission for coming log-dump
|
||||||
|
TIMESTAMP_FILENAME="log-$(date +%s)"
|
||||||
|
CURRENT_CHOWN_USER=$(whoami)
|
||||||
|
FULL_LOG_FILE_PATH="$LOG_FOLDER_PATH/buffer_evaluation_$TIMESTAMP_FILENAME"
|
||||||
|
sudo touch "$FULL_LOG_FILE_PATH"
|
||||||
|
sudo chmod 755 "$FULL_LOG_FILE_PATH"
|
||||||
|
sudo chown "$CURRENT_CHOWN_USER" "$FULL_LOG_FILE_PATH"
|
||||||
|
|
||||||
|
|
||||||
|
# Log color formatting of log, then export log to specified log file (butter_evaluation_log-[timestamp])
|
||||||
|
printf "${COLOR_GRAY}";
|
||||||
|
liquidsoap -v --debug 'input.alsa(bufferize=false)' >> $FULL_LOG_FILE_PATH & sleep 3;
|
||||||
|
sudo pkill "liquidsoap";
|
||||||
|
sleep 2
|
||||||
|
printf "${COLOR_DEFAULT}"
|
||||||
|
|
||||||
|
|
||||||
|
# Notification of command edecution
|
||||||
|
confirmation_message "[H] Review Hardware Audio Frame Size:"
|
||||||
|
|
||||||
|
|
||||||
|
# sed to strip away just want
|
||||||
|
# Example log line (for reference):
|
||||||
|
# 2019/11/09 19:11:09 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples.
|
||||||
|
BUFFER_RECOMMENDED=$(sed -e s/"^.*ticks = "// -e s/" audio samples.*$"// <<< $(sed -n "s/Frame size must be a multiple of//p" $FULL_LOG_FILE_PATH))
|
||||||
|
BUFFER_DECLARED=$(sed -e s/'[ \t]*\"\"\:\"'// -e s/'".*'// <<< $(sed -n "s/"hardware_audio_frame_size"//p" $STREAMABLE_CONFIG_FILE_PATH))
|
||||||
|
|
||||||
|
|
||||||
|
# Check if declared AFS buffer size is a multiple of recommended AFS buffer (using bc)
|
||||||
|
# Then, if checked result has 8 decimal places of zeroes, then echo appropriate notice
|
||||||
|
BUFFER_MULTIPLE_CHECK=`echo "scale=8; $BUFFER_DECLARED/$BUFFER_RECOMMENDED" | bc -l`
|
||||||
|
if [[ $BUFFER_MULTIPLE_CHECK == *".00000000"* ]]; then
|
||||||
|
NOTICE="${COLOR_GREEN}${SYMBOL_CHECKMARK}${COLOR_DEFAULT} ${FONT_BOLD}Config settings OK! (config AFS is multiple of recommended AFS)${FONT_DEFAULT}"
|
||||||
|
else
|
||||||
|
NOTICE="${FONT_BOLD}${COLOR_YELLOW}${SYMBOL_HAZARD}${COLOR_DEFAULT} Warning: Config AFS is not a multiple of recommended AFS${FONT_DEFAULT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Output / Reporting:
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "${FONT_BOLD} HARDWARE, AUDIO FRAME SIZE (AFS):${FONT_DEFAULT}\n"
|
||||||
|
printf "\n"
|
||||||
|
# printf " • Default system frame size - $BUFFER_OBSERVED\n"
|
||||||
|
printf " • Recommended frame size - $BUFFER_RECOMMENDED\n"
|
||||||
|
printf " • Your current config's frame size - $BUFFER_DECLARED\n"
|
||||||
|
printf "\n"
|
||||||
|
printf " $NOTICE\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
|
||||||
|
# Unset Variables
|
||||||
|
IDENTIFYING_STRING=""
|
||||||
|
BUFFER_LINE=""
|
||||||
|
EVALUATED_SAMPLES=""
|
||||||
|
BUFFER_OBSERVED=""
|
||||||
|
NOTICE=""
|
||||||
|
|
||||||
|
# If no config file exists
|
||||||
|
else
|
||||||
|
error_message "[H] Review Hardware Audio Frame Size: No config file to reference. Please specify."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,236 @@
|
||||||
|
#! /bin/bash
|
||||||
|
# TILDERADIO MASTER EXECUTABLE - master executable for tilderadio
|
||||||
|
# Top level runtime of tilderadio program
|
||||||
|
|
||||||
|
|
||||||
|
# Get Source Dir, and then source Core Declarations file
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
source "${DIR}/scripts/system/system-declarations"
|
||||||
|
|
||||||
|
|
||||||
|
# Includes and Declarations (global variables, formatting and functions)
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-declarations"
|
||||||
|
source "${APPLICATION_ROOT}/scripts/system/system-functions"
|
||||||
|
source "${APPLICATION_ROOT}/var/version"
|
||||||
|
|
||||||
|
|
||||||
|
# Render Main Menu
|
||||||
|
function render_main_menu {
|
||||||
|
|
||||||
|
# Check to make sure active config file idenifier is valid. If not, then empty identifier.
|
||||||
|
CURRENT_CONFIG_NAME=$(<$CONFIG_FILE_IDENTIFIER_PATH)
|
||||||
|
CURRENT_CONFIG_FILE_CLAIMED_PATH="$CONFIG_DIRECTORY/config-${CURRENT_CONFIG_NAME}.json"
|
||||||
|
if ! [[ -f "$CURRENT_CONFIG_FILE_CLAIMED_PATH" ]]; then
|
||||||
|
|
||||||
|
truncate -s 0 "$CONFIG_FILE_IDENTIFIER_PATH"
|
||||||
|
CURRENT_CONFIG_NAME=$(<$CONFIG_FILE_IDENTIFIER_PATH)
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare Pretty Header
|
||||||
|
APP_AND_VERSION_PREFIX="soapdish - v${VERSION}"
|
||||||
|
APP_AND_VERSION_CHARCOUNT=${#APP_AND_VERSION_PREFIX}
|
||||||
|
|
||||||
|
# Render Main Menu - Appropriate pretty menuheading (check if a config is specified)
|
||||||
|
if [[ -n "$CURRENT_CONFIG_NAME" ]]; then
|
||||||
|
|
||||||
|
# If config file is set, prep variables
|
||||||
|
CURRENT_CONFIG_NAME_AND_PREFIX="[Using profile: \"${CURRENT_CONFIG_NAME}\"]"
|
||||||
|
CURRENT_CONFIG_NAME_CHARCOUNT=${#CURRENT_CONFIG_NAME_AND_PREFIX}
|
||||||
|
MENU_HEADER_SPACING_COUNT=$(( "80" - "$CURRENT_CONFIG_NAME_CHARCOUNT" - "$APP_AND_VERSION_CHARCOUNT" ))
|
||||||
|
MENU_HEADER_SPACING=""
|
||||||
|
for (( i = 0; i < MENU_HEADER_SPACING_COUNT; i++ )); do
|
||||||
|
MENU_HEADER_SPACING="${MENU_HEADER_SPACING} "
|
||||||
|
done
|
||||||
|
|
||||||
|
# Render
|
||||||
|
echo -e "";
|
||||||
|
echo -e "";
|
||||||
|
echo -e "${FONT_BOLD}${APP_AND_VERSION_PREFIX}${MENU_HEADER_SPACING}${CURRENT_CONFIG_NAME_AND_PREFIX}${FONT_DEFAULT}"
|
||||||
|
render_horizontal_rule
|
||||||
|
echo "";
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# If config file is NOT set, prep variables
|
||||||
|
CURRENT_CONFIG_NAME_AND_PREFIX="[No config specified!]"
|
||||||
|
CURRENT_CONFIG_NAME_CHARCOUNT=${#CURRENT_CONFIG_NAME_AND_PREFIX}
|
||||||
|
MENU_HEADER_SPACING_COUNT=$(( "80" - "$CURRENT_CONFIG_NAME_CHARCOUNT" - "$APP_AND_VERSION_CHARCOUNT" ))
|
||||||
|
MENU_HEADER_SPACING=""
|
||||||
|
for (( i = 0; i < MENU_HEADER_SPACING_COUNT; i++ )); do
|
||||||
|
MENU_HEADER_SPACING="${MENU_HEADER_SPACING} "
|
||||||
|
done
|
||||||
|
|
||||||
|
# Render
|
||||||
|
echo -e "";
|
||||||
|
echo -e "";
|
||||||
|
echo -e "${FONT_BOLD}${APP_AND_VERSION_PREFIX}${MENU_HEADER_SPACING}${COLOR_RED}${CURRENT_CONFIG_NAME_AND_PREFIX}${FONT_DEFAULT}"
|
||||||
|
render_horizontal_rule
|
||||||
|
echo "";
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Render Main Menu - Streaming Commands
|
||||||
|
echo -e " ${FONT_BOLD}${COLOR_DARK_GRAY}STREAM ALSA:${COLOR_DEFAULT}${FONT_DEFAULT} ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}L${FONT_DEFAULT}${COLOR_DEFAULT} - stream ALSA/live (to Main) ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}l${FONT_DEFAULT}${COLOR_DEFAULT} - stream ALSA/live (to Testing) ";
|
||||||
|
echo -e "";
|
||||||
|
|
||||||
|
|
||||||
|
# Render Main Menu - Broadcast Commands
|
||||||
|
echo -e " ${FONT_BOLD}${COLOR_DARK_GRAY}STREAM FILES:${COLOR_DEFAULT}${FONT_DEFAULT} ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}F${FONT_DEFAULT}${COLOR_DEFAULT} - stream files (to Main) ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}f${FONT_DEFAULT}${COLOR_DEFAULT} - stream files (to Testing) ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}V${FONT_DEFAULT}${COLOR_DEFAULT} - playlist view ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}C${FONT_DEFAULT}${COLOR_DEFAULT} - playlist create ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}E${FONT_DEFAULT}${COLOR_DEFAULT} - playlist edit ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}Q${FONT_DEFAULT}${COLOR_DEFAULT} - queued folder contents ";
|
||||||
|
echo -e "";
|
||||||
|
|
||||||
|
# Render Main Menu - Cron
|
||||||
|
echo -e " ${FONT_BOLD}${COLOR_DARK_GRAY}CRON${COLOR_DEFAULT}${FONT_DEFAULT} ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}S${FONT_DEFAULT}${COLOR_DEFAULT} - cron status ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}A${FONT_DEFAULT}${COLOR_DEFAULT} - cron activate ";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}D${FONT_DEFAULT}${COLOR_DEFAULT} - cron deactivate ";
|
||||||
|
echo -e "";
|
||||||
|
|
||||||
|
# Render Main Menu - System
|
||||||
|
echo -e " ${COLOR_DARK_GRAY}${FONT_BOLD}SYSTEM${FONT_DEFAULT}${COLOR_DEFAULT}";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}K${FONT_DEFAULT}${COLOR_DEFAULT} - killall and restart liquidsoap";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}J${FONT_DEFAULT}${COLOR_DEFAULT} - config profile options";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}H${FONT_DEFAULT}${COLOR_DEFAULT} - review hardware audio frame size";
|
||||||
|
echo -e " ${COLOR_LIGHT_MAGENTA}${FONT_BOLD}M${FONT_DEFAULT}${COLOR_DEFAULT} - alsa mixer";
|
||||||
|
echo -e "";
|
||||||
|
echo -e "";
|
||||||
|
echo -e "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Process input variable
|
||||||
|
function process_input_variable() {
|
||||||
|
|
||||||
|
# Case Switch
|
||||||
|
case $INPUTCOMMAND in
|
||||||
|
|
||||||
|
# SHOW COMMANDS:
|
||||||
|
|
||||||
|
# LIVE-STREAMING
|
||||||
|
|
||||||
|
# (L) ---- main, stream live/alsa
|
||||||
|
L) source "${APPLICATION_ROOT}/scripts/streaming/main/main-stream_live_alsa" ;;
|
||||||
|
# (l) ---- testing, stream live/alsa
|
||||||
|
l) source "${APPLICATION_ROOT}/scripts/streaming/testing/testing-stream_live_alsa" ;;
|
||||||
|
|
||||||
|
|
||||||
|
# FILE-STREAMING
|
||||||
|
|
||||||
|
# (F) ---- main, stream files
|
||||||
|
F) source "${APPLICATION_ROOT}/scripts/streaming/main/main-stream_files" ;;
|
||||||
|
# (f) ---- testing, stream files
|
||||||
|
f) source "${APPLICATION_ROOT}/scripts/streaming/testing/testing-stream_files" ;;
|
||||||
|
# (V) ---- main, playlist view
|
||||||
|
V) source "${APPLICATION_ROOT}/scripts/playlist/playlist_view" ;;
|
||||||
|
# (C) ---- main, playlist create
|
||||||
|
C) source "${APPLICATION_ROOT}/scripts/playlist/playlist_create" ;;
|
||||||
|
# (E) ---- main, playlist edit
|
||||||
|
E) source "${APPLICATION_ROOT}/scripts/playlist/playlist_edit" ;;
|
||||||
|
# (Q) ---- main, queued folder contents
|
||||||
|
Q) source "${APPLICATION_ROOT}/scripts/queued/queued_folder_contents" ;;
|
||||||
|
|
||||||
|
# CRON
|
||||||
|
|
||||||
|
# (S) ---- cron status
|
||||||
|
S) source "${APPLICATION_ROOT}/scripts/cron/main-cron_status" ;;
|
||||||
|
# (A) ---- cron activate
|
||||||
|
A) source "${APPLICATION_ROOT}/scripts/cron/main-cron_activate" ;;
|
||||||
|
# (D) ---- cron deactivate
|
||||||
|
D) source "${APPLICATION_ROOT}/scripts/cron/main-cron_deactivate" ;;
|
||||||
|
|
||||||
|
|
||||||
|
# SYSTEM COMMANDS
|
||||||
|
|
||||||
|
# (K) ---- killall and restart
|
||||||
|
K) source "${APPLICATION_ROOT}/scripts/system/system-killall_and_restart" ;;
|
||||||
|
# (J) ---- edit config
|
||||||
|
J) source "${APPLICATION_ROOT}/scripts/system/system-config" ;;
|
||||||
|
# (H) ---- review hardware audio frame size
|
||||||
|
H) source "${APPLICATION_ROOT}/scripts/system/system-update_hardware_audio_frame_size" ;;
|
||||||
|
# (M) ---- alsa mixer
|
||||||
|
M) source "${APPLICATION_ROOT}/scripts/system/system-alsa_mixer" ;;
|
||||||
|
|
||||||
|
|
||||||
|
# Fallback if command not recognized
|
||||||
|
*)
|
||||||
|
printf "${COLOR_RED}[-] Command not recognized.${COLOR_DEFAULT}\n"
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Main Program Function
|
||||||
|
function execute_program {
|
||||||
|
|
||||||
|
|
||||||
|
# Check for missing dependencies (if missing, exits)
|
||||||
|
check_for_missing_dependencies
|
||||||
|
|
||||||
|
# Git touch routine to add .gitkeep and create any missing folders
|
||||||
|
git_keep_touch_routine
|
||||||
|
|
||||||
|
# Read Command Input
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
|
||||||
|
# Render Main Menu
|
||||||
|
echo ""
|
||||||
|
render_main_menu
|
||||||
|
|
||||||
|
|
||||||
|
# Read main application input command
|
||||||
|
MENU_NAME=$(echo -e "${COLOR_LIGHT_MAGENTA}[Main Menu]${COLOR_DEFAULT}")
|
||||||
|
read -p "$MENU_NAME Choice? (\"quit\" to exit, RETURN for menu): " INPUTCOMMAND;
|
||||||
|
|
||||||
|
# If "quit" entered
|
||||||
|
if [[ $INPUTCOMMAND == "quit" ]]; then
|
||||||
|
|
||||||
|
|
||||||
|
# Kill, just in case
|
||||||
|
sudo pkill "liquidsoap";
|
||||||
|
|
||||||
|
# Wait and restart liquidsoap, just in case
|
||||||
|
sleep 2
|
||||||
|
sudo systemctl restart liquidsoap
|
||||||
|
|
||||||
|
# Notify of exit
|
||||||
|
printf "${COLOR_GREEN}[quit] Exiting...${COLOR_DEFAULT}\n"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
break
|
||||||
|
|
||||||
|
# If no key entered
|
||||||
|
elif [[ -z $INPUTCOMMAND ]]; then
|
||||||
|
printf "${COLOR_GREEN}[RETURN] Main menu.${COLOR_DEFAULT}\n"
|
||||||
|
echo ""
|
||||||
|
render_main_menu
|
||||||
|
|
||||||
|
# Evaluate Character entered
|
||||||
|
else
|
||||||
|
process_input_variable
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Master execution of program
|
||||||
|
execute_program
|
||||||
|
|
||||||
|
|
||||||
|
# Closing change of permissions on execution of script
|
||||||
|
reset_permissions
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
// CONFIG SETTINGS:
|
||||||
|
// Config Name: "%%%%config_name%%%%"
|
||||||
|
// Creation date: %%%%creation_date%%%%
|
||||||
|
// Last modified: %%%%last_modified%%%%
|
||||||
|
|
||||||
|
|
||||||
|
// Streaming Configuration Settings ("Main" stream)
|
||||||
|
"main_host":"",
|
||||||
|
"main_port":"",
|
||||||
|
"main_user":"",
|
||||||
|
"main_password":"",
|
||||||
|
"main_mount":"",
|
||||||
|
"main_crontab_time":"",
|
||||||
|
"main_metadata_artist":"",
|
||||||
|
"main_metadata_title":"",
|
||||||
|
|
||||||
|
// Streaming Configuration Settings ("Testing" stream)
|
||||||
|
"testing_host":"",
|
||||||
|
"testing_port":"",
|
||||||
|
"testing_user":"",
|
||||||
|
"testing_password":"",
|
||||||
|
"testing_mount":"",
|
||||||
|
"testing_metadata_artist":"",
|
||||||
|
"testing_metadata_title":"",
|
||||||
|
|
||||||
|
// Playlist Configuration
|
||||||
|
"playlist_url":"",
|
||||||
|
"randomize_playlist_files":"false",
|
||||||
|
|
||||||
|
// System Configuration Settings
|
||||||
|
"hardware_audio_frame_size":"3528",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Application Version
|
||||||
|
# Example: 1.2.1
|
||||||
|
VERSION="4.3.2"
|
Loading…
Reference in New Issue