diff --git a/README.md b/README.md
index 0dd988e38..9d461211c 100644
--- a/README.md
+++ b/README.md
@@ -1,492 +1,49 @@
-
# Armbian Configuration Utility
-Updated: Wed 31 Jul 2024 23:44:46 NZST
-
-Utility for configuring your board, adjusting services, and installing applications. It comes with Armbian by default.
-
-To start the Armbian configuration utility, use the following command:
-~~~
-sudo armbian-config
-~~~
-
-- ## **System**
- - **S01** - Enable Armbian kernel upgrades
- - **S02** - Disable Armbian kernel upgrades
- - **S03** - Edit the boot environment (WIP)
- - **S04** - Install Linux headers
- - **S05** - Remove Linux headers
-
-
-- ## **Network**
- - **N00** - Install Bluetooth support
- - **N01** - Remove Bluetooth support
- - **N02** - Bluetooth Discover
- - **N03** - Install Infrared support
- - **N04** - Uninstall Infrared support
- - **N05** - Manage wifi network connections
- - **N06** - Advanced Edit /etc/network/interface
- - **N07** - Disconnect and forget all wifi connections (Advanced)
- - **N08** - Toggle system IPv6/IPv4 internet protocol
- - **N09** - (WIP) Setup Hotspot/Access point
-
-
-- ## **Localisation**
- - **L00** - Change Global timezone (WIP)
- - **L01** - Change Locales reconfigure the language and character set
- - **L02** - Change Keyboard layout
- - **L03** - Change APT mirrors
-
-
-- ## **Software**
- - **I00** - Update Application Repository
- - **I01** - CLI System Monitor
-
+Utility for configuring your board, adjusting services, and installing applications.
-- ## **Help**
- - **H00** - About This system. (WIP)
- - **H02** - List of Config function(WIP)
-
-## Install
-Armbian installation
-~~~
-sudo apt install armbian-config
-~~~
-
-3rd party Debian based distributions
-~~~
-{
- sudo wget https://apt.armbian.com/armbian.key -O key
- sudo gpg --dearmor < key | sudo tee /usr/share/keyrings/armbian.gpg > /dev/null
- sudo chmod go+r /usr/share/keyrings/armbian.gpg
- sudo echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/armbian.gpg] http://apt.armbian.com $(lsb_release -cs) main $(lsb_release -cs)-utils $(lsb_release -cs)-desktop" | sudo tee /etc/apt/sources.list.d/armbian.list
- sudo apt update
- sudo apt install armbian-config
-}
-~~~
-
-***
-
-## CLI options
-Command line options.
-
-Use:
-~~~
-armbian-config --help
-~~~
-
-Outputs:
-~~~
-Usage: armbian-configng [option] [arguments]
+Armbian-configng User selection is divided into four main sections:
+- **System**: System and security settings.
+- **Network**: Wired, wireless, Bluetooth, access point.
+- **Localisation**: Timezone, language, hostname.
+- **Software**: System and third-party software install.
- --help - Display this help message.
- main=Help - Display Legacy Options (Backward Compatible)
-
- --cli S01 - Enable Armbian kernel upgrades
- --cli S02 - Disable Armbian kernel upgrades
- --cli S03 - Edit the boot environment (WIP)
- --cli S04 - Install Linux headers
- --cli S05 - Remove Linux headers
- --cli N00 - Install Bluetooth support
- --cli N01 - Remove Bluetooth support
- --cli N02 - Bluetooth Discover
- --cli N03 - Install Infrared support
- --cli N04 - Uninstall Infrared support
- --cli N05 - Manage wifi network connections
- --cli N06 - Advanced Edit /etc/network/interface
- --cli N07 - Disconnect and forget all wifi connections (Advanced)
- --cli N08 - Toggle system IPv6/IPv4 internet protocol
- --cli N09 - (WIP) Setup Hotspot/Access point
- --cli L00 - Change Global timezone (WIP)
- --cli L01 - Change Locales reconfigure the language and character set
- --cli L02 - Change Keyboard layout
- --cli L03 - Change APT mirrors
- --cli I00 - Update Application Repository
- --cli I01 - CLI System Monitor
-~~~
-
-## Legacy options
-Backward Compatible options.
-
-Use:
-~~~
-armbian-config main=Help
-~~~
-
-Outputs:
-~~~
-Legacy Options (Backward Compatible)
-Please use 'armbian-config --help' for more information.
-
-Usage: armbian-configng main=[arguments] selection=[options]
-
- armbian-configng main=System selection=Headers - Install headers:
- armbian-configng main=System selection=Headers_remove - Remove headers:
-~~~
-
-***
-
-## Development
+### Development
Development is divided into three sections:
-
-Click for more info:
-
-
-Jobs / JSON Object
-
-A list of the jobs defined in the Jobs file.
-
- ### S01
-
-Enable Armbian kernel upgrades
-
-Jobs:
-
-~~~
-set_safe_boot unhold
-~~~
-
-### S02
-
-Disable Armbian kernel upgrades
-
-Jobs:
-
-~~~
-set_safe_boot freeze
-~~~
-
-### S03
-
-Edit the boot environment (WIP)
-
-Jobs:
-
-~~~
-get_user_continue "This will open /boot/armbianEnv.txt file to edit
-CTRL+S to save
-CTLR+X to exit
-would you like to continue?" process_input
-nano /boot/armbianEnv.txt
-~~~
-
-### S04
-
-Install Linux headers
-
-Jobs:
-
-~~~
-Headers_install
-~~~
-
-### S05
-
-Remove Linux headers
-
-Jobs:
-
-~~~
-Headers_remove
-~~~
-
-### N00
-
-Install Bluetooth support
-
-Jobs:
-
-~~~
-see_current_apt
-debconf-apt-progress -- apt-get -y install bluetooth bluez bluez-tools
-check_if_installed xserver-xorg && debconf-apt-progress -- apt-get -y --no-install-recommends install pulseaudio-module-bluetooth blueman
-~~~
-
-### N01
-
-Remove Bluetooth support
-
-Jobs:
-
-~~~
-see_current_apt
-debconf-apt-progress -- apt-get -y remove bluetooth bluez bluez-tools
-check_if_installed xserver-xorg && debconf-apt-progress -- apt-get -y remove pulseaudio-module-bluetooth blueman
-debconf-apt-progress -- apt -y -qq autoremove
-~~~
-
-### N02
-
-Bluetooth Discover
-
-Jobs:
-
-~~~
-get_user_continue "Verify that your Bluetooth device is discoverable!" process_input ; connect_bt_interface
-~~~
-
-### N03
-
-Install Infrared support
-
-Jobs:
-
-~~~
-see_current_apt; debconf-apt-progress -- apt-get -y --no-install-recommends install lirc
-~~~
-
-### N04
-
-Uninstall Infrared support
-
-Jobs:
-
-~~~
-see_current_apt; debconf-apt-progress -- apt-get -y --no-install-recommends install lirc
-~~~
-
-### N05
-
-Manage wifi network connections
-
-Jobs:
-
-~~~
-nmtui connect
-~~~
-
-### N06
-
-Advanced Edit /etc/network/interface
-
-Jobs:
-
-~~~
-get_user_continue "This will open interface file to edit
-CTRL+S to save
-CTLR+X to exit
-would you like to continue?" process_input
-nano /etc/network/interfaces
-~~~
-
-### N07
-
-Disconnect and forget all wifi connections (Advanced)
-
-Jobs:
-
-~~~
-get_user_continue "Disconnect and forget all wifi connections
-Would you like to continue?" process_input
-LC_ALL=C nmcli --fields UUID,TIMESTAMP-REAL,TYPE con show | grep wifi | awk '{print $1}' | while read line; \
-do nmcli con delete uuid $line; done > /dev/null
-~~~
-
-### N08
-
-Toggle system IPv6/IPv4 internet protocol
-
-Jobs:
-
-~~~
-get_user_continue "This will toggle your internet protocol
-Would you like to continue?" process_input
-toggle_ipv6 | show_infobox
-~~~
-
-### N09
-
-(WIP) Setup Hotspot/Access point
-
-Jobs:
-
-~~~
-get_user_continue "This operation will install necessary software and add configuration files.
-Do you wish to continue?" process_input
-hotspot_setup
-~~~
-
-### L00
-
-Change Global timezone (WIP)
-
-Jobs:
-
-~~~
-dpkg-reconfigure tzdata
-~~~
-
-### L01
-
-Change Locales reconfigure the language and character set
-
-Jobs:
-
-~~~
-dpkg-reconfigure locales
-source /etc/default/locale ; sed -i "s/^LANGUAGE=.*/LANGUAGE=$LANG/" /etc/default/locale
-export LANGUAGE=$LANG
-~~~
-
-### L02
-
-Change Keyboard layout
-
-Jobs:
-
-~~~
-dpkg-reconfigure keyboard-configuration ; setupcon
-~~~
-
-### L03
-
-Change APT mirrors
-
-Jobs:
-
-~~~
-get_user_continue "This is only a frontend test" process_input
-~~~
-
-### I00
-
-Update Application Repository
-
-Jobs:
-
-~~~
-get_user_continue "This will update apt" process_input
-debconf-apt-progress -- apt update
-~~~
-
-### I01
-
-CLI System Monitor
-
-Jobs:
-
-~~~
-armbianmonitor -m | show_infobox
-~~~
-
-### H00
-
-About This system. (WIP)
-
-Jobs:
-
-~~~
-show_message <<< "This app is to help execute procedures to configure your system
-
-Some options may not work on manually modified systems"
-~~~
-
-### H02
-
-List of Config function(WIP)
-
-Jobs:
-
-~~~
-show_message <<< see_use
-~~~
-
-
-
-
-
-Jobs API / Helper Functions
-
-These helper functions facilitate various operations related to job management, such as creation, updating, deletion, and listing of jobs, acting as a practical API for developers.
-
-| Description | Example | Credit |
-|:----------- | ------- |:------:|
-| Generate a Help message legacy cli commands. | see_cli_legacy | Joey Turner
-| Run time variables Migrated procedures from Armbian config. | set_runtime_variables | Igor Pecovnik
-| Generate this markdown table of all module_options | see_function_table_md | Joey Turner
-| Display a menu from pipe | show_menu <<< armbianmonitor -h ; | Joey Turner
-| Build the main menu from a object | generate_top_menu 'json_data' | Joey Turner
-| Migrated procedures from Armbian config. | is_package_manager_running | Igor Pecovnik
-| Migrated procedures from Armbian config. | check_desktop | Igor Pecovnik
-| Generate Document files. | generate_readme | Joey Turner
-| Needed by generate_menu | | Joey Turner
-| Display a Yes/No dialog box and process continue/exit | get_user_continue 'Do you wish to continue?' process_input | Joey Turner
-| Display a message box | show_message <<< 'hello world' | Joey Turner
-| Migrated procedures from Armbian config. | connect_bt_interface | Igor Pecovnik
-| Freeze/unhold Migrated procedures from Armbian config. | set_safe_boot unhold or set_safe_boot freeze | Igor Pecovnik
-| Check when apt list was last updated | see_current_apt | Joey Turner
-| Migrated procedures from Armbian config. | check_if_installed nano | Igor Pecovnik
-| Generate 'Armbian CPU logo' SVG for document file. | generate_svg | Joey Turner
-| Remove Linux headers | Headers_remove | Joey Turner
-| Show or hide menu items based on conditions | toggle_menu_item | Joey Turner
-| Update submenu descriptions based on conditions | update_submenu_data | Joey Turner
-| sanitize input cli | sanitize_input |
-| Check if a domain is reachable via IPv4 and IPv6 | check_ip_version google.com | Joey Turner
-| Migrated procedures from Armbian config. | set_header_remove | Igor Pecovnik
-| Generate a submenu from a parent_id | generate_menu 'parent_id' | Joey Turner
-| Generate a markdown list json objects using jq. | see_jq_menu_list | Joey Turner
-| Generate jobs from JSON file. | generate_jobs_from_json | Joey Turner
-| Install kernel headers | is_package_manager_running | Joey Turner
-| Set up a WiFi hotspot on the device | hotspot_setup | Joey Turner
-| Toggle IPv6 on or off | toggle_ipv6 | Joey Turner
-| Generate a Help message for cli commands. | see_cli_list | Joey Turner
-| Generate JSON-like object file. | generate_json | Joey Turner
-| Change the background color of the terminal or dialog box | set_colors 0-7 | Joey Turner
-| Serve the edit and debug server. | serve_doc | Joey Turner
-| Update JSON data with system information | update_json_data | Joey Turner
-| pipeline strings to an infobox | show_infobox <<< 'hello world' ; | Joey Turner
-| Show the usage of the functions. | see_use | Joey Turner
-| Check the internet connection with fallback DNS | see_ping | Joey Turner
-| Secure version of get_user_continue | get_user_continue_secure 'Do you wish to continue?' process_input | Joey Turner
-
-
-
-
-
-
-Runtime / Board Statuses
-
-(WIP)
-
-This section outlines the runtime environment to check configurations and statuses for dynamically managing jobs based on JSON data.
-
-(WIP)
-
-
-
-
-## Testing and contributing
-
-
-Get Development
-
-Install the dependencies:
-~~~
+- **Jobs - JSON Object**
+ - Defines various tasks and their parameters in a JSON file.
+ - Location: `lib/armbian-configng/config.ng.jobs.json`
+- **Helpers - Bash Functions**
+ - Contains reusable Bash functions to support various operations.
+ - Core functions: `lib/armbian-configng/config.ng.functions.sh`
+ - Documentation functions: `lib/armbian-configng/config.ng.docs.sh`
+ - Network functions: `lib/armbian-configng/config.ng.network.sh`
+- **Runtime - Board Statuses**
+ - Utilizes [jq](https://stedolan.github.io/jq/) (a lightweight and flexible command-line JSON processor) job definitions to monitor and manage board statuses.
+ - Location: `lib/armbian-configng/config.ng.jobs.json`
+
+## Testing and Contributing
+
+### Development
+
+**Git Development and Contribution:**
+~~~bash
+git clone https://github.com/armbian/configng
+cd configng
+./armbian-configng --help
+~~~
+
+**Install the dependencies:**
+~~~bash
sudo apt install git jq whiptail
~~~
-Get Development and contribute:
-~~~
-{
- git clone https://github.com/armbian/configng
- cd configng
- ./armbian-configng --help
-}
-~~~
-
-Install and test Development deb:
-~~~
-{
- sudo apt install whiptail
- latest_release=$(curl -s https://api.github.com/repos/armbian/configng/releases/latest)
- deb_url=$(echo "$latest_release" | jq -r '.assets[] | select(.name | endswith(".deb")) | .browser_download_url')
- curl -LO "$deb_url"
- deb_file=$(echo "$deb_url" | awk -F"/" '{print $NF}')
- sudo dpkg -i "$deb_file"
- sudo dpkg --configure -a
- sudo apt --fix-broken install
-}
+**Make changes, test, and update documents:**
+(Note: `sudo` is not used for development.)
+~~~bash
+armbian-configng --doc
~~~
-
+### Tools
+Included is a module generator located at `tools/index.html`. For more details, refer to the [README in the tools directory](./tools/README.md).
\ No newline at end of file
diff --git a/User-Guide_Armbian-ConfigNG.md b/User-Guide_Armbian-ConfigNG.md
new file mode 100644
index 000000000..45f063883
--- /dev/null
+++ b/User-Guide_Armbian-ConfigNG.md
@@ -0,0 +1,140 @@
+
+# Armbian Configuration Utility
+Utility for configuring your board, adjusting services, and installing applications.
+
+## Sections
+Armbian-configng is divided into four main sections:
+- System - system and security settings,
+- Network - wired, wireless, Bluetooth, access point,
+- Localisation - timezone, language, hostname,
+- Software - system and 3rd party software install.
+
+## Install latest release
+~~~
+{
+ sudo apt install whiptail
+ latest_release=$(curl -s https://api.github.com/repos/armbian/configng/releases/latest)
+ deb_url=$(echo "$latest_release" | jq -r '.assets[] | select(.name | endswith(".deb")) | .browser_download_url')
+ curl -LO "$deb_url"
+ deb_file=$(echo "$deb_url" | awk -F"/" '{print $NF}')
+ sudo dpkg -i "$deb_file"
+ sudo dpkg --configure -a
+ sudo apt --fix-broken install
+}
+~~~
+
+Armbian_config requires root privilege. To start the Armbian configuration utility, use the following sudo "super user do" command:
+~~~
+sudo armbian-configng
+~~~
+
+## list of features
+Updated: Thu Aug 8 11:47:36 PM EDT 2024
+
+- ### **System**
+ - **S01** - Enable Armbian kernel upgrades
+ - **S02** - Disable Armbian kernel upgrades
+ - **S03** - Edit the boot environment
+ - **S04** - Install Linux headers
+ - **S05** - Remove Linux headers
+
+
+- ### **Network**
+ - **N00** - Install Bluetooth support
+ - **N01** - Remove Bluetooth support
+ - **N02** - Bluetooth Discover
+ - **N03** - Install Infrared support
+ - **N04** - Uninstall Infrared support
+ - **N05** - Manage wifi network connections
+ - **N06** - Advanced Edit /etc/network/interface
+ - **N07** - Disconnect and forget all wifi connections (Advanced)
+ - **N08** - Toggle system IPv6/IPv4 internet protocol
+ - **N09** - (WIP) Setup Hotspot/Access point
+ - **N10** - Announce system in the network (Avahi)
+ - **N11** - Disable system announce in the network (Avahi)
+
+
+- ### **Localisation**
+ - **L00** - Change Global timezone (WIP)
+ - **L01** - Change Locales reconfigure the language and character set
+ - **L02** - Change Keyboard layout
+ - **L03** - Change APT mirrors
+
+
+- ### **Software**
+ - **I00** - Update Application Repository
+ - **I01** - CLI System Monitor
+
+
+- ### **Help**
+ - **H00** - About This system. (WIP)
+ - **H02** - List of Config function(WIP)
+
+
+***
+
+## CLI options
+Command line options.
+
+Use:
+~~~
+armbian-configng --help
+~~~
+
+Outputs:
+~~~
+Usage: armbian-configng [option] [arguments]
+
+ --help - Display this help message.
+ main=Help - Display Legacy Options (Backward Compatible)
+
+ --cli S01 - Enable Armbian kernel upgrades
+ --cli S02 - Disable Armbian kernel upgrades
+ --cli S03 - Edit the boot environment
+ --cli S04 - Install Linux headers
+ --cli S05 - Remove Linux headers
+ --cli N00 - Install Bluetooth support
+ --cli N01 - Remove Bluetooth support
+ --cli N02 - Bluetooth Discover
+ --cli N03 - Install Infrared support
+ --cli N04 - Uninstall Infrared support
+ --cli N05 - Manage wifi network connections
+ --cli N06 - Advanced Edit /etc/network/interface
+ --cli N07 - Disconnect and forget all wifi connections (Advanced)
+ --cli N08 - Toggle system IPv6/IPv4 internet protocol
+ --cli N09 - (WIP) Setup Hotspot/Access point
+ --cli N10 - Announce system in the network (Avahi)
+ --cli N11 - Disable system announce in the network (Avahi)
+ --cli L00 - Change Global timezone (WIP)
+ --cli L01 - Change Locales reconfigure the language and character set
+ --cli L02 - Change Keyboard layout
+ --cli L03 - Change APT mirrors
+ --cli I00 - Update Application Repository
+ --cli I01 - CLI System Monitor
+~~~
+
+## Legacy options
+Backward Compatible options.
+
+Use:
+~~~
+armbian-configng main=Help
+~~~
+
+Outputs:
+~~~
+Legacy Options (Backward Compatible)
+Please use 'armbian-configng --help' for more information.
+
+Usage: armbian-configng main=[arguments] selection=[options]
+
+ armbian-configng main=System selection=Headers - Install headers:
+ armbian-configng main=System selection=Headers_remove - Remove headers:
+~~~
+
+***
+
+Sources
+
+https://github.com/armbian/configng
+
diff --git a/lib/armbian-configng/config.ng.docs.sh b/lib/armbian-configng/config.ng.docs.sh
index 5237762ad..b816149e0 100644
--- a/lib/armbian-configng/config.ng.docs.sh
+++ b/lib/armbian-configng/config.ng.docs.sh
@@ -25,37 +25,42 @@ function generate_readme() {
echo -e "Sorting data\nUpdating documentation" # current_date ;
-cat << EOF > "$script_dir/../README.md"
+cat << EOF > "$script_dir/../User-Guide_Armbian-ConfigNG.md"
# Armbian Configuration Utility
-Updated: $current_date
+Utility for configuring your board, adjusting services, and installing applications.
-Utility for configuring your board, adjusting services, and installing applications. It comes with Armbian by default.
+## Sections
+Armbian-configng is divided into four main sections:
+- System - system and security settings,
+- Network - wired, wireless, Bluetooth, access point,
+- Localisation - timezone, language, hostname,
+- Software - system and 3rd party software install.
-To start the Armbian configuration utility, use the following command:
+## Install latest release
~~~
-sudo armbian-config
+{
+ sudo apt install whiptail
+ latest_release=\$(curl -s https://api.github.com/repos/armbian/configng/releases/latest)
+ deb_url=\$(echo "\$latest_release" | jq -r '.assets[] | select(.name | endswith(".deb")) | .browser_download_url')
+ curl -LO "\$deb_url"
+ deb_file=\$(echo "\$deb_url" | awk -F"/" '{print \$NF}')
+ sudo dpkg -i "\$deb_file"
+ sudo dpkg --configure -a
+ sudo apt --fix-broken install
+}
~~~
-$(see_full_list)
-
-## Install
-Armbian installation
+Armbian_config requires root privilege. To start the Armbian configuration utility, use the following sudo "super user do" command:
~~~
-sudo apt install armbian-config
+sudo armbian-configng
~~~
-3rd party Debian based distributions
-~~~
-{
- sudo wget https://apt.armbian.com/armbian.key -O key
- sudo gpg --dearmor < key | sudo tee /usr/share/keyrings/armbian.gpg > /dev/null
- sudo chmod go+r /usr/share/keyrings/armbian.gpg
- sudo echo "deb [arch=\$(dpkg --print-architecture) signed-by=/usr/share/keyrings/armbian.gpg] http://apt.armbian.com \$(lsb_release -cs) main \$(lsb_release -cs)-utils \$(lsb_release -cs)-desktop" | sudo tee /etc/apt/sources.list.d/armbian.list
- sudo apt update
- sudo apt install armbian-config
-}
-~~~
+## list of features
+Updated: $current_date
+
+$(see_full_list)
+
***
@@ -64,7 +69,7 @@ Command line options.
Use:
~~~
-armbian-config --help
+armbian-configng --help
~~~
Outputs:
@@ -77,7 +82,7 @@ Backward Compatible options.
Use:
~~~
-armbian-config main=Help
+armbian-configng main=Help
~~~
Outputs:
@@ -87,81 +92,13 @@ $(see_cli_legacy)
***
-## Development
-
-Development is divided into three sections:
-
-Click for more info:
-
-
-Jobs / JSON Object
-
-A list of the jobs defined in the Jobs file.
-
- $(see_jq_menu_list)
-
-
-
-
-
-Jobs API / Helper Functions
-
-These helper functions facilitate various operations related to job management, such as creation, updating, deletion, and listing of jobs, acting as a practical API for developers.
-
-$(see_function_table_md)
-
+Sources
-
+https://github.com/armbian/configng
+EOF
-
-Runtime / Board Statuses
-
-(WIP)
-
-This section outlines the runtime environment to check configurations and statuses for dynamically managing jobs based on JSON data.
-
-(WIP)
-
-
-
-
-## Testing and contributing
-
-
-Get Development
-
-Install the dependencies:
-~~~
-sudo apt install git jq whiptail
-~~~
-
-Get Development and contribute:
-~~~
-{
- git clone https://github.com/armbian/configng
- cd configng
- ./armbian-configng --help
-}
-~~~
-
-Install and test Development deb:
-~~~
-{
- sudo apt install whiptail
- latest_release=\$(curl -s https://api.github.com/repos/armbian/configng/releases/latest)
- deb_url=\$(echo "\$latest_release" | jq -r '.assets[] | select(.name | endswith(".deb")) | .browser_download_url')
- curl -LO "\$deb_url"
- deb_file=\$(echo "\$deb_url" | awk -F"/" '{print \$NF}')
- sudo dpkg -i "\$deb_file"
- sudo dpkg --configure -a
- sudo apt --fix-broken install
-}
-~~~
-
-
-EOF
}
@@ -375,7 +312,7 @@ function see_full_list() {
cat=$(jq -r ".menu[$i].id" "$json_file")
description=$(jq -r ".menu[$i].description" "$json_file")
- echo -e "- ## **$cat** "
+ echo -e "- ### **$cat** "
#echo "$description"
sub_items=$(jq -r ".menu[$i].sub | length" "$json_file")
@@ -507,7 +444,7 @@ function see_cli_legacy() {
local script_name=$(basename "$0")
cat << EOF
Legacy Options (Backward Compatible)
-Please use 'armbian-config --help' for more information.
+Please use 'armbian-configng --help' for more information.
Usage: $script_name main=[arguments] selection=[options]
diff --git a/lib/armbian-configng/config.ng.gui.sh b/lib/armbian-configng/config.ng.gui.sh
new file mode 100644
index 000000000..987e622a5
--- /dev/null
+++ b/lib/armbian-configng/config.ng.gui.sh
@@ -0,0 +1,399 @@
+#!/bin/bash
+
+
+
+
+# Start of config ng
+
+module_options+=(
+["set_colors,author"]="Joey Turner"
+["set_colors,ref_link"]=""
+["set_colors,feature"]="set_colors"
+["set_colors,desc"]="Change the background color of the terminal or dialog box"
+["set_colors,example"]="set_colors 0-7"
+["set_colors,doc_link"]=""
+["set_colors,status"]="Active"
+)
+#
+# Function to set the tui colors
+#
+[[ -x "$(command -v whiptail)" ]] && DIALOG="whiptail" || exit 1 ;
+
+function set_colors() {
+ local color_code=$1
+
+ if [ "$DIALOG" = "whiptail" ]; then
+ set_newt_colors "$color_code"
+ #echo "color code: $color_code" | show_infobox ;
+ elif [ "$DIALOG" = "dialog" ]; then
+ set_term_colors "$color_code"
+ else
+ echo "Invalid dialog type"
+ return 1
+ fi
+}
+
+
+#
+# Function to set the colors for newt
+#
+function set_newt_colors() {
+ local color_code=$1
+ case $color_code in
+ 0) color="black" ;;
+ 1) color="red" ;;
+ 2) color="green" ;;
+ 3) color="yellow" ;;
+ 4) color="blue" ;;
+ 5) color="magenta" ;;
+ 6) color="cyan" ;;
+ 7) color="white" ;;
+ 8) color="black" ;;
+ 9) color="red" ;;
+ *) return ;;
+ esac
+ export NEWT_COLORS="root=,$color"
+}
+
+
+#
+# Function to set the colors for terminal
+#
+function set_term_colors() {
+ local color_code=$1
+ case $color_code in
+ 0) color="\e[40m" ;; # black
+ 1) color="\e[41m" ;; # red
+ 2) color="\e[42m" ;; # green
+ 3) color="\e[43m" ;; # yellow
+ 4) color="\e[44m" ;; # blue
+ 5) color="\e[45m" ;; # magenta
+ 6) color="\e[46m" ;; # cyan
+ 7) color="\e[47m" ;; # white
+ *) echo "Invalid color code"; return 1 ;;
+ esac
+ echo -e "$color"
+}
+
+
+#
+# Function to reset the colors
+#
+function reset_colors() {
+ echo -e "\e[0m"
+}
+
+
+module_options+=(
+["generate_top_menu,author"]="Joey Turner"
+["generate_top_menu,ref_link"]=""
+["generate_top_menu,feature"]="generate_top_menu"
+["generate_top_menu,desc"]="Build the main menu from a object"
+["generate_top_menu,example"]="generate_top_menu 'json_data'"
+["generate_top_menu,doc_link"]=""
+["generate_top_menu,status"]="Active"
+)
+#
+# Function to generate the main menu from a JSON object
+#
+generate_top_menu() {
+ local json_data=$1
+ local menu_options=()
+ while IFS= read -r id
+ do
+ IFS= read -r description
+ IFS= read -r requirements
+ # If the condition field is not empty and not null, run the function specified in the condition
+ if [[ -n $requirements && $requirements != "null" ]]; then
+ local condition_result=$(eval $requirements)
+ # If the function returns a truthy value, add the menu item to the menu
+ if [[ $condition_result ]]; then
+ menu_options+=("$id" " - $description ($something)")
+ fi
+ else
+ # If the condition field is empty or null, add the menu item to the menu
+ menu_options+=("$id" " - $description ")
+ fi
+ done < <(echo "$json_data" | jq -r '.menu[] | select(.show==true) | "\(.id)\n\(.description)\n\(.condition)"' || exit 1 )
+
+ set_colors 4
+
+ local OPTION=$($DIALOG --title "$TITLE" --menu "$BACKTITLE" 0 80 9 "${menu_options[@]}" 3>&1 1>&2 2>&3)
+ local exitstatus=$?
+
+ if [ $exitstatus = 0 ]; then
+ if [ "$OPTION" == "" ]; then
+ exit 0
+ fi
+ [[ -n "$debug" ]] && echo "$OPTION"
+ generate_menu "$OPTION"
+ fi
+
+# echo "Menu options: ${menu_options[@]}"
+
+}
+
+
+module_options+=(
+["generate_menu,author"]="Joey Turner"
+["generate_menu,ref_link"]=""
+["generate_menu,feature"]="generate_menu"
+["generate_menu,desc"]="Generate a submenu from a parent_id"
+["generate_menu,example"]="generate_menu 'parent_id'"
+["generate_menu,doc_link"]=""
+["generate_menu,status"]="Active"
+)
+#
+# Function to generate the submenu
+#
+function generate_menu() {
+ local parent_id=$1
+
+ # Get the submenu options for the current parent_id
+ local submenu_options=()
+ while IFS= read -r id
+ do
+ IFS= read -r description
+ submenu_options+=("$id" " - $description")
+ done < <(jq -r --arg parent_id "$parent_id" '.menu[] | select(.id==$parent_id) | .sub[]? | select(.show==true) | "\(.id)\n\(.description)"' <<< "$json_data")
+
+
+ local OPTION=$($DIALOG --title "$TITLE" --menu "$BACKTITLE" 0 80 9 "${submenu_options[@]}" \
+ --ok-button Select --cancel-button Back 3>&1 1>&2 2>&3)
+
+ local exitstatus=$?
+
+ if [ $exitstatus = 0 ]; then
+ if [ "$OPTION" == "" ]; then
+ generate_top_menu
+ fi
+ # Check if the selected option has a submenu
+ local submenu_count=$(jq -r --arg id "$OPTION" '.menu[] | .. | objects | select(.id==$id) | .sub[]? | length' "$json_file")
+ submenu_count=${submenu_count:-0} # If submenu_count is null or empty, set it to 0
+ if [ "$submenu_count" -gt 0 ]; then
+ # If it does, generate a new menu for the submenu
+ set_colors 2 # "$?"
+ [[ -n "$debug" ]] && echo "$OPTION"
+ generate_menu "$OPTION"
+ else
+ # If it doesn't, execute the command
+ [[ -n "$debug" ]] && echo "$OPTION"
+ execute_command "$OPTION"
+ #show_message <<< "$OPTION"
+ fi
+ fi
+
+ # echo "Submenu options: ${submenu_options[@]}"
+
+}
+
+
+module_options+=(
+["execute_command,author"]="Joey Turner"
+["execute_command,ref_link"]=""
+["execute_command,feature"]="execute_command"
+["execute_command,desc"]="Needed by generate_menu"
+["execute_command,example"]=""
+["execute_command,doc_link"]=""
+["execute_command,status"]="Active"
+)
+#
+# Function to execute the command
+#
+function execute_command() {
+ local id=$1
+ local commands=$(jq -r --arg id "$id" '.menu[] | .. | objects | select(.id==$id) | .command[]' "$json_file")
+ for command in "${commands[@]}"; do
+ # Check if the command is not in the list of restricted commands
+ [[ -n "$debug" ]] && echo "$command"
+ eval "$command"
+ done
+
+}
+
+
+module_options+=(
+["show_message,author"]="Joey Turner"
+["show_message,ref_link"]=""
+["show_message,feature"]="show_message"
+["show_message,desc"]="Display a message box"
+["show_message,example"]="show_message <<< 'hello world' "
+["show_message,doc_link"]=""
+["show_message,status"]="Active"
+)
+#
+# Function to display a message box
+#
+function show_message() {
+ # Read the input from the pipe
+ input=$(cat)
+
+ # Display the "OK" message box with the input data
+ if [[ $DIALOG != "bash" ]]; then
+ $DIALOG --title "$BACKTITLE" --msgbox "$input" 0 0
+ else
+ echo -e "$input"
+ read -p -r "Press [Enter] to continue..."
+ fi
+}
+
+
+module_options+=(
+["show_infobox,author"]="Joey Turner"
+["show_infobox,ref_link"]=""
+["show_infobox,feature"]="show_infobox"
+["show_infobox,desc"]="pipeline strings to an infobox "
+["show_infobox,example"]="show_infobox <<< 'hello world' ; "
+["show_infobox,doc_link"]=""
+["show_infobox,status"]="Active"
+)
+#
+# Function to display an infobox with a message
+#
+function show_infobox() {
+ export TERM=ansi
+ local input
+ local BACKTITLE="$BACKTITLE"
+ local -a buffer # Declare buffer as an array
+ if [ -p /dev/stdin ]; then
+ while IFS= read -r line; do
+ buffer+=("$line") # Add the line to the buffer
+ # If the buffer has more than 10 lines, remove the oldest line
+ if (( ${#buffer[@]} > 18 )); then
+ buffer=("${buffer[@]:1}")
+ fi
+ # Display the lines in the buffer in the infobox
+
+ TERM=ansi $DIALOG --title "$BACKTITLE" --infobox "$(printf "%s\n" "${buffer[@]}" )" 16 90
+ sleep 0.5
+ done
+ else
+
+ input="$1"
+ TERM=ansi $DIALOG --title "$BACKTITLE" --infobox "$input" 6 80
+ fi
+ echo -ne '\033[3J' # clear the screen
+}
+
+
+module_options+=(
+["show_menu,author"]="Joey Turner"
+["show_menu,ref_link"]=""
+["show_menu,feature"]="show_menu"
+["show_menu,desc"]="Display a menu from pipe"
+["show_menu,example"]="show_menu <<< armbianmonitor -h ; "
+["show_menu,doc_link"]=""
+["show_menu,status"]="Active"
+)
+#
+#
+#
+show_menu(){
+
+ # Get the input and convert it into an array of options
+ inpu_raw=$(cat)
+ # Remove the lines before -h
+ input=$(echo "$inpu_raw" | sed 's/-\([a-zA-Z]\)/\1/' | grep '^ [a-zA-Z] ' | grep -v '\[')
+ options=()
+ while read -r line; do
+ package=$(echo "$line" | awk '{print $1}')
+ description=$(echo "$line" | awk '{$1=""; print $0}' | sed 's/^ *//')
+ options+=("$package" "$description")
+ done <<< "$input"
+
+ # Display the menu and get the user's choice
+ [[ $DIALOG != "bash" ]] && choice=$($DIALOG --title "Menu" --menu "Choose an option:" 0 0 9 "${options[@]}" 3>&1 1>&2 2>&3)
+
+ # Check if the user made a choice
+ if [ $? -eq 0 ]; then
+ echo "$choice"
+ else
+ exit 0
+ fi
+
+ }
+
+
+module_options+=(
+["get_user_continue,author"]="Joey Turner"
+["get_user_continue,ref_link"]=""
+["get_user_continue,feature"]="get_user_continue"
+["get_user_continue,desc"]="Display a Yes/No dialog box and process continue/exit"
+["get_user_continue,example"]="get_user_continue 'Do you wish to continue?' process_input"
+["get_user_continue,doc_link"]=""
+["get_user_continue,status"]="Active"
+)
+#
+# Function to display a Yes/No dialog box
+#
+function get_user_continue() {
+ local message="$1"
+ local next_action="$2"
+
+ if $($DIALOG --yesno "$message" 10 80 3>&1 1>&2 2>&3); then
+ $next_action
+ else
+ $next_action "No"
+ fi
+}
+
+
+menu_options+=(
+["get_user_continue,author"]="Joey Turner"
+["get_user_continue,ref_link"]=""
+["get_user_continue,feature"]="process_input"
+["get_user_continue,desc"]="used to process the user's choice paired with get_user_continue"
+["get_user_continue,example"]="get_user_continue 'Do you wish to continue?' process_input"
+["get_user_continue,status"]="Active"
+["get_user_continue,doc_link"]=""
+)
+#
+# Function to process the user's choice paired with get_user_continue
+#
+function process_input() {
+ local input="$1"
+ if [ "$input" = "No" ]; then
+ exit 1
+ fi
+}
+
+
+module_options+=(
+["get_user_continue_secure,author"]="Joey Turner"
+["get_user_continue_secure,ref_link"]=""
+["get_user_continue_secure,feature"]="get_user_continue_secure"
+["get_user_continue_secure,desc"]="Secure version of get_user_continue"
+["get_user_continue_secure,example"]="get_user_continue_secure 'Do you wish to continue?' process_input"
+["get_user_continue_secure,doc_link"]=""
+["get_user_continue_secure,status"]="Active"
+)
+#
+# Secure version of get_user_continue
+#
+function get_user_continue_secure() {
+ local message="$1"
+ local next_action="$2"
+
+ # Define a list of allowed functions
+ local allowed_functions=("process_input" "other_function")
+ # Check if the next_action is in the list of allowed functions
+ found=0
+ for func in "${allowed_functions[@]}"; do
+ if [[ "$func" == "$next_action" ]]; then
+ found=1
+ break
+ fi
+ done
+
+ if [[ "$found" -eq 1 ]]; then
+ if $($DIALOG --yesno "$message" 10 80 3>&1 1>&2 2>&3); then
+ $next_action
+ else
+ $next_action "No"
+ fi
+ else
+ echo "Error: Invalid function"
+
+ exit 1
+ fi
+}
diff --git a/lib/armbian-configng/config.ng.jobs.json b/lib/armbian-configng/config.ng.jobs.json
index 1d6b2390f..e2cbbfd65 100644
--- a/lib/armbian-configng/config.ng.jobs.json
+++ b/lib/armbian-configng/config.ng.jobs.json
@@ -273,7 +273,8 @@
"id": "L02",
"description": "Change Keyboard layout",
"command": [
- "dpkg-reconfigure keyboard-configuration ; setupcon "
+ "dpkg-reconfigure keyboard-configuration ; setupcon ",
+ "update-initramfs -u"
],
"show": true,
"status": "Active",
diff --git a/lib/armbian-configng/config.ng.runtime.sh b/lib/armbian-configng/config.ng.runtime.sh
index 71ca0ba69..f7417ecc5 100644
--- a/lib/armbian-configng/config.ng.runtime.sh
+++ b/lib/armbian-configng/config.ng.runtime.sh
@@ -15,7 +15,7 @@ system_info="$(uname -m)"
locale_setting="$LANG"
installed_software="$(see_current_apt)"
held_packages=$(apt-mark showhold)
-
+network_adapter="$DEFAULT_ADAPTER"
module_options+=(
["update_json_data,author"]="Joey Turner"
@@ -77,9 +77,7 @@ update_json_data "Localisation" "$locale_setting"
update_json_data "Software" "$installed_software"
-#
-# Check if network adapter is IPv6 or IPv4
-network_adapter="$DEFAULT_ADAPTER"
+
# Conditional submenu updates based on network type
if [ "$network_adapter" = "IPv6" ]; then
diff --git a/lib/armbian-configng/config.ng.tui.sh b/lib/armbian-configng/config.ng.tui.sh
new file mode 100644
index 000000000..987e622a5
--- /dev/null
+++ b/lib/armbian-configng/config.ng.tui.sh
@@ -0,0 +1,399 @@
+#!/bin/bash
+
+
+
+
+# Start of config ng
+
+module_options+=(
+["set_colors,author"]="Joey Turner"
+["set_colors,ref_link"]=""
+["set_colors,feature"]="set_colors"
+["set_colors,desc"]="Change the background color of the terminal or dialog box"
+["set_colors,example"]="set_colors 0-7"
+["set_colors,doc_link"]=""
+["set_colors,status"]="Active"
+)
+#
+# Function to set the tui colors
+#
+[[ -x "$(command -v whiptail)" ]] && DIALOG="whiptail" || exit 1 ;
+
+function set_colors() {
+ local color_code=$1
+
+ if [ "$DIALOG" = "whiptail" ]; then
+ set_newt_colors "$color_code"
+ #echo "color code: $color_code" | show_infobox ;
+ elif [ "$DIALOG" = "dialog" ]; then
+ set_term_colors "$color_code"
+ else
+ echo "Invalid dialog type"
+ return 1
+ fi
+}
+
+
+#
+# Function to set the colors for newt
+#
+function set_newt_colors() {
+ local color_code=$1
+ case $color_code in
+ 0) color="black" ;;
+ 1) color="red" ;;
+ 2) color="green" ;;
+ 3) color="yellow" ;;
+ 4) color="blue" ;;
+ 5) color="magenta" ;;
+ 6) color="cyan" ;;
+ 7) color="white" ;;
+ 8) color="black" ;;
+ 9) color="red" ;;
+ *) return ;;
+ esac
+ export NEWT_COLORS="root=,$color"
+}
+
+
+#
+# Function to set the colors for terminal
+#
+function set_term_colors() {
+ local color_code=$1
+ case $color_code in
+ 0) color="\e[40m" ;; # black
+ 1) color="\e[41m" ;; # red
+ 2) color="\e[42m" ;; # green
+ 3) color="\e[43m" ;; # yellow
+ 4) color="\e[44m" ;; # blue
+ 5) color="\e[45m" ;; # magenta
+ 6) color="\e[46m" ;; # cyan
+ 7) color="\e[47m" ;; # white
+ *) echo "Invalid color code"; return 1 ;;
+ esac
+ echo -e "$color"
+}
+
+
+#
+# Function to reset the colors
+#
+function reset_colors() {
+ echo -e "\e[0m"
+}
+
+
+module_options+=(
+["generate_top_menu,author"]="Joey Turner"
+["generate_top_menu,ref_link"]=""
+["generate_top_menu,feature"]="generate_top_menu"
+["generate_top_menu,desc"]="Build the main menu from a object"
+["generate_top_menu,example"]="generate_top_menu 'json_data'"
+["generate_top_menu,doc_link"]=""
+["generate_top_menu,status"]="Active"
+)
+#
+# Function to generate the main menu from a JSON object
+#
+generate_top_menu() {
+ local json_data=$1
+ local menu_options=()
+ while IFS= read -r id
+ do
+ IFS= read -r description
+ IFS= read -r requirements
+ # If the condition field is not empty and not null, run the function specified in the condition
+ if [[ -n $requirements && $requirements != "null" ]]; then
+ local condition_result=$(eval $requirements)
+ # If the function returns a truthy value, add the menu item to the menu
+ if [[ $condition_result ]]; then
+ menu_options+=("$id" " - $description ($something)")
+ fi
+ else
+ # If the condition field is empty or null, add the menu item to the menu
+ menu_options+=("$id" " - $description ")
+ fi
+ done < <(echo "$json_data" | jq -r '.menu[] | select(.show==true) | "\(.id)\n\(.description)\n\(.condition)"' || exit 1 )
+
+ set_colors 4
+
+ local OPTION=$($DIALOG --title "$TITLE" --menu "$BACKTITLE" 0 80 9 "${menu_options[@]}" 3>&1 1>&2 2>&3)
+ local exitstatus=$?
+
+ if [ $exitstatus = 0 ]; then
+ if [ "$OPTION" == "" ]; then
+ exit 0
+ fi
+ [[ -n "$debug" ]] && echo "$OPTION"
+ generate_menu "$OPTION"
+ fi
+
+# echo "Menu options: ${menu_options[@]}"
+
+}
+
+
+module_options+=(
+["generate_menu,author"]="Joey Turner"
+["generate_menu,ref_link"]=""
+["generate_menu,feature"]="generate_menu"
+["generate_menu,desc"]="Generate a submenu from a parent_id"
+["generate_menu,example"]="generate_menu 'parent_id'"
+["generate_menu,doc_link"]=""
+["generate_menu,status"]="Active"
+)
+#
+# Function to generate the submenu
+#
+function generate_menu() {
+ local parent_id=$1
+
+ # Get the submenu options for the current parent_id
+ local submenu_options=()
+ while IFS= read -r id
+ do
+ IFS= read -r description
+ submenu_options+=("$id" " - $description")
+ done < <(jq -r --arg parent_id "$parent_id" '.menu[] | select(.id==$parent_id) | .sub[]? | select(.show==true) | "\(.id)\n\(.description)"' <<< "$json_data")
+
+
+ local OPTION=$($DIALOG --title "$TITLE" --menu "$BACKTITLE" 0 80 9 "${submenu_options[@]}" \
+ --ok-button Select --cancel-button Back 3>&1 1>&2 2>&3)
+
+ local exitstatus=$?
+
+ if [ $exitstatus = 0 ]; then
+ if [ "$OPTION" == "" ]; then
+ generate_top_menu
+ fi
+ # Check if the selected option has a submenu
+ local submenu_count=$(jq -r --arg id "$OPTION" '.menu[] | .. | objects | select(.id==$id) | .sub[]? | length' "$json_file")
+ submenu_count=${submenu_count:-0} # If submenu_count is null or empty, set it to 0
+ if [ "$submenu_count" -gt 0 ]; then
+ # If it does, generate a new menu for the submenu
+ set_colors 2 # "$?"
+ [[ -n "$debug" ]] && echo "$OPTION"
+ generate_menu "$OPTION"
+ else
+ # If it doesn't, execute the command
+ [[ -n "$debug" ]] && echo "$OPTION"
+ execute_command "$OPTION"
+ #show_message <<< "$OPTION"
+ fi
+ fi
+
+ # echo "Submenu options: ${submenu_options[@]}"
+
+}
+
+
+module_options+=(
+["execute_command,author"]="Joey Turner"
+["execute_command,ref_link"]=""
+["execute_command,feature"]="execute_command"
+["execute_command,desc"]="Needed by generate_menu"
+["execute_command,example"]=""
+["execute_command,doc_link"]=""
+["execute_command,status"]="Active"
+)
+#
+# Function to execute the command
+#
+function execute_command() {
+ local id=$1
+ local commands=$(jq -r --arg id "$id" '.menu[] | .. | objects | select(.id==$id) | .command[]' "$json_file")
+ for command in "${commands[@]}"; do
+ # Check if the command is not in the list of restricted commands
+ [[ -n "$debug" ]] && echo "$command"
+ eval "$command"
+ done
+
+}
+
+
+module_options+=(
+["show_message,author"]="Joey Turner"
+["show_message,ref_link"]=""
+["show_message,feature"]="show_message"
+["show_message,desc"]="Display a message box"
+["show_message,example"]="show_message <<< 'hello world' "
+["show_message,doc_link"]=""
+["show_message,status"]="Active"
+)
+#
+# Function to display a message box
+#
+function show_message() {
+ # Read the input from the pipe
+ input=$(cat)
+
+ # Display the "OK" message box with the input data
+ if [[ $DIALOG != "bash" ]]; then
+ $DIALOG --title "$BACKTITLE" --msgbox "$input" 0 0
+ else
+ echo -e "$input"
+ read -p -r "Press [Enter] to continue..."
+ fi
+}
+
+
+module_options+=(
+["show_infobox,author"]="Joey Turner"
+["show_infobox,ref_link"]=""
+["show_infobox,feature"]="show_infobox"
+["show_infobox,desc"]="pipeline strings to an infobox "
+["show_infobox,example"]="show_infobox <<< 'hello world' ; "
+["show_infobox,doc_link"]=""
+["show_infobox,status"]="Active"
+)
+#
+# Function to display an infobox with a message
+#
+function show_infobox() {
+ export TERM=ansi
+ local input
+ local BACKTITLE="$BACKTITLE"
+ local -a buffer # Declare buffer as an array
+ if [ -p /dev/stdin ]; then
+ while IFS= read -r line; do
+ buffer+=("$line") # Add the line to the buffer
+ # If the buffer has more than 10 lines, remove the oldest line
+ if (( ${#buffer[@]} > 18 )); then
+ buffer=("${buffer[@]:1}")
+ fi
+ # Display the lines in the buffer in the infobox
+
+ TERM=ansi $DIALOG --title "$BACKTITLE" --infobox "$(printf "%s\n" "${buffer[@]}" )" 16 90
+ sleep 0.5
+ done
+ else
+
+ input="$1"
+ TERM=ansi $DIALOG --title "$BACKTITLE" --infobox "$input" 6 80
+ fi
+ echo -ne '\033[3J' # clear the screen
+}
+
+
+module_options+=(
+["show_menu,author"]="Joey Turner"
+["show_menu,ref_link"]=""
+["show_menu,feature"]="show_menu"
+["show_menu,desc"]="Display a menu from pipe"
+["show_menu,example"]="show_menu <<< armbianmonitor -h ; "
+["show_menu,doc_link"]=""
+["show_menu,status"]="Active"
+)
+#
+#
+#
+show_menu(){
+
+ # Get the input and convert it into an array of options
+ inpu_raw=$(cat)
+ # Remove the lines before -h
+ input=$(echo "$inpu_raw" | sed 's/-\([a-zA-Z]\)/\1/' | grep '^ [a-zA-Z] ' | grep -v '\[')
+ options=()
+ while read -r line; do
+ package=$(echo "$line" | awk '{print $1}')
+ description=$(echo "$line" | awk '{$1=""; print $0}' | sed 's/^ *//')
+ options+=("$package" "$description")
+ done <<< "$input"
+
+ # Display the menu and get the user's choice
+ [[ $DIALOG != "bash" ]] && choice=$($DIALOG --title "Menu" --menu "Choose an option:" 0 0 9 "${options[@]}" 3>&1 1>&2 2>&3)
+
+ # Check if the user made a choice
+ if [ $? -eq 0 ]; then
+ echo "$choice"
+ else
+ exit 0
+ fi
+
+ }
+
+
+module_options+=(
+["get_user_continue,author"]="Joey Turner"
+["get_user_continue,ref_link"]=""
+["get_user_continue,feature"]="get_user_continue"
+["get_user_continue,desc"]="Display a Yes/No dialog box and process continue/exit"
+["get_user_continue,example"]="get_user_continue 'Do you wish to continue?' process_input"
+["get_user_continue,doc_link"]=""
+["get_user_continue,status"]="Active"
+)
+#
+# Function to display a Yes/No dialog box
+#
+function get_user_continue() {
+ local message="$1"
+ local next_action="$2"
+
+ if $($DIALOG --yesno "$message" 10 80 3>&1 1>&2 2>&3); then
+ $next_action
+ else
+ $next_action "No"
+ fi
+}
+
+
+menu_options+=(
+["get_user_continue,author"]="Joey Turner"
+["get_user_continue,ref_link"]=""
+["get_user_continue,feature"]="process_input"
+["get_user_continue,desc"]="used to process the user's choice paired with get_user_continue"
+["get_user_continue,example"]="get_user_continue 'Do you wish to continue?' process_input"
+["get_user_continue,status"]="Active"
+["get_user_continue,doc_link"]=""
+)
+#
+# Function to process the user's choice paired with get_user_continue
+#
+function process_input() {
+ local input="$1"
+ if [ "$input" = "No" ]; then
+ exit 1
+ fi
+}
+
+
+module_options+=(
+["get_user_continue_secure,author"]="Joey Turner"
+["get_user_continue_secure,ref_link"]=""
+["get_user_continue_secure,feature"]="get_user_continue_secure"
+["get_user_continue_secure,desc"]="Secure version of get_user_continue"
+["get_user_continue_secure,example"]="get_user_continue_secure 'Do you wish to continue?' process_input"
+["get_user_continue_secure,doc_link"]=""
+["get_user_continue_secure,status"]="Active"
+)
+#
+# Secure version of get_user_continue
+#
+function get_user_continue_secure() {
+ local message="$1"
+ local next_action="$2"
+
+ # Define a list of allowed functions
+ local allowed_functions=("process_input" "other_function")
+ # Check if the next_action is in the list of allowed functions
+ found=0
+ for func in "${allowed_functions[@]}"; do
+ if [[ "$func" == "$next_action" ]]; then
+ found=1
+ break
+ fi
+ done
+
+ if [[ "$found" -eq 1 ]]; then
+ if $($DIALOG --yesno "$message" 10 80 3>&1 1>&2 2>&3); then
+ $next_action
+ else
+ $next_action "No"
+ fi
+ else
+ echo "Error: Invalid function"
+
+ exit 1
+ fi
+}
diff --git a/tools/README.md b/tools/README.md
new file mode 100644
index 000000000..2b76e7e7e
--- /dev/null
+++ b/tools/README.md
@@ -0,0 +1,42 @@
+# Tools
+
+This folder contains various utility scripts.
+
+## Descriptions
+
+### index.html
+
+A form that will help generate a module for `armbian-config`. The form includes fields for specifying a description and a category, metadata, and bash procedures (commands).
+
+To use, upload to a remote web server or start one of the provided simple servers (python3 required), or visit [armbian.tech](http://armbian.tech).
+
+### server.sh
+
+The `server.sh` script starts a simple Python HTTP server on the first available port in the range 8000-8100. This script is intended for Unix-like systems.
+
+### server.bat
+
+The `server.bat` script starts a simple Python HTTP server on the first available port in the range 8000-8100. This script is intended for Windows systems.
+
+## Requirements
+
+- A javascript compatible web browser (for accessing index.html)
+- [armbian.tech](https://armbian.tech/) Web server, or alternatively, Python 3.x (for the simple server)
+
+## Usage
+
+### server.sh
+
+To start the server on Unix-like systems, run:
+
+~~~sh
+bash ./server.sh
+~~~
+
+### server.bat
+
+To start the server on Windows systems, run:
+
+~~~bat
+server.bat
+~~~
\ No newline at end of file
diff --git a/tools/index.html b/tools/index.html
new file mode 100644
index 000000000..8fbf014c5
--- /dev/null
+++ b/tools/index.html
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+
+
+
+ Contribute
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tools/server.bat b/tools/server.bat
new file mode 100644
index 000000000..42d3127e0
--- /dev/null
+++ b/tools/server.bat
@@ -0,0 +1,26 @@
+@echo off
+REM Check if python is installed
+python --version
+if errorlevel 1 (
+ echo Python could not be found
+ exit /b
+)
+
+REM Start the Python server on the first available port in the range 8000-8100
+for /L %%i in (8000,1,8100) do (
+ echo Starting server on port %%i...
+ start /b python -m http.server %%i
+ timeout /t 1
+ REM Check if the server started successfully
+ netstat -an | findstr /R /C:"^ TCP 0.0.0.0:%%i "
+ if not errorlevel 1 (
+ echo Server started on port %%i. Press any key to stop the server.
+ pause
+ echo Stopping server...
+ taskkill /IM python.exe /F
+ echo Server stopped.
+ exit /b
+ ) else (
+ echo Failed to start server on port %%i
+ )
+)
diff --git a/tools/server.sh b/tools/server.sh
new file mode 100644
index 000000000..f59d4c6f0
--- /dev/null
+++ b/tools/server.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+# Check if python3 is installed
+if ! command -v python3 &> /dev/null
+then
+ echo "python3 could not be found"
+ exit
+fi
+
+# Get the IP address
+IP_ADDRESS=$(hostname -I | awk '{print $1}')
+
+# Change to the directory where the script is located
+cd "$(dirname "$0")"
+
+
+# Start the Python server in the background
+for port in {8000..8100}; do
+ # Check if the port is in use
+ if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then
+ # Get the name of the command using the port
+ command_name=$(ps -p $(lsof -t -i:$port) -o comm=)
+ echo "Port $port is in use by $command_name"
+ continue
+ fi
+
+ # Start the server
+ echo "Starting server on port $port..."
+ python3 -m http.server $port > /tmp/config.log 2>&1 &
+ server_pid=$!
+
+ # Wait for the server to start
+ sleep 1
+
+ # Check if the server is running
+ if kill -0 $server_pid 2>/dev/null; then
+ echo -e "\nServer started at IP: $IP_ADDRESS Port: $port"
+ echo -e "Press enter to stop the server."
+ read -p ""
+ kill $server_pid
+ echo "Server stopped."
+ break
+ else
+ echo "Failed to start server on port $port"
+ fi
+done
\ No newline at end of file