From 4319c6573771bbc08b128676ce69ba89c1df9c18 Mon Sep 17 00:00:00 2001 From: Vargink Date: Mon, 30 Sep 2024 06:36:25 +1000 Subject: [PATCH] Initial Commit Initial Commit --- README.md | 11 + install.sh | 8 + vargtools | 744 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 763 insertions(+) create mode 100644 README.md create mode 100644 install.sh create mode 100644 vargtools diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ecef1e --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +## Vargtools ## + +A bunch of tools and scripts to make the world go round + +## To Setup ## + +Just run the following command to install + +``` +sudo bash -c "$(wget -q -O - https://git.tcmeta.net/kurtis/vargtools/raw/branch/main/install.sh)" +``` diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..2c448bd --- /dev/null +++ b/install.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# download script +echo "Downloading vargtools" +wget https://git.tcmeta.net/kurtis/vargtools/raw/branch/main/vargtools -q -O /usr/local/bin/vargtools +chmod +x /usr/local/bin/vargtools + +echo Done you should now be able to start vargtools by typing sudo vargtools + diff --git a/vargtools b/vargtools new file mode 100644 index 0000000..522d612 --- /dev/null +++ b/vargtools @@ -0,0 +1,744 @@ +#!/usr/bin/env bash + +# Debian XFCE init and setup + +# Check for sudo access +if [ "$EUID" -ne 0 ] + then echo "Please run as root" + exit +fi + +user_home=$(sudo -u $SUDO_USER sh -c 'echo $HOME') +URL=https://git.tcmeta.net/kurtis/elementaryos-config/raw/branch/main/ +app_version=24092720 +init_version=0 + +# Depriv + +depriv() { + if [[ $SUDO_USER ]]; then + sudo -u "$SUDO_USER" -- "$@" + else + "$@" + fi +} + +start() { + if [ -f /etc/vargtools/init ]; then + init_version=$( /etc/vargtools/init + fi + if [ "$init_version" -lt "$app_version" ]; then + menuItems=( + "1. Perform Initialisation" + "Q. Exit " + ) + menuActions=( + doInit + quitApp + ) + menuTitle=" VargTools has not been initalised yet. Proceed?" + menuWidth=60 + menuLeft=20 + menuHighlight=$DRAW_COL_GREEN + menuInit + menuLoop + else + vMenuMain + fi +} + +vMenuMain() { + menuItems=( + "1. Software" + "2. System " + "Q. Exit " + ) + menuActions=( + vMenuSoftware + vMenuSystem + quitApp + ) + menuTitle=" VargTools" + menuWidth=60 + menuLeft=20 + menuHighlight=$DRAW_COL_GREEN + menuInit + menuLoop +} + +vMenuSystem() { + menuItems=( + "1. Setup Chicago95 " + "2. Update / Install Chromium Policy" + "B. Back " + ) + menuActions=( + installChicago95 + configChromium + vMenuMain + ) + menuTitle=" VargTools" + menuWidth=60 + menuLeft=20 + menuHighlight=$DRAW_COL_GREEN + menuInit + menuLoop +} + +vMenuSoftware() { + menuNumberIndex=1 + menuItems=("$menuNumberIndex. Install All Software") + menuActions=(installAll) + flatpakInstalled=0 + flatpak info "com.valvesoftware.SteamLink" >/dev/null 2>&1 && flatpakInstalled=1 + if [ "$flatpakInstalled" = "0" ]; then + menuNumberIndex=$((menuNumberIndex+1)) + menuItems+=("$menuNumberIndex. SteamLink") + menuActions+=(installSteamLink) + fi + if ! [ -x "$(command -v chromium)" ]; then + menuNumberIndex=$((menuNumberIndex+1)) + menuItems+=("$menuNumberIndex. Chromium") + menuActions+=(setupChromium) + fi + if ! [ -x "$(command -v discord)" ]; then + menuNumberIndex=$((menuNumberIndex+1)) + menuItems+=("$menuNumberIndex. Discord") + menuActions+=(installDiscord) + fi + if ! [ -x "$(command -v subl)" ]; then + menuNumberIndex=$((menuNumberIndex+1)) + menuItems+=("$menuNumberIndex. Sublime Text Editor & Merge") + menuActions+=(installSublime) + fi + if ! [ -x "$(command -v blueman-manager)" ]; then + menuNumberIndex=$((menuNumberIndex+1)) + menuItems+=("$menuNumberIndex. Bluetooth") + menuActions+=(installBluetooth) + fi + menuItems+=("B. Back ") + menuActions+=(vMenuMain) + menuTitle="Vargtools - Software" + menuWidth=60 + menuLeft=20 + menuHighlight=$DRAW_COL_GREEN + menuInit + menuLoop +} + +doInit() { + logo + if [ "$init_version" -lt 24092720 ]; then + echo Removing cdrom from apt + sed -i "/^deb cdrom:/s/^/#/" /etc/apt/sources.list + apt update + echo Installing base software + apt install -y git python3 python3-pip pipx stow btop duf + echo installing console python apps + depriv pipx ensurepath + depriv pipx install thefuck + depriv pipx install sshch + fi + echo "$app_version" > /etc/vargtools/init + echo Should be all upto date now .. press any key to continue + read -n 1 + vMenuMain +} + +installChicago95() { + logo + echo [Chicago95] Installing prereqs + wget "https://github.com/MerkeX/Lightdm-webkit2-greeter/releases/download/v2.2.5-1/lightdm-webkit2-greeter_2.2.5-1_amd64.deb" -O /tmp/lightdm-webkit2-greeter.deb + apt install -y /tmp/lightdm-webkit2-greeter.deb + rm /tmp/lightdm-webkit2-greeter.deb + apt install -y xfce4-panel-profiles gnome-session-canberra sox libcanberra-gtk3-module libcanberra-gtk-module dbus-x11 + echo [Chicago95] Downloading theme + depriv git clone https://github.com/grassmunk/Chicago95.git /tmp/Chicago95 + echo [Chicago95] Installing system wide + cp -r /tmp/Chicago95/Theme/Chicago95 /usr/share/themes/ + cp -r /tmp/Chicago95/Icons/* /usr/share/icons/ + cp -v /tmp/Chicago95/Fonts/vga_font/LessPerfectDOSVGA.ttf /usr/share/fonts + cp -r /tmp/Chicago95/Fonts/bitmap/cronyx-cyrillic /usr/share/fonts + echo [Chicago95] Installing fonts + mv /etc/fonts/conf.d/70-no-bitmaps.conf /etc/fonts/conf.d/70-no-bitmaps.conf.bak + fc-cache -fv + echo [Chicago95] Installing Login Screen + sed -i 's/\#greeter-session/greeter-session/g' /etc/lightdm/lightdm.conf + sed -i 's/\#user-session/user-session/g' /etc/lightdm/lightdm.conf + sed -i -e "s/\(greeter-session *= *\).*/\1lightdm-webkit2-greeter/" /etc/lightdm/lightdm.conf + sed -i -e "s/\(user-session *= *\).*/\1xfce/" /etc/lightdm/lightdm.conf + cp -r /tmp/Chicago95/Lightdm/Chicago95 /usr/share/lightdm-webkit/themes/ + echo [Chicago95] Generating Config + echo "#" > /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# [greeter]" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# debug_mode = Greeter theme debug mode." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# detect_theme_errors = Provide an option to load a fallback theme when theme errors are detected." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# screensaver_timeout = Blank the screen after this many seconds of inactivity." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# secure_mode = Don't allow themes to make remote http requests." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# time_format = A moment.js format string so the greeter can generate localized time for display." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# time_language = Language to use when displaying the time or "auto" to use the system's language." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# webkit_theme = Webkit theme to use." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "#" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# NOTE: See moment.js documentation for format string options: http://momentjs.com/docs/#/displaying/format/" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "#" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "[greeter]" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "debug_mode = false" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "detect_theme_errors = true" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "screensaver_timeout = 300" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "secure_mode = true" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "time_format = LT" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "time_language = auto" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "webkit_theme = Chicago95" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "#" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# [branding]" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# background_images = Path to directory that contains background images for use by themes." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# logo = Path to logo image for use by greeter themes." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# user_image = Default user image/avatar. This is used by themes for users that have no .face image." >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "#" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "# NOTE: Paths must be accessible to the lightdm system user account (so they cannot be anywhere in /home)" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "#" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "[branding]" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "background_images = /usr/share/backgrounds" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "logo = /usr/share/lightdm-webkit/themes/antergos/img/antergos.png" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "user_image = /usr/share/lightdm-webkit/themes/antergos/img/antergos-logo-user.png" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo "" >> /etc/lightdm/lightdm-webkit2-greeter.conf + echo [Chicago95] Installing boot screen + cp -r /tmp/Chicago95/Plymouth/Chicago95 /usr/share/plymouth/themes/ + cp -r /tmp/Chicago95/Plymouth/RetroTux /usr/share/plymouth/themes/ + plymouth-set-default-theme -R Chicago95 + echo [Chicago95] Modifying grub + sed -i -e "s/\(GRUB_TIMEOUT *= *\).*/\10/" /etc/default/grub + sed -i 's/\quiet/quiet splash/g' /etc/default/grub + sed -i 's/\\#GRUB_TERMINAL/GRUB_TERMINAL/g' /etc/default/grub + echo [Chicago95] Updating Grub + update-grub2 + echo [Chicago95] Running Client installer + depriv python3 /tmp/Chicago95/installer.py + echo [Chicago95] Installing startup sound / wallpapers + depriv cp "/tmp/Chicago95/Extras/Microsoft Windows 95 Startup Sound.ogg" "$user_home/.themes/Chicago95/misc/Microsoft Windows 95 Startup Sound.ogg" + depriv mkdir -p $user_home/.config/autostart + depriv echo "[Desktop Entry]" > "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Encoding=UTF-8" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Version=0.9.4" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Type=Application" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Name=Windows Logon Sound" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Comment=Plays the windows 95 logon music" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Exec=play \"$user_home/.themes/Chicago95/misc/Microsoft Windows 95 Startup Sound.ogg\"" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "OnlyShowIn=XFCE;" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "RunHook=0" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "StartupNotify=false" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Terminal=false" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv echo "Hidden=false" >> "$user_home/.config/autostart/Windows Logon Sound.desktop" + depriv cp -r /tmp/Chicago95/Extras/Backgrounds $user_home/.themes/Chicago95/misc + echo [Chicago95] Okay done + return 1 +} + +installDiscord() { + echo [Discord] Downloading latest version + wget "https://discord.com/api/download?platform=linux&format=deb" -O /tmp/discord.deb + echo [Discord] Installing + apt install -y /tmp/discord.deb + echo [Discord] Cleaning up + rm /tmp/discord.deb + return 1 +} + +setupChromium() { + logo + installChromium + configChromium + return 1 +} + +installSublime() { + echo [Sublime] Adding Repo + wget "https://download.sublimetext.com/sublimehq-pub.gpg" -O /tmp/sublimehq-pub-download.gpg + gpg --no-default-keyring --keyring /tmp/temp-keyring.gpg --import /tmp/sublimehq-pub-download.gpg + gpg --no-default-keyring --keyring /tmp/temp-keyring.gpg --export --output /tmp/sublimehq-pub.gpg + mkdir -p /etc/apt/keyrings/ + cp /tmp/sublimehq-pub.gpg /etc/apt/keyrings/sublimehq-pub.gpg + rm /tmp/sublimehq-pub-download.gpg /tmp/temp-keyring.gpg /tmp/sublimehq-pub.gpg + echo "deb [signed-by=/etc/apt/keyrings/sublimehq-pub.gpg] https://download.sublimetext.com/ apt/stable/" | sudo tee /etc/apt/sources.list.d/sublime-text.list + echo [Sublime] Updating Repo + sudo apt update + echo [Sublime] Installing + sudo apt install sublime-text sublime-merge + read -n 1 + return 1 +} + +installChromium() { + if ! [ -x "$(command -v chromium)" ]; then + echo [Chromium] Installing Chromium + apt install -y chromium + else + echo [Chromium] Already Installed + fi + return 1 +} + +installBluetooth() { + if ! [ -x "$(command -v bluetooth)" ]; then + echo [Bluetooth] Installing bluetooth stack + apt install -y bluetooth + else + echo [Bluetooth] Bluetooth already installed + fi + if ! [ -x "$(command -v blueman)" ]; then + echo [Bluetooth] Installing blueman + apt install -y blueman + else + echo [Bluetooth] Blueman already installed + fi + return 1 +} + +configChromium() { + echo [Chromium] Deploying policy + mkdir -p /etc/chromium/policies/managed + chmod -w /etc/chromium/policies/managed + wget https://git.tcmeta.net/kurtis/chromium-policy/raw/branch/main/varg-policy.json -O /etc/chromium/policies/managed/varg-policy.json + echo [Chromium] Policy deployed + return 1 +} + +installFlatPak() { + if ! [ -x "$(command -v flatpak)" ]; then + echo [FlatPak] Installing + apt install -y flatpak + flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + else + echo [FlatPak] Already Installed Installed + fi +} + +installSteamLink() { + if ! [ -x "$(command -v flatpak)" ]; then + echo [SteamLink] flatpak not found installing + installFlatPak + fi + flatpakInstalled=0 + flatpak info "com.valvesoftware.SteamLink" >/dev/null 2>&1 && flatpakInstalled=1 + if [ "$flatpakInstalled" = "0" ]; then + echo [SteamLink] Installing + flatpak -y install flathub com.valvesoftware.SteamLink + fi + return 1 +} + +quitApp() { + return 0 +} + +logo() { echo -e "\x20\x20\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\n\e[48;5;34m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;10m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;12m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\e[48;5;16m\x20\x20\e[m\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\e[48;5;16m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\n\x20\x20\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\e[48;5;34m\x20\x20\e[m\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"; } + +# +# Public Functions +# +# menuInit() +# menuLoop() +# +# +# Public Variables to Override +# +# Should these get passed into menuInit() rather than be set as global +# script variables? +# +# menuTop # Top row of menu (defaults to row 2) +# menuLeft # Left offset for menu item text (defaults to column 15) +# menuWidth # Width of menu (defaults to 42 columns) +# menuMargin # Left offset for menu border (defaults to column 4) +# +# menuColour # Colour of menu text (defaults to DRAW_COL_WHITE) +# menuHighlight # Highlight colour for menu (defaults to DRAW_COL_GREEN) +# +# menuTitle # Title of menu +# menuFooter # Footer text of menu +# +# menuItems # Array containing menu item text +# menuActions # Array containing functions to call upon menu item selection +# + + +# Ensure we are running under bash (will not work under sh or dash etc) +if [ "$BASH_SOURCE" = "" ]; then + echo "ERROR: bash-menu requires to be running under bash" + exit 1 +fi + +# Get script root (as we are sourced from another script, $0 will not be us) +declare -r menuScript=$(readlink -f ${BASH_SOURCE[0]}) +menuRoot=$(dirname "$menuScript") + +################################ +# Private Variables +# +# These should not be overridden +################################ +declare -a menuItems +declare -a menuActions + +menuHeaderText="" +menuFooterText="" +menuBorderText="" + + +################################ +# Setup Menu +# +# These are defaults which should +# be overridden as required. +################################ + +# Top of menu (row 2) +menuTop=2 + +# Left offset for menu items (not border) +menuLeft=15 + +# Width of menu +menuWidth=42 + +# Left offset for menu border (not menu items) +menuMargin=4 + +menuItems[0]="Exit" +menuActions[0]="return 0" + +menuItemCount=1 +menuLastItem=0 + +menuColour=$DRAW_COL_WHITE +menuHighlight=$DRAW_COL_GREEN + +menuTitle=" Super Bash Menu System" +menuFooter=" Enter=Select, Up/Down=Prev/Next Option" + + +################################ +# Initialise Menu +################################ +menuInit() { + menuItemCount=${#menuItems[@]} + menuLastItem=$((menuItemCount-1)) + + # Ensure header and footer are padded appropriately + menuHeaderText=`printf "%-${menuWidth}s" "$menuTitle"` + menuFooterText=`printf "%-${menuWidth}s" "$menuFooter"` + + # Menu (side) borders + local marginSpaces=$((menuMargin-1)) + local menuSpaces=$((menuWidth-2)) + local leftGap=`printf "%${marginSpaces}s" ""` + local midGap=`printf "%${menuSpaces}s" ""` + menuBorderText="${leftGap}x${midGap}x" +} + + +################################ +# Show Menu +################################ +menu_Display() { + local menuSize=$((menuItemCount+2)) + local menuEnd=$((menuSize+menuTop+1)) + + drawClear + drawColour $menuColour $menuHighlight + + # Menu header + drawHighlightAt $menuTop $menuMargin "$menuHeaderText" 1 + + # Menu (side) borders + for row in $(seq 1 $menuSize); do + drawSpecial "$menuBorderText" 1 + done + + # Menu footer + drawHighlightAt $menuEnd $menuMargin "$menuFooterText" 1 + + # Menu items + for item in $(seq 0 $menuLastItem); do + menu_ClearItem $item + done +} + + +################################ +# Mark Menu Items +################################ + +# Ensure menu item is not highlighted +menu_ClearItem() { + local item=$1 + local top=$((menuTop+item+2)) + local menuText=${menuItems[$item]} + + drawPlainAt $top $menuLeft "$menuText" +} + +# Highlight menu item +menu_HighlightItem() { + local item=$1 + local top=$((menuTop+item+2)) + local menuText=${menuItems[$item]} + + drawHighlightAt $top $menuLeft "$menuText" +} + + +################################ +# Wait for and process user input +################################ +menu_HandleInput() { + local choice=$1 + + local after=$((choice+1)) + [[ $after -gt $menuLastItem ]] && after=0 + + local before=$((choice-1)) + [[ $before -lt 0 ]] && before=$menuLastItem + + # Clear highlight from prev/next menu items + menu_ClearItem $before + menu_ClearItem $after + + # Highlight current menu item + menu_HighlightItem $choice + + # Get keyboard input + local key="" + local extra="" + + read -s -n1 key 2> /dev/null >&2 + while read -s -n1 -t .05 extra 2> /dev/null >&2 ; do + key="$key$extra" + done + + # Handle known keys + local escKey=`echo -en "\033"` + local upKey=`echo -en "\033[A"` + local downKey=`echo -en "\033[B"` + + if [[ $key = $upKey ]]; then + return $before + elif [[ $key = $downKey ]]; then + return $after + elif [[ $key = $escKey ]]; then + if [[ $choice -eq $menuLastItem ]]; then + # Pressing Esc while on last menu item will trigger action + # This is a helper as we assume the last menu option is exit + key="" + else + # Jumping possibly more than 1 (next/prev) item + menu_ClearItem $choice + return $menuLastItem + fi + elif [[ ${#key} -eq 1 ]]; then + # See if we wanrt to jump to a menu item + # by entering the first character + for index in $(seq 0 $menuLastItem) ; do + local item=${menuItems[$index]} + local startChar=${item:0:1} + if [[ "$key" = "$startChar" ]]; then + # Jumping possibly more than 1 (next/prev) item + menu_ClearItem $choice + return $index + fi + done + fi + + if [[ "$key" = "" ]]; then + # Notify that Enter key was pressed + return 255 + fi + + return $choice +} + + +################################ +# Main Menu Loop +################################ +menuLoop() { + local choice=0 + local running=1 + + menu_Display + + while [[ $running -eq 1 ]]; do + # Enable case insensitive matching + local caseMatch=`shopt -p nocasematch` + shopt -s nocasematch + + menu_HandleInput $choice + local newChoice=$? + + # Revert to previous case matching + $caseMatch + + if [[ $newChoice -eq 255 ]]; then + # Enter pressed - run menu action + drawClear + action=${menuActions[$choice]} + $action + running=$? + + # Back from action + # If we are still running, redraw menu + [[ $running -eq 1 ]] && menu_Display + + elif [[ $newChoice -lt $menuItemCount ]]; then + # Update selected menu item + choice=$newChoice + fi + done + + # Cleanup screen + drawClear +} + +# +# Public Functions: +# +# drawClear() +# drawColour(colour = DRAW_COL_DEF, bgColour = DRAW_COL_DEF) +# +# drawPlain(text, newLine = 0) +# drawSpecial(text, newLine = 0) +# drawHighlight(text, newLine = 0) +# drawPlainAt(left, top, text, newLine = 0) +# drawHighlightAt(left, top, text, newLine = 0) +# +# +# Colours +# +# DRAW_COL_DEF # Default colour +# DRAW_COL_BLACK +# DRAW_COL_WHITE +# DRAW_COL_RED +# DRAW_COL_GREEN +# DRAW_COL_YELLOW +# DRAW_COL_BLUE +# DRAW_COL_GRAY # Light gray (grey?) +# + + +# Ensure we are running under bash (will not work under sh or dash etc) +if [ "$BASH_SOURCE" = "" ]; then + echo "ERROR: bash-draw requires to be running under bash" + exit 1 +fi + + +DRAW_COL_DEF=39 +DRAW_COL_BLACK=30 +DRAW_COL_WHITE=97 +DRAW_COL_RED=31 +DRAW_COL_GREEN=32 +DRAW_COL_YELLOW=33 +DRAW_COL_BLUE=34 +DRAW_COL_GRAY=37 + + +# drawClear() +drawClear() { + $ESC_WRITE "\033c" +} + +# drawColour(colour = DRAW_COL_DEF, bgColour = DRAW_COL_DEF) +drawColour() { + local colour=$DRAW_COL_DEF + local bgColour=$((DRAW_COL_DEF+10)) + + if [[ ! -z "$1" && "$1" != "" ]]; then + colour="$1" + fi + + if [[ ! -z "$2" && "$2" != "" ]]; then + bgColour="$2" + fi + + $ESC_ECHO "\033c\033[H\033[J\033[${colour};${bgColour}m\033[J" +} + +# drawPlain(text, newLine = 0) +drawPlain() { + if [[ -z "$2" || "$2" -eq 0 ]]; then + $ESC_WRITE "$1" + else + $ESC_ECHO "$1" + fi +} + +# drawSpecial(text, newLine = 0) +drawSpecial() { + [[ -z "$2" ]] && newLine=0 || newLine="$2" + + draw_SetDrawMode + drawPlain "$1" "$newLine" + draw_SetWriteMode +} + +# drawHighlight(text, newLine = 0) +drawHighlight() { + [[ -z "$2" ]] && newLine=0 || newLine="$2" + + draw_StartHighlight + drawPlain "$1" "$newLine" + draw_EndHighlight +} + +# drawPlainAt(left, top, text, newLine = 0) +drawPlainAt() { + [[ -z "$4" ]] && newLine=0 || newLine="$4" + + draw_MoveTo $1 $2 + drawPlain "$3" "$newLine" +} + +# drawHighlightAt(left, top, text, newLine = 0) +drawHighlightAt() { + [[ -z "$4" ]] && newLine=0 || newLine="$4" + + draw_StartHighlight + drawPlainAt "$1" "$2" "$3" "$newLine" + draw_EndHighlight +} + + +# Write escape sequence with no newline +ESC_WRITE='echo -en' + +# Write escape sequence adding newline +ESC_ECHO='echo -e' + + +# Move cursor to specified location +draw_MoveTo() { + $ESC_WRITE "\033[${1};${2}H" +} + +draw_StartHighlight() { + $ESC_WRITE "\033[7m" +} + +draw_EndHighlight() { + $ESC_WRITE "\033[27m" +} + +draw_SetDrawMode() { + $ESC_WRITE "\033%@\033(0" +} + +draw_SetWriteMode() { + $ESC_WRITE "\033(B" +} + +start;