A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys, Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun VPN routing, and a web dashboard to manage it all. Free & open forever to self-host; optional paid hosted services fund it. See PROMISE.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
130 lines
5.8 KiB
Bash
Executable File
130 lines
5.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
appInstallMenu() {
|
|
while true; do
|
|
isHeader "App Categories"
|
|
echo ""
|
|
isNotice "Loading application categories..."
|
|
echo ""
|
|
|
|
local menu_categories=()
|
|
declare -A category_app_data
|
|
|
|
for category_app_dir in "$install_containers_dir"/*/; do
|
|
if [ -d "$category_app_dir" ]; then
|
|
local category_config_file="$category_app_dir/$(basename "$category_app_dir").config"
|
|
|
|
if [ -f "$category_config_file" ]; then
|
|
source "$category_config_file"
|
|
local category_app_name=$(basename "$category_app_dir")
|
|
local category_app_category=$(grep -Po "CFG_${category_app_name^^}_CATEGORY=\"[^\"]*\"" "$category_config_file" 2>/dev/null | sed "s/.*CATEGORY=\"\([^\"]*\)\".*/\1/")
|
|
local category_app_title=$(grep -Po "CFG_${category_app_name^^}_TITLE=\"[^\"]*\"" "$category_config_file" 2>/dev/null | sed "s/.*TITLE=\"\([^\"]*\)\".*/\1/")
|
|
local category_app_description=$(grep -Po "CFG_${category_app_name^^}_DESCRIPTION=\"[^\"]*\"" "$category_config_file" 2>/dev/null | sed "s/.*DESCRIPTION=\"\([^\"]*\)\".*/\1/")
|
|
|
|
if [ -n "$category_app_name" ] && [ -n "$category_app_category" ]; then
|
|
if [[ ! " ${menu_categories[@]} " =~ " ${category_app_category} " ]]; then
|
|
menu_categories+=("$category_app_category")
|
|
fi
|
|
|
|
local actions_var="CFG_${category_app_name^^}_ACTIONS"
|
|
local available_actions="${!actions_var}"
|
|
category_app_data["$category_app_name"]="$category_app_category|$category_app_title|$category_app_description|$available_actions"
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
IFS=$'\n' sorted_menu_categories=($(sort <<<"${menu_categories[*]}"))
|
|
unset IFS
|
|
|
|
for i in "${!sorted_menu_categories[@]}"; do
|
|
local capitalized_category=$(echo "${sorted_menu_categories[$i]}" | awk '{print toupper(substr($0, 1, 1)) tolower(substr($0, 2))}')
|
|
isOption "$((i + 1)). ${capitalized_category}"
|
|
done
|
|
echo ""
|
|
isOption "x. Exit"
|
|
echo ""
|
|
isQuestion "Please select an option (1-${#sorted_menu_categories[@]} or 'x' to exit): "
|
|
read -p "" choice
|
|
|
|
if [[ "$choice" =~ ^[1-9][0-9]*$ ]] && [ "$choice" -le "${#sorted_menu_categories[@]}" ]; then
|
|
local selected_category="${sorted_menu_categories[$((choice - 1))]}"
|
|
local capitalized_category=$(echo "${selected_category}" | awk '{print toupper(substr($0, 1, 1)) tolower(substr($0, 2))}')
|
|
showInstructions;
|
|
isHeader "${capitalized_category}"
|
|
|
|
local app_list=()
|
|
local user_actions=() # Store user inputs for each app
|
|
|
|
# Build app list from stored app_data (no file reading!)
|
|
for category_app_name in "${!category_app_data[@]}"; do
|
|
local stored_data="${category_app_data[$category_app_name]}"
|
|
IFS='|' read -r category_app_category category_app_title category_app_description actions <<< "$stored_data"
|
|
|
|
if [[ "$category_app_category" == "$selected_category" ]]; then
|
|
app_list+=("$category_app_name:$category_app_title:$category_app_description:$actions")
|
|
fi
|
|
done
|
|
|
|
if [ ${#app_list[@]} -eq 0 ]; then
|
|
isNotice "No applications found in category '$selected_category'!"
|
|
continue
|
|
fi
|
|
|
|
# Show each app on single line and collect input
|
|
for app_entry in "${app_list[@]}"; do
|
|
IFS=':' read -r app_name title description actions <<< "$app_entry"
|
|
|
|
# Extract first letters from actions and format with commas
|
|
actions_display=$(echo "$actions" | tr '|' '\n' | cut -c1 | paste -sd, - | sed 's/,$//')
|
|
|
|
isQuestion "$title - $description [$actions_display] : "
|
|
read -p "" app_input
|
|
|
|
if [ -n "$app_input" ]; then
|
|
user_actions+=("$app_name:$app_input")
|
|
fi
|
|
done
|
|
|
|
if [ ${#user_actions[@]} -gt 0 ]; then
|
|
echo ""
|
|
isNotice "Processing actions..."
|
|
for action_pair in "${user_actions[@]}"; do
|
|
IFS=':' read -r app_name user_input <<< "$action_pair"
|
|
|
|
if [ -z "$app_name" ] || [ -z "$user_input" ]; then
|
|
continue
|
|
fi
|
|
|
|
isNotice "Processing app: $app_name with actions: $user_input"
|
|
|
|
# Set app variable with complete user input
|
|
declare -g "${app_name}=${user_input}"
|
|
|
|
# Call install function once with all actions
|
|
local install_func="install${app_name^}"
|
|
|
|
if declare -f "$install_func" > /dev/null; then
|
|
"$install_func"
|
|
else
|
|
isNotice "Warning: Function '$install_func' not found."
|
|
fi
|
|
|
|
# Clean up after execution
|
|
unset "${app_name}"
|
|
done
|
|
|
|
endStart
|
|
else
|
|
isNotice "No actions entered."
|
|
fi
|
|
|
|
elif [[ "$choice" == "x" ]]; then
|
|
isNotice "Exiting..."
|
|
else
|
|
isNotice "Invalid selection. Please choose a valid category or 'x' to exit."
|
|
fi
|
|
|
|
done
|
|
}
|