mirror of
https://github.com/m-housh/dotfiles.git
synced 2026-02-14 06:12:34 +00:00
feat: Updates install-webapp script with more flags and a launch option to open in a new terminal window.
This commit is contained in:
338
env/.local/scripts/hypr/install-webapp
vendored
338
env/.local/scripts/hypr/install-webapp
vendored
@@ -1,24 +1,37 @@
|
||||
#!/bin/zsh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Adapted from https://github.com/basecamp/omarchy/tree/master?tab=readme-ov-file
|
||||
|
||||
# TODO: Use bash and only allow options, not positional arguments to make easier.
|
||||
THIS=$(basename ${BASH_SOURCE[0]})
|
||||
|
||||
function usage() {
|
||||
cat <<EOF
|
||||
Generates a '.desktop' file for a web application, so that it
|
||||
can act as a stand alone application and launched from an application
|
||||
launcher.
|
||||
Generates a '.desktop' file for a web application, so that it can act as a stand alone application and
|
||||
be launched from an application launcher.
|
||||
|
||||
USAGE: install-webapp [-n <name>] [-u <url>] [-i <icon>] [-e <exec-cmd>] [-m <mime-types>] [-f <file>] [-h] [args...]
|
||||
USAGE: $THIS [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-n | --name: The name of the application.
|
||||
-u | --url: The url used to launch the application.
|
||||
-i | --icon: The icon for the application.
|
||||
-e | --exec: Custom execution command (optional).
|
||||
-m | --mime-types: MIME-types for the application (optional).
|
||||
-f | --file: Install from a spec in a json file.
|
||||
-n | --name <name>: The name of the application.
|
||||
|
||||
-u | --url <url>: The url used to launch the application.
|
||||
|
||||
-i | --icon <icon>: The icon for the application.
|
||||
|
||||
-e | --exec <cmd>: Custom execution command (optional).
|
||||
|
||||
-m | --mime-types <types>: MIME-types for the application (optional).
|
||||
|
||||
-f | --file <file>: Install from a spec in a json file.
|
||||
|
||||
-l | --launch: Launches in a new terminal window in interactive mode.
|
||||
|
||||
--no-interactive: Don't proceed to interactive mode. If required properties aren't set,
|
||||
then error. This is useful if using '--file' and there are parsing errors
|
||||
or missing properties.
|
||||
|
||||
--dry-run: Run in dry-run mode, which doesn't generate files or download icons.
|
||||
|
||||
-h | --help: Show usage information.
|
||||
|
||||
EXAMPLES:
|
||||
@@ -26,25 +39,18 @@ EXAMPLES:
|
||||
If no options or arguments are supplied, then it will start an interactive session that prompts for the
|
||||
values.
|
||||
|
||||
$ install-webapp
|
||||
$ $THIS
|
||||
|
||||
Calling the app with named arguments:
|
||||
|
||||
$ install-webapp \\
|
||||
$ $THIS \\
|
||||
--name "My Awesome App" \\
|
||||
--url "https://awesome.com" \\
|
||||
--icon "https://awesome.com/assets/icon.png"
|
||||
|
||||
Using a json file as input:
|
||||
|
||||
$ install-webapp --file myapp.json
|
||||
|
||||
It is also possible to use only positional arguments with out their key. They can be passed in the order as
|
||||
they're listed.
|
||||
|
||||
$ install-webapp "My Awesome App" \\
|
||||
"https://awesome.com" \\
|
||||
"https://awesome.com/assets/icon.png"
|
||||
$ $THIS --file myapp.json
|
||||
|
||||
NOTES:
|
||||
|
||||
@@ -55,7 +61,7 @@ Interactive sessions do not give the option to use a custom execution command or
|
||||
MIME types, which are less frequently used options.
|
||||
|
||||
If using a json spec file, all keys are the same as their option name, except for mime-types use 'mime_types' as the
|
||||
key in the json object. Although the 'exec' and 'mime_types' are not required in the spec file. An common json spec
|
||||
key in the json object. Although the 'exec' and 'mime_types' are not required in the spec file. A common json spec
|
||||
file example would look like:
|
||||
|
||||
{
|
||||
@@ -67,138 +73,238 @@ file example would look like:
|
||||
EOF
|
||||
}
|
||||
|
||||
declare -a app_name
|
||||
declare -a app_url
|
||||
declare -a icon_ref
|
||||
declare -a custom_exec # Optional custom exec command
|
||||
declare -a mime_types # Optional mime types
|
||||
declare -a help_flag
|
||||
declare -a file_mode
|
||||
declare -a launch_flag
|
||||
declare INTERACTIVE_MODE=false
|
||||
SCRIPTS="${SCRIPTS}"
|
||||
|
||||
window_class="com.ghostty.launch-webapp"
|
||||
window_class="com.ghostty.install-webapp"
|
||||
window_padding_x="2"
|
||||
|
||||
app_name=""
|
||||
app_url=""
|
||||
exec_cmd=""
|
||||
dry_run="0"
|
||||
file_mode_flag="0"
|
||||
icon_ref=""
|
||||
json_file=""
|
||||
mime_types=""
|
||||
launch_flag="0"
|
||||
interactive_flag="0" # This is an internal flag, to not log some things when launch is used.
|
||||
interactive_mode=false
|
||||
no_interactive_flag="0"
|
||||
SCRIPTS="${SCRIPTS}"
|
||||
XDG_DATA_HOME=${XDG_DATA_HOME}
|
||||
|
||||
if [[ -z "$SCRIPTS" ]]; then
|
||||
echo "SCRIPTS not set"
|
||||
echo "using ~/.local/scripts"
|
||||
SCRIPTS=$HOME/.local/scripts
|
||||
fi
|
||||
|
||||
zparseopts -D -F -K -- \
|
||||
{n,-name}:=app_name \
|
||||
{u,-url}:=app_url \
|
||||
{i,-icon}:=icon_ref \
|
||||
{e,-exec}:=custom_exec \
|
||||
{m,-mime-types}:=mime_types \
|
||||
{f,-file}:=file_mode \
|
||||
{h,-help}=help_flag \
|
||||
{l,-launch}=launch_flag
|
||||
if [[ -z "$XDG_DATA_HOME" ]]; then
|
||||
echo "XDG_DATA_HOME not set"
|
||||
echo "using ~/.local/share"
|
||||
XDG_DATA_HOME=$HOME/.local/share
|
||||
fi
|
||||
|
||||
[ ${#help_flag[@]} -gt 0 ] && usage && exit 0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
if [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
|
||||
usage && exit 0
|
||||
elif [[ $1 == "-n" ]] || [[ $1 == "--name" ]]; then
|
||||
shift
|
||||
app_name=$1
|
||||
elif [[ $1 == "-u" ]] || [[ $1 == "--url" ]]; then
|
||||
shift
|
||||
app_url=$1
|
||||
elif [[ $1 == "-i" ]] || [[ $1 == "--icon" ]]; then
|
||||
shift
|
||||
icon_ref=$1
|
||||
elif [[ $1 == "-e" ]] || [[ $1 == "--exec" ]]; then
|
||||
shift
|
||||
exec_cmd=$1
|
||||
elif [[ $1 == "-m" ]] || [[ $1 == "--mime-types" ]]; then
|
||||
shift
|
||||
mime_types=$1
|
||||
elif [[ $1 == "-f" ]] || [[ $1 == "--file" ]]; then
|
||||
file_mode_flag="1"
|
||||
shift
|
||||
json_file=$1
|
||||
elif [[ $1 == "-l" ]] || [[ $1 == "--launch" ]]; then
|
||||
launch_flag="1"
|
||||
elif [[ $1 == "--interactive" ]]; then
|
||||
interactive_flag="1"
|
||||
elif [[ $1 == "--no-interactive" ]]; then
|
||||
no_interactive_flag="1"
|
||||
elif [[ $1 =~ ^--dry ]]; then
|
||||
dry_run="1"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ ${#launch_flag[@]} -gt 0 ]]; then
|
||||
log() {
|
||||
if [[ $dry_run == "1" ]]; then
|
||||
echo -e "\e[34m[DRY_RUN]=>\e[0m $1"
|
||||
else
|
||||
echo -e "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_error() {
|
||||
log "\e[31m[ERROR]:\e[0m $1"
|
||||
}
|
||||
|
||||
launch() {
|
||||
ghostty --class=$window_class --window-padding-x=$window_padding_x \
|
||||
--keybind="ctrl+c=quit" \
|
||||
-e $SCRIPTS/hypr/install-webapp
|
||||
exit 0
|
||||
-e "${BASH_SOURCE[0]}" --interactive
|
||||
}
|
||||
|
||||
check_properties() {
|
||||
if [[ -z $app_name ]] || [[ -z $app_url ]] || [[ -z $icon_ref ]]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
load_from_file() {
|
||||
if [[ ! -f $1 ]]; then
|
||||
log_error "File '$1' is not found or readable." && exit 1
|
||||
fi
|
||||
file=$(cat $1)
|
||||
app_name=$(echo $file | jq -r '.name // ""')
|
||||
app_url=$(echo $file | jq -r '.url // ""')
|
||||
icon_ref=$(echo $file | jq -r '.icon // ""')
|
||||
exec_cmd=$(echo $file | jq -r '.exec // ""')
|
||||
mime_types=$(echo $file | jq -r '.mime_types // ""')
|
||||
}
|
||||
|
||||
print_properties() {
|
||||
log "\e[33mAPP NAME:\e[0m $app_name"
|
||||
log "\e[33mURL:\e[0m $app_url"
|
||||
log "\e[33mICON:\e[0m $icon_ref"
|
||||
log "\e[33mEXEC:\e[0m $exec_cmd"
|
||||
log "\e[33mMIME:\e[0m $mime_types"
|
||||
}
|
||||
|
||||
prompt_for_properties() {
|
||||
log "\e[32mLet's create a new web app you can start with the app launcher.\n\e[0m"
|
||||
|
||||
if [[ -z $app_name ]]; then
|
||||
app_name=$(gum input --prompt "Name> " --placeholder "My favorite web app")
|
||||
fi
|
||||
|
||||
# If passed in as positional arguments, without flags.
|
||||
[ -n "$1" ] && app_name+=("$1")
|
||||
[ -n "$2" ] && app_url+=("$2")
|
||||
[ -n "$3" ] && icon_ref+=("$3")
|
||||
[ -n "$4" ] && custom_exec+=("$4")
|
||||
[ -n "$5" ] && mime_types+=("$5")
|
||||
|
||||
# If passed in a json spec file.
|
||||
if [[ -n "$file_mode" ]]; then
|
||||
file=$(cat ${file_mode[-1]})
|
||||
app_name+=$(echo $file | jq -r '.name')
|
||||
app_url+=$(echo $file | jq -r '.url')
|
||||
icon_ref+=$(echo $file | jq -r '.icon')
|
||||
custom_exec+=$(echo $file | jq -r '.exec')
|
||||
mime_types+=$(echo $file | jq -r '.mime_types')
|
||||
if [[ -z $app_url ]]; then
|
||||
app_url=$(gum input --prompt "URL> " --placeholder "https://example.com")
|
||||
fi
|
||||
|
||||
# Check if proper arguments were passed in. Start interactive mode if not.
|
||||
if [[ -z "$app_name[-1]" || -z "$app_url[-1]" || -z "$icon_ref[-1]" ]]; then
|
||||
echo -e "\e[32mLet's create a new web app you can start with the app launcher.\n\e[0m"
|
||||
app_name+=($(gum input --prompt "Name> " --placeholder "My favorite web app"))
|
||||
app_url+=($(gum input --prompt "URL> " --placeholder "https://example.com"))
|
||||
icon_ref+=($(gum input --prompt "Icon URL> " --placeholder "See https://dashboardicons.com (must use PNG!)"))
|
||||
INTERACTIVE_MODE=true
|
||||
else
|
||||
INTERACTIVE_MODE=false
|
||||
if [[ -z $icon_ref ]]; then
|
||||
icon_ref=$(gum input --prompt "Icon URL> " --placeholder "See https://dashboardicons.com (must use PNG!)")
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure valid execution
|
||||
if [[ -z "$app_name[-1]" || "$app_name[-1]" == "null" ||
|
||||
-z "$app_url[-1]" || "$app_url[-1]" == "null" ||
|
||||
-z "$icon_ref[-1]" || "$icon_ref[-1]" == "null" ]]; then
|
||||
echo "You must set app name, app URL, and icon URL!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP_NAME=$app_name[-1]
|
||||
APP_URL=$app_url[-1]
|
||||
ICON_REF=$icon_ref[-1]
|
||||
CUSTOM_EXEC=$custom_exec[-1]
|
||||
MIME_TYPES=$mime_types[-1]
|
||||
|
||||
set_icon_ref() {
|
||||
# Refer to local icon or fetch remotely from URL
|
||||
ICON_DIR="$HOME/.local/share/applications/icons"
|
||||
# Ensure the icon directory exists (useful if it's the first run.)
|
||||
[ ! -d $ICON_DIR ] && mkdir -p $ICON_DIR
|
||||
local icon_dir="$XDG_DATA_HOME/applications/icons"
|
||||
local icon_path=""
|
||||
|
||||
if [[ $ICON_REF == https://* ]]; then
|
||||
ICON_PATH="$ICON_DIR/$APP_NAME.png"
|
||||
if curl -sL -o "$ICON_PATH" "$ICON_REF"; then
|
||||
ICON_PATH="$ICON_DIR/$APP_NAME.png"
|
||||
# Ensure the icon directory exists (useful if it's the first run.)
|
||||
[ ! -d $icon_dir ] && mkdir -p $icon_dir
|
||||
|
||||
if [[ $icon_ref == https://* ]]; then
|
||||
icon_path="$icon_dir/$app_name.png"
|
||||
log "Downloading icon: $icon_ref"
|
||||
if [[ $dry_run == "0" ]]; then
|
||||
if curl -sL -o "$icon_path" "$icon_ref"; then
|
||||
icon_path="$icon_dir/$app_name.png"
|
||||
else
|
||||
echo "Error: Failed to download icon."
|
||||
exit 1
|
||||
log_error "Failed to download icon." && exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Check if the icon path is a file.
|
||||
if [ -f $ICON_REF ]; then
|
||||
ICON_PATH=$ICON_REF
|
||||
if [ -f $icon_ref ]; then
|
||||
icon_path=$icon_ref
|
||||
else
|
||||
ICON_PATH="$ICON_DIR/$ICON_REF"
|
||||
icon_path="$icon_dir/$icon_ref"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Use custom exec if provided, otherwise default behavior
|
||||
if [[ -n $CUSTOM_EXEC ]] && [[ ! $CUSTOM_EXEC == "null" ]]; then
|
||||
EXEC_COMMAND="$CUSTOM_EXEC"
|
||||
else
|
||||
EXEC_COMMAND="${SCRIPTS:-$HOME/.local/scripts}/hypr/launch-webapp $APP_URL"
|
||||
fi
|
||||
icon_ref=$icon_path
|
||||
}
|
||||
|
||||
# Create application .desktop file
|
||||
DESKTOP_FILE="$HOME/.local/share/applications/$APP_NAME.desktop"
|
||||
generate_file() {
|
||||
|
||||
cat >"$DESKTOP_FILE" <<EOF
|
||||
cat >"$1" <<EOF
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=$APP_NAME
|
||||
Comment=$APP_NAME
|
||||
Exec=$EXEC_COMMAND
|
||||
Name=$app_name
|
||||
Comment=$app_name
|
||||
Exec=$exec_cmd
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=$ICON_PATH
|
||||
Icon=$icon_ref
|
||||
StartupNotify=true
|
||||
EOF
|
||||
|
||||
# Add mime types if provided
|
||||
if [[ -n $MIME_TYPES ]] && [[ ! $MIME_TYPES == "null" ]]; then
|
||||
echo "MimeType=$MIME_TYPES" >>"$DESKTOP_FILE"
|
||||
if [[ -n $mime_types ]]; then
|
||||
echo "MimeType=$mime_types" >>"$1"
|
||||
fi
|
||||
|
||||
chmod +x "$DESKTOP_FILE"
|
||||
chmod +x "$1"
|
||||
}
|
||||
|
||||
if [[ $INTERACTIVE_MODE == true ]]; then
|
||||
echo -e "You can now find $APP_NAME using the app launcher (SUPER + SPACE)\n"
|
||||
################################################################################
|
||||
# MAIN
|
||||
################################################################################
|
||||
|
||||
if [[ $launch_flag == "1" ]]; then
|
||||
launch && exit 0
|
||||
fi
|
||||
|
||||
if [[ $file_mode_flag == "1" ]]; then
|
||||
load_from_file $json_file
|
||||
fi
|
||||
|
||||
# Check that all properties are set, prompt for missing values if not.
|
||||
check_properties
|
||||
if [[ "$?" == "1" ]]; then
|
||||
|
||||
# Check if the '--no-interactive' flag was passed and exit with error.
|
||||
[[ $no_interactive_flag == "1" ]] &&
|
||||
log_error "Required properties not set and '--no-interactive' flag was passed." &&
|
||||
exit 1
|
||||
|
||||
# Only log this if not in interactive mode.
|
||||
[[ $interactive_mode == "0" ]] &&
|
||||
log "All required properties not set, prompting for missing properties."
|
||||
|
||||
prompt_for_properties
|
||||
|
||||
# Check properties again after prompting in interactive mode.
|
||||
check_properties
|
||||
if [[ "$?" == "1" ]]; then
|
||||
# Exit if they were not set during interactive mode.
|
||||
log_error "You must set app name, app URL, and icon URL!" && exit 1
|
||||
fi
|
||||
|
||||
# Set flag that we are in interactive mode.
|
||||
interactive_mode=true
|
||||
fi
|
||||
|
||||
desktop_file="$XDG_DATA_HOME/applications/$app_name.desktop"
|
||||
|
||||
# Parse the icon ref and download icon, if applicable.
|
||||
set_icon_ref
|
||||
|
||||
# Check that an exec command is set, or default to the 'launch-webapp' script.
|
||||
if [[ -z $exec_cmd ]]; then
|
||||
exec_cmd="$SCRIPTS/hypr/launch-webapp $app_url"
|
||||
fi
|
||||
|
||||
log "\e[032mCreating web app:\e[0m $desktop_file"
|
||||
print_properties
|
||||
|
||||
if [[ $dry_run == "0" ]]; then
|
||||
generate_file $desktop_file
|
||||
fi
|
||||
|
||||
if [[ $interactive_mode == true ]] && [[ $dry_run == "0" ]]; then
|
||||
log "You can now find $app_name using the app launcher (SUPER + SPACE)\n"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user