added create-webapp.sh - via claude
parent
69f5b3c13b
commit
242a544909
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env bash
|
||||
# Creates a Chromium webapp .desktop entry with favicon as icon.
|
||||
# Usage: create-webapp.sh <url> [display-name]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $(basename "$0") <url> [display-name]"
|
||||
echo
|
||||
echo " Fetches the page title and favicon, then writes a .desktop"
|
||||
echo " entry that opens the URL in Chromium app-window mode (no tabs/address bar)."
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ $# -lt 1 ]] && usage
|
||||
|
||||
URL="$1"
|
||||
CUSTOM_NAME="${2:-}"
|
||||
|
||||
# Ensure scheme
|
||||
[[ "$URL" != http://* && "$URL" != https://* ]] && URL="https://$URL"
|
||||
|
||||
BASE_URL=$(echo "$URL" | grep -oE 'https?://[^/]+')
|
||||
DOMAIN=$(echo "$BASE_URL" | sed -E 's|https?://(www\.)?||')
|
||||
|
||||
echo "Fetching: $URL"
|
||||
PAGE_HTML=$(curl -sL --max-time 15 \
|
||||
-A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \
|
||||
"$URL" 2>/dev/null || echo "")
|
||||
|
||||
# Resolve app name from <title> or argument
|
||||
if [[ -n "$CUSTOM_NAME" ]]; then
|
||||
APP_NAME="$CUSTOM_NAME"
|
||||
else
|
||||
APP_NAME=$(echo "$PAGE_HTML" | python3 -c '
|
||||
import sys, re, html as html_mod
|
||||
content = sys.stdin.read()
|
||||
m = re.search(r"<title[^>]*>([^<]+)</title>", content, re.IGNORECASE)
|
||||
print(html_mod.unescape(m.group(1).strip()) if m else "", end="")
|
||||
' 2>/dev/null || true)
|
||||
APP_NAME="${APP_NAME:-$DOMAIN}"
|
||||
fi
|
||||
|
||||
# Safe identifier for filenames / WM_CLASS
|
||||
SAFE_ID=$(echo "$APP_NAME" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-*//;s/-*$//')
|
||||
[[ -z "$SAFE_ID" ]] && SAFE_ID="$DOMAIN"
|
||||
|
||||
# Find best favicon from HTML link tags (largest declared size wins)
|
||||
FAVICON_URL=$(echo "$PAGE_HTML" | python3 -c '
|
||||
import sys, re
|
||||
from urllib.parse import urljoin
|
||||
|
||||
base = sys.argv[1]
|
||||
content = sys.stdin.read()
|
||||
|
||||
candidates = []
|
||||
for link in re.findall(r"<link([^>]+?)/??>", content, re.IGNORECASE | re.DOTALL):
|
||||
rel_m = re.search(r"rel=[\"'"'"']([^\"'"'"']+)[\"'"'"']", link, re.IGNORECASE)
|
||||
if not rel_m or "icon" not in rel_m.group(1).lower():
|
||||
continue
|
||||
href_m = re.search(r"href=[\"'"'"']([^\"'"'"']+)[\"'"'"']", link, re.IGNORECASE)
|
||||
if not href_m:
|
||||
continue
|
||||
size = 0
|
||||
sizes_m = re.search(r"sizes=[\"'"'"']([^\"'"'"']+)[\"'"'"']", link, re.IGNORECASE)
|
||||
if sizes_m:
|
||||
val = sizes_m.group(1).lower().split("x")[0]
|
||||
try:
|
||||
size = 999 if val == "any" else int(val)
|
||||
except ValueError:
|
||||
pass
|
||||
candidates.append((size, href_m.group(1)))
|
||||
|
||||
if candidates:
|
||||
candidates.sort(key=lambda x: x[0], reverse=True)
|
||||
print(urljoin(base, candidates[0][1]), end="")
|
||||
' "$BASE_URL" 2>/dev/null || true)
|
||||
|
||||
FAVICON_URL="${FAVICON_URL:-$BASE_URL/favicon.ico}"
|
||||
echo "Favicon: $FAVICON_URL"
|
||||
|
||||
# Download icon
|
||||
ICON_DIR="$HOME/.local/share/icons/webapps"
|
||||
mkdir -p "$ICON_DIR"
|
||||
|
||||
TMP=$(mktemp /tmp/webapp-icon.XXXXXX)
|
||||
trap 'rm -f "$TMP"' EXIT
|
||||
|
||||
ICON_PATH="chromium" # fallback
|
||||
|
||||
if curl -sL --max-time 10 -A "Mozilla/5.0" -o "$TMP" "$FAVICON_URL" && [[ -s "$TMP" ]]; then
|
||||
if command -v convert &>/dev/null \
|
||||
&& convert "${TMP}[0]" -resize 128x128\> "${ICON_DIR}/${SAFE_ID}.png" 2>/dev/null; then
|
||||
ICON_PATH="${ICON_DIR}/${SAFE_ID}.png"
|
||||
echo "Icon: $ICON_PATH (PNG via ImageMagick)"
|
||||
else
|
||||
MIME=$(file -b --mime-type "$TMP")
|
||||
EXT="${MIME##*/}"
|
||||
[[ "$EXT" == "x-icon" || "$EXT" == "vnd.microsoft.icon" ]] && EXT="ico"
|
||||
cp "$TMP" "${ICON_DIR}/${SAFE_ID}.${EXT}"
|
||||
ICON_PATH="${ICON_DIR}/${SAFE_ID}.${EXT}"
|
||||
echo "Icon: $ICON_PATH ($MIME)"
|
||||
fi
|
||||
else
|
||||
echo "Warning: could not fetch favicon — using chromium default icon"
|
||||
fi
|
||||
|
||||
# Write .desktop file
|
||||
DESKTOP_DIR="$HOME/.local/share/applications"
|
||||
mkdir -p "$DESKTOP_DIR"
|
||||
DESKTOP_FILE="${DESKTOP_DIR}/webapp-${SAFE_ID}.desktop"
|
||||
|
||||
cat > "$DESKTOP_FILE" << DESKTOP
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=${APP_NAME}
|
||||
Exec=chromium --app=${URL}
|
||||
Icon=${ICON_PATH}
|
||||
Terminal=false
|
||||
Categories=Network;WebBrowser;
|
||||
StartupWMClass=${SAFE_ID}
|
||||
DESKTOP
|
||||
|
||||
chmod +x "$DESKTOP_FILE"
|
||||
|
||||
echo
|
||||
echo "Created : $DESKTOP_FILE"
|
||||
echo " Name : $APP_NAME"
|
||||
echo " URL : $URL"
|
||||
echo " Icon : $ICON_PATH"
|
||||
Loading…
Reference in New Issue