Last active
February 23, 2025 19:49
-
-
Save daninsky1/e773b240ad0139cf8cacb5ba57e1da12 to your computer and use it in GitHub Desktop.
Install PWAs on Linux and Unix-like systems.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Public domain. | |
VERSION=0.1 | |
show_help() { | |
cat <<END | |
Version $VERSION | |
Usage: $0 [OPTION] | |
Creates a web app launcher for Chromium based browsers. | |
Options: | |
-i <APP_NAME> <URL> [BROWSER] Install PWA app for URL. | |
-u <APP_NAME> Uninstall PWA app. | |
-l List PWAs installed with this script in | |
'\${HOME}/.local/share/applications'. | |
-h Show this help message and exit. | |
Arguments: | |
URL Web address for the PWA, e.g., https://example.com. | |
APP_NAME Specific name of the application, e.g., "Example App". | |
BROWSER Optional Chromium based browser executable (default: chromium). | |
END | |
} | |
create_app_id() { | |
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | awk '{print $1"-pwa"}' | |
} | |
DESKTOP_MENU_PATH="${HOME}/.local/share/applications" | |
FAVICON_SIZES="256 128 96 64 48 32 24 16" | |
install() { | |
MIN_ARGS="2" | |
MAX_ARGS="3" | |
if [ $# -ne "$MIN_ARGS" ] && [ $# -ne "$MAX_ARGS" ]; then | |
echo "Error: Expected $MIN_ARGS or $MAX_ARGS arguments, but got $#." >&2 | |
show_help | |
exit 1 | |
fi | |
BROWSER=$3 | |
if [ -z "$BROWSER" ]; then | |
BROWSER=chromium | |
fi | |
BROWSER_CMD=$(command -v "$BROWSER") | |
if [ -z "$BROWSER_CMD" ]; then | |
echo "Error: '${BROWSER}' is not installed." >&2 | |
exit 1 | |
fi | |
URL=$2 | |
APP_NAME=$1 | |
DOMAIN=$(echo "$URL" | awk -F/ '{print $3}') | |
APP_ID=$(create_app_id "$APP_NAME") | |
mkdir -p "$DESKTOP_MENU_PATH" | |
DESKTOP_MENU_FILE="${DESKTOP_MENU_PATH}/${APP_ID}.desktop" | |
cat > "$DESKTOP_MENU_FILE" <<END | |
#!/usr/bin/env xdg-open | |
[Desktop Entry] | |
Version=1.0 | |
Terminal=false | |
Type=Application | |
Name=${APP_NAME} | |
Exec=${BROWSER_CMD} --profile-directory=Default --app=${URL} | |
Icon=${APP_ID%.*} | |
StartupWMClass=${DOMAIN} | |
END | |
chmod +x "$DESKTOP_MENU_FILE" | |
if command -v update-desktop-database > /dev/null 2>&1; then | |
update-desktop-database "$DESKTOP_MENU_PATH" | |
fi | |
echo "created: '${DESKTOP_MENU_FILE}'" | |
for size in $FAVICON_SIZES; do | |
( | |
FAVICON_SERVICE_URL="https://www.google.com/s2/favicons?domain=${URL}&sz=${size}" | |
TMP_ICON=$(mktemp /tmp/tmp.XXXXXXXX.png) | |
curl -sLo "$TMP_ICON" "$FAVICON_SERVICE_URL" | |
FILE_FMT=$(file --brief "$TMP_ICON") | |
if ! echo "$FILE_FMT" | grep -q "PNG image data"; then | |
echo "${size}x${size} icon must be a PNG image data instead got: ${FILE_FMT}." | |
rm -f "$TMP_ICON" | |
continue | |
fi | |
xdg-icon-resource install --size "$size" "$TMP_ICON" "$APP_ID" | |
) & | |
done | |
echo "installed icons '${APP_ID}' successfully." | |
wait | |
echo "Web app '${APP_NAME}' created successfully!" | |
} | |
uninstall() { | |
NUM_ARGS="1" | |
if [ $# -ne "$NUM_ARGS" ]; then | |
echo "Error: Expected ${NUM_ARGS} arguments, but got $#." >&2 | |
show_help | |
exit 1 | |
fi | |
APP_NAME=$1 | |
APP_ID=$(create_app_id "$APP_NAME") | |
DESKTOP_MENU_FILE="${DESKTOP_MENU_PATH}/${APP_ID}.desktop" | |
if [ ! -e "$DESKTOP_MENU_FILE" ]; then | |
echo "PWA app '${APP_NAME}' is not installed." | |
exit 1 | |
fi | |
rm -f "$DESKTOP_MENU_FILE" | |
for size in $FAVICON_SIZES; do | |
xdg-icon-resource uninstall --size "$size" "$APP_ID" | |
done | |
echo "removed: '${DESKTOP_MENU_FILE}'" | |
echo "removed icons '${APP_ID}' successfully." | |
echo "Web app '${APP_NAME}' uninstalled successfully!" | |
} | |
list() { | |
if [ ! -d "$DESKTOP_MENU_PATH" ]; then return 0; fi | |
for desktop_file in "${DESKTOP_MENU_PATH}/*-pwa.desktop"; do | |
echo " - $(grep -m 1 "^Name=" "$desktop_file" | cut -d '=' -f2)" | |
done | |
} | |
while getopts "iulh" opts; do | |
case "$opts" in | |
i) shift $((OPTIND - 1)); install "$@"; exit 0 ;; | |
u) shift $((OPTIND - 1)); uninstall "$@"; exit 0 ;; | |
l) list; exit 0 ;; | |
h) show_help ; exit 0 ;; | |
*) show_help; exit 1 ;; | |
esac | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment