DistroHopper/quicktui

684 lines
20 KiB
Bash
Executable File

#!/usr/bin/bash
# Author: zenobit
# Description: Uses gum to provide a simple TUI for quickemu and quickget
# License MIT
define_variables() {
progname="${progname:="${0##*/}"}"
version='0.33'
configdir="$HOME/.config/$progname"
path=$(pwd)
vms=(*.conf)
# Set traps to catch the signals and exit gracefully
trap 'exit' INT
trap 'exit' EXIT
if ! command -v quickemu >/dev/null 2>&1; then
echo 'You are missing quickemu...!'
fi
QUICKGET=$(command -v quickget)
if ! command -v gum >/dev/null 2>&1; then
echo 'You are missing gum...!'
fi
# use configdir
if [ -f "${configdir}/border" ]; then
BORDER="$(cat "${configdir}"/border)"
else
BORDER="rounded"
fi
if [ -f "${configdir}/color" ]; then
BORDERS_FOREGROUND="$(cat "${configdir}"/color)"
else
BORDERS_FOREGROUND="$(( RANDOM % 255 + 1 ))"
fi
if [ -f "${configdir}/indicator" ]; then
GUM_FILTER_INDICATOR_FOREGROUND="$(cat "${configdir}"/indicator)"
else
GUM_FILTER_INDICATOR_FOREGROUND="$(( RANDOM % 255 + 1 ))"
fi
if [ -f "${configdir}/spinner-color" ]; then
GUM_SPIN_SPINNER_FOREGROUND="$(cat "${configdir}"/spinner-color)"
else
GUM_SPIN_SPINNER_FOREGROUND="$(( RANDOM % 255 + 1 ))"
fi
if [ -f "${configdir}/spinner" ]; then
spinner="$(cat "${configdir}"/spinner)"
else
spinner="globe"
fi
}
check_updates() {
show_version_quickemu
https://github.com/quickemu-project/quickemu/releases/latest
show_version_qemu
https://download.qemu.org
show_version_gum
https://github.com/charmbracelet/gum/releases/latest
$version
https://github.com/oSoWoSo/quickemu/tags
}
show_editor() {
if [ -z "$EDITOR" ]; then
echo ' editor Not set!'
else
echo " editor $EDITOR"
fi
}
show_vms() {
if [ ${#vms[@]} -eq 0 ]; then
echo 'No VMs found.'
else
echo "${vms[@]%.*}" | tr " " "\n"
fi
}
show_custom() {
if [ -f "${configdir}/command" ]; then
printf '\n command:\nquickemu %s' "$(cat "${configdir}/command")"
fi
if [ -f "${configdir}/default_vm_config" ]; then
printf '\n VMs default config:\n%s' "$(cat "${configdir}/default_vm_config")"
fi
if [ -f "${configdir}/border" ]; then
printf '\n border: %s' "$(cat "${configdir}/border")"
fi
if [ -f "${configdir}/color" ]; then
printf '\n borders color: %s' "$(cat "${configdir}/color")"
fi
if [ -f "${configdir}/indicator" ]; then
printf '\n indicator color: %s' "$(cat "${configdir}/indicator")"
fi
if [ -f "${configdir}/spinner" ]; then
printf '\n spinner: %s' "$(cat "${configdir}/spinner")"
fi
}
show_version_quickemu() {
quickemu --version | grep "ERROR! QEMU not found" && echo "QEMU is missing!" || quickemu --version
}
show_version_qemu() {
qemu-x86_64 -version | sed 2d | cut -d' ' -f3
}
show_header() {
gum style --padding "0 1" --border="$BORDER" --border-foreground="$BORDERS_FOREGROUND" "$header"
}
show_headers_small() {
header1=$(header="$(gum style --bold "$progname") $version"; show_header)
header2=$(header=" ready VMs:
$(echo "${vms[@]%.*}" | tr " " "\n")"; show_header)
header3=$(header=" workdir:
$(pwd)$(show_custom)"; show_header)
header1_2=$(gum join --vertical "$header1" "$header2")
gum join --align top "$header1_2" "$header3"
}
show_headers_full() {
header1=$(header=" $(gum style --bold "$progname") $version
Simple TUI for quickemu"; show_header)
header2=$(header=" qemu $(show_version_qemu)
quickemu $(show_version_quickemu)
$(show_editor)"; show_header)
header3=$(header=" ready VMs:
$(show_vms)"; show_header)
header4=$(header=" workdir:
$(pwd)$(show_custom)"; show_header)
header1_2=$(gum join "$header1" "$header2")
header3_4=$(gum join "$header3" "$header4")
gum join --align center --vertical "$header1_2" "$header3_4"
}
show_help() {
clear
show_headers_full
show_header
}
help_main() {
header=" $progname $version
Uses gum to provide a simple TUI for quickemu and quickget 'https://github.com/quickemu-project/quickemu'
'https://github.com/charmbracelet/gum'
For menus you can use arrow keys or fuzzy filtering and then ENTER
(e + ENTER for exit or b + ENTER for back to main menu)
If is posible choose more options use TAB for highliting desired and then ENTER
Config and temp files are stored at $configdir"
}
#template for functions
# header=""
# show_header
gum_choose_os() {
header="Choose OS"
show_header
os=$(gum filter < "$configdir"/supported)
choices=$(cat "$configdir/distros/$os")
}
gum_choose_release() {
header="Choose release"
show_header
height=$(echo "$choices" | grep 'Releases:' | cut -d':' -f2 | grep -o '[^ ]*' | wc -l)
release=$(echo "$choices" | grep 'Releases:' | cut -d':' -f2 | grep -o '[^ ]*' | gum filter --sort --height="$height")
}
gum_choose_edition() {
header="Choose edition"
show_header
height=$(echo "$choices" | grep 'Editions:' | cut -d':' -f2 | grep -o '[^ ]*' | wc -l)
edition=$(echo "$choices" | grep 'Editions:' | cut -d':' -f2 | grep -o '[^ ]*' | gum filter --sort --height="$height")
}
gum_choose_VM() {
if ls | grep ".conf" ; then
header="Choose VM"
show_header
height=$(ls -1 | grep ".conf" | wc -l)
chosen=$(ls -1 | grep ".conf" | rev | cut -d'.' -f2- | rev | gum filter --height "$height")
else
echo "No VMs to run."
fi
#chosen=$(printf '%s\n' "${vms[@]%.conf}" | gum filter --height "$("${vms[@]%.conf}" | wc -l)" --header='Choose VM to run')
}
edit_default_VMs_config() {
header="Editing default VM's config..."
show_header
printf 'For example:\ncpu_cores="2"\nram="4G"\n'
header="CTRL+D to complete. CTRL+C and esc will cancel"
show_header
gum write > "${configdir}"/default_vm_config
}
edit_VM_config() {
if [ -z "$EDITOR" ]; then
echo "Editor not set! Can't continue!"
else
header="Editing VM config"
show_header
height=$(ls -1 | grep ".conf" | wc -l)
${EDITOR} "$(ls | grep ".conf" | gum filter --height "$height")"
fi
}
custom_quickemu_command() {
header="Define custom command"
show_header
custom=$(echo "edit delete" | grep -o '[^ ]*' | gum choose --header='Edit or delete custom command?')
if [ "$custom" = "edit" ]; then
header=$(quickemu | awk 'NR==6,/version/')
show_header
printf '\nEnter quickemu custom command:\n For example:--public-dir ~/Downloads\n:'
read -r command
mkdir -p "$configdir"
echo "$command" > "${configdir}/command"
elif [ "$custom" = "delete" ]; then
rm "${configdir}/command"
fi
}
run_VM() {
header="Starting $chosen..."
show_header
if [ -f "${configdir}/command" ]; then
quickemu < "${configdir}/command" -vm "$chosen.conf"
else
quickemu -vm "$chosen.conf"
fi
}
create_VM() {
gum_choose_os
if [ -z "$os" ]; then exit 100
elif [ "$(echo "$choices" | wc -l)" = 1 ]; then
clear
gum_choose_release
gum spin --spinner "$spinner" --show-output --title="Downloading $os $release" -- "$QUICKGET" "$os" "$release"
"$QUICKGET" "$os" "$release"
if [ -f "${configdir}/default_vm_config" ]; then
echo 'Adding default values to config...'
cat "${configdir}/default_vm_config" >> "$os-$release.conf"
fi
else
clear
gum_choose_release
gum_choose_edition
gum spin --spinner "$spinner" --show-output --title="Downloading $os $release $edition" -- "$QUICKGET" "$os" "$release" "$edition"
if [ -f "${configdir}/default_vm_config" ]; then
echo 'Adding default values to config...'
cat "${configdir}/default_vm_config" >> "$os-$release-$edition.conf"
fi
fi
echo "New VM not appear in ready VMs: yet #TODO
To start your new $os virtual machine use 'run VM' from menu"
show_headers_small
}
gum_choose_VM_to_delete() {
height=$(ls -1 | grep ".conf" | wc -l)
GUM_FILTER_HEADER="Choose VM to delete"
GUM_FILTER_HEADER_FOREGROUND="1"
if ls | grep ".conf" ; then
chosen=$(echo "${vms[@]%.*}" | tr " " "\n" | gum filter --height "$height" --no-limit)
echo 'Removing config(s)...'
rm -r "$chosen" & rm "$chosen".conf
else
echo "No VMs to delete"
fi
}
# shellcheck disable=SC2016,2034,2153
add_new_distro() {
header="Adding new distro..."
show_header
echo "add new OS, all lowercase"
NAME="$(gum input --header="NAME" --placeholder="arch")"
echo "add a pretty name for new OS *only if the catch all is not suitable*"
PRETTY_NAME="$(gum input --header="PRETTY_NAME" --placeholder="Arch Linux")"
echo "add a homepage for new OS"
HOMEPAGE="$(gum input --header="HOMEPAGE" --placeholder="https://voidlinux.org/")"
echo "current supported release versions"
RELEASES="$(gum input --header="RELEASES" --placeholder="8 9")"
echo "the editions if new OS has multiple flavours/editions"
EDITIONS="$(gum input --header="EDITIONS" --placeholder="kde gnome")"
echo "base URL for ISO download"
URL="$(gum input --header="URL" --placeholder="https://ddl.bunsenlabs.org/ddl")"
echo "Name of ISO"
ISO="$(gum input --header="ISO" --placeholder="GhostBSD-${RELEASE}-XFCE.iso")"
echo "name of hash file "
CHECKSUM="$(gum input --header="CHECKSUM" --placeholder='${ISO}.sha256sum')"
cat <<EOF > "$configdir/template"
#line 58+
$NAME) PRETTY_NAME="$PRETTY_NAME";;
#line 207+
$NAME \\
#line 292+
$NAME) HOMEPAGE=$HOMEPAGE;;
#line 374+
function releases_$NAME() {
echo $RELEASES
}
function editions_$NAME() {
echo $EDITIONS
}
#line 1176+
function get_$NAME() {
local EDITION="\${1:-}"
local HASH=""
local ISO="$ISO"
local URL="$URL"
HASH="\$(wget -q -O- \${URL}/\$CHECKSUM | grep (\${ISO} | cut -d' ' -f4)"
echo "\${URL}/\${ISO}" "\${HASH}"
}
EOF
diff "$configdir/template" "quickget"
}
# shellcheck disable=SC2154
create_desktop_entry() {
cat <<EOF > "${DESKTOP_FILE}"
[Desktop Entry]
Version=$version
Type=$type
Name=$name
GenericName=$progname
Comment=$comment
Exec=$execmd
Icon=$icon
Terminal=$terminal
X-MultipleArgs=$args
Type=$type
Categories=$categories
StartupNotify=$notify
MimeType=$mime
Keywords=$keyword
EOF
}
test_ISOs_download() {
cd "$configdir/distros" || exit
echo "New run $(date)" > "$configdir/test_download"
while read -r get_name; do
echo "Trying $get_name..."
releases=$(echo "$get_name" | grep 'Releases:' | cut -d':' -f2 | grep -o '[^ ]*')
editions=$(echo "$get_name" | grep 'Editions:' | cut -d':' -f2 | grep -o '[^ ]*')
if [ -z "$editions" ]; then
for release in $releases; do
echo "$get_name" >> "$configdir/test_download"
timeout 10 "$QUICKGET" -t "$get_name" "${release}"
done
else
while read -r release; do
for edition in $editions; do
echo "$get_name" >> "$configdir/test_download"
timeout 10 "$QUICKGET" -t "$get_name" "${release}" "${edition}"
done
done < releases
fi
cd "$configdir" || exit
done < "$configdir/supported"
printf "\nDone"
}
show_ISOs_urls(){
cd "$configdir/distros" || exit
choices=$(echo "$configdir/distros/$os")
while read -r get_name; do
releases=$(echo "$choices" | grep 'Releases:' | cut -d':' -f2 | grep -o '[^ ]*')
editions=$(echo "$choices" | grep 'Editions:' | cut -d':' -f2 | grep -o '[^ ]*')
if [ -z "$editions" ]; then
for release in $releases; do
"$QUICKGET" -s "$get_name" "${release}"
done
else
while read -r release; do
for edition in $editions; do
"$QUICKGET" -s "$get_name" "${release}" "${edition}"
done
done < releases
fi
cd "$path" || exit
done < "$configdir/supported"
printf "\nDone"
}
generate_if_needed() {
if [ ! -f "${configdir}"/supported ]; then
generate_supported
fi
}
generate_supported(){
echo "Extracting OS Editions and Releases..."
rm -r "$configdir/distros"
mkdir -p "$configdir/distros"
"$QUICKGET" | awk 'NR==2,/zorin/' | cut -d':' -f2 | grep -o '[^ ]*' > "$configdir/supported"
while read -r get_name; do
supported=$(gum spin --spinner "$spinner" --title="$get_name" --show-output -- "$QUICKGET" "$get_name" | sed 1d)
echo "$supported" > "$configdir/distros/${get_name}"
done < "$configdir/supported"
}
open_distro_homepage(){
gum_choose_os
"$QUICKGET" -o "${os}"
}
change_borders() {
header="Change borders style"
show_header
height=6
BORDER=$(echo "none
hidden
normal
rounded
thick
double" | gum filter --height $height)
echo "$BORDER" > "${configdir}"/border
}
change_color() {
if command -v yad >/dev/null 2>&1; then
header="Define color, use color picker or choose random"
show_header
height=4
start=$(echo "random
yad color picker
custom
EXIT $progname" | gum filter --height $height)
case $start in
'random' ) BORDER_FOREGROUND="$(( RANDOM % 255 + 1 ))";;
'yad color picker' ) BORDER_FOREGROUND="$(yad --color)";;
'custom' ) BORDER_FOREGROUND=$(gum input --header="Enter color value");;
'show help' ) help_main; show_help;;
"EXIT $progname" ) exit 0;;
esac
else
header="Define color number or choose random"
show_header
BORDER_FOREGROUND=$(echo 'random' | gum filter --no-strict GUM_FILTER_PLACEHOLDER="custom" --height 1)
fi
echo "$BORDER_FOREGROUND" > "${configdir}"/color
}
change_color_indicator() {
if command -v yad >/dev/null 2>&1; then
header="Define indicator color value, use color picker or choose random"
show_header
height=5
start=$(echo "random
yad color picker
custom
EXIT $progname" | gum filter --height $height)
case $start in
'random' ) GUM_FILTER_INDICATOR_FOREGROUND="$(( RANDOM % 255 + 1 ))";;
'yad color picker' ) GUM_FILTER_INDICATOR_FOREGROUND="$(yad --color)";;
'custom' ) GUM_FILTER_INDICATOR_FOREGROUND=$(gum input --header="Enter color value");;
'show help' ) help_main; show_help;;
"EXIT $progname" ) exit 0;;
esac
else
header="Define indicator color value or choose random"
show_header
GUM_FILTER_INDICATOR_FOREGROUND=$(echo 'random' | gum filter --no-strict GUM_FILTER_PLACEHOLDER="custom" --height 1)
fi
echo "$GUM_FILTER_INDICATOR_FOREGROUND" > "${configdir}"/indicator
}
change_color_spinner() {
if command -v yad >/dev/null 2>&1; then
header="Define color, use color picker or choose random"
show_header
height=4
start=$(echo "random
yad color picker
custom
EXIT $progname" | gum filter --height $height)
case $start in
'random' ) GUM_SPIN_SPINNER_FOREGROUND="$(( RANDOM % 255 + 1 ))";;
'yad color picker' ) GUM_SPIN_SPINNER_FOREGROUND="$(yad --color)";;
'custom' ) GUM_SPIN_SPINNER_FOREGROUND=$(gum input --header="Enter color value");;
'show help' ) help_main; show_help;;
"EXIT $progname" ) exit 0;;
esac
else
header="Define color number or choose random"
show_header
GUM_SPIN_SPINNER_FOREGROUND=$(echo 'random' | gum filter --no-strict GUM_FILTER_PLACEHOLDER="custom" --height 1)
fi
echo "$GUM_SPIN_SPINNER_FOREGROUND" > "${configdir}"/spinner-color
}
use_color() {
if [ -f "${configdir}/color" ]; then
BORDER_FOREGROUND=$(cat "${configdir}"/color)
fi
}
change_spinner() {
height=11
spinner=$(echo "line
dot
minidot
jump
pulse
points
globe
moon
monkey
meter
hamburger" | gum filter --height $height)
echo "$spinner" > "${configdir}"/spinner
}
# MENU
show_menu_main() {
while true
do
height=9
start=$(echo "create new VM
run VM
open distro homepage
delete VM
advanced menu
settings menu
test menu
show help
EXIT $progname" | gum filter --height $height)
case $start in
'create new VM' ) create_VM;;
'advanced menu' ) show_menu_advanced;;
'settings menu' ) show_menu_settings;;
'run VM' ) gum_choose_VM && run_VM;;
'open distro homepage' ) open_distro_homepage;;
'delete VM' ) gum_choose_VM_to_delete;;
'test menu' ) show_menu_test;;
'show help' ) help_main; show_help;;
"EXIT $progname" ) exit 0;;
esac
done
}
show_menu_advanced() {
while true
do
header="advanced"
show_header
height=8
start=$(echo "test ISOs download
show ISOs URLs
set default config for VMs
edit VM config
custom quickemu command
add new distro
back to main menu
EXIT $progname" | gum filter --height $height)
case $start in
'set default config for VMs' ) edit_default_VMs_config;;
'edit VM config' ) edit_VM_config;;
'custom quickemu command' ) custom_quickemu_command;;
'add new distro' ) add_new_distro;;
'test ISOs download' ) test_ISOs_download;;
'show ISOs URLs' ) show_ISOs_urls;;
'back to main menu') clear; show_headers_small; break;;
"EXIT $progname" ) exit 0;;
esac
done
}
show_menu_settings() {
while true
do
header="settings"
show_header
height=8
start=$(echo "update $progname
regenerate supported
change borders color
change borders style
change indicator color
change spinner color
change spinner style
back to main menu
EXIT $progname" | gum filter --height $height)
case $start in
"update $progname" ) update_quicktui;;
'regenerate supported' ) generate_supported;;
'change borders color' ) change_color;;
'change borders style' ) change_borders;;
'change indicator color' ) change_color_indicator;;
'change spinner style' ) change_spinner;;
'change spinner color' ) change_color_spinner;;
'back to main menu') clear; show_headers_small; break;;
"EXIT $progname" ) exit 0;;
esac
done
}
show_menu_test() {
while true
do
header="dev (Not for use!)"
show_header
height=27
start=$(echo "add new distro
change spinner
choose vm to delete
create vm
create desktop entry
custom quickemu command
delete vm
edit vm config
edit default vms config
generate if needed
generate supported
gum choose vm
gum choose editions
gum choose os
gum choose release
open distro homepage
qemu version
quickemu version
run vm
show isos urls
show custom
show editor
show headers
show vms
test isos download
back to main menu
EXIT $progname" | gum filter --height $height)
case $start in
'add new distro' ) add_new_distro;;
'change spinner' ) change_spinner;;
'choose vm to delete' ) gum_choose_VM_to_delete;;
'create vm' ) create_VM;;
'create desktop entry' ) create_desktop_entry;;
'custom quickemu command' ) custom_quickemu_command;;
'delete vm' ) delete_VMe;;
'edit vm config' ) edit_VM_config;;
'edit default vms config' ) edit_default_VMs_config;;
'generate if needed' ) generate_if_needed;;
'generate supported' ) generate_supported;;
'gum choose vm' ) gum_choose_VM;;
'gum choose editions' ) gum_choose_edition;;
'gum choose os' ) gum_choose_os;;
'gum choose release' ) gum_choose_release;;
'open distro homepage' ) open_distro_homepage;;
'qemu version' ) show_version_qemu;;
'quickemu version' ) show_version_quickemu;;
'run vm' ) run_VM;;
'show isos urls' ) show_ISOs_urls;;
'show custom' ) show_custom;;
'show editor' ) show_editor;;
'show headers' ) show_headers;;
'show vms' ) show_vms;;
'test isos download' ) test_ISOs_download;;
'back to main menu') clear; show_headers_small; break;;
"EXIT $progname" ) exit 0;;
esac
done
}
# run
clear
define_variables
generate_if_needed
show_headers_small
show_menu_main