-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-pwa.sh
More file actions
executable file
·171 lines (140 loc) · 4.93 KB
/
Copy pathcreate-pwa.sh
File metadata and controls
executable file
·171 lines (140 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env bash
set -euo pipefail
# Create a Chrome/Chromium "PWA-style" launcher for a URL.
# - Auto-downloads a site icon (favicon / apple-touch-icon best-effort)
# - Removes/replaces any existing launcher + icon for the same URL-derived app id
# - Supports Google Chrome and Chromium
#
# Usage:
# ./create-pwa.sh https://regex101.com/
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <url>"
exit 1
fi
URL="$1"
# -------- helpers --------
have() { command -v "$1" >/dev/null 2>&1; }
pick_browser() {
if have google-chrome; then echo "google-chrome"; return; fi
if have google-chrome-stable; then echo "google-chrome-stable"; return; fi
if have chromium-browser; then echo "chromium-browser"; return; fi
if have chromium; then echo "chromium"; return; fi
echo "ERROR: Neither Google Chrome nor Chromium found. Install one first." >&2
exit 1
}
host_from_url() {
echo "$1" | sed -E 's#^[a-zA-Z]+://##; s#/.*##'
}
safe_slug() {
echo "$1" \
| tr '[:upper:]' '[:lower:]' \
| sed -E 's/[^a-z0-9]+/-/g; s/^-+|-+$//g; s/-+/-/g'
}
BROWSER="$(pick_browser)"
HOST="$(host_from_url "$URL")"
SLUG="$(safe_slug "$HOST")"
APP_NAME="$HOST"
APP_ID="${SLUG}-pwa"
APP_CLASS="$(echo "$SLUG" | sed -E 's/(^|[-_])([a-z])/\U\2/g')"PWA
ICON_DIR="$HOME/.local/share/icons"
APP_DIR="$HOME/.local/share/applications"
DESKTOP_FILE="$APP_DIR/${APP_ID}.desktop"
ICON_FILE="$ICON_DIR/${APP_ID}.png"
USER_DATA_DIR="$HOME/.config/${APP_ID}"
mkdir -p "$ICON_DIR" "$APP_DIR"
# -------- remove existing launcher/icon (if any) --------
rm -f "$DESKTOP_FILE" "$ICON_FILE"
if [[ -d "$HOME/Desktop" ]]; then
rm -f "$HOME/Desktop/${APP_ID}.desktop"
fi
# -------- icon download (best-effort) --------
download_icon() {
local url="$1"
local tmpdir base html href icon_url ext
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' RETURN
if ! have curl; then
echo "Note: curl not found; skipping icon download."
return 0
fi
base="$(echo "$url" | sed -E 's#^(https?://[^/]+).*$#\1#')"
# Common favicon locations
if curl -fsSL "${base}/favicon.ico" -o "${tmpdir}/favicon.ico" 2>/dev/null; then
if have convert; then
convert "${tmpdir}/favicon.ico" "${tmpdir}/icon.png" 2>/dev/null || true
fi
if [[ -f "${tmpdir}/icon.png" ]]; then
cp -f "${tmpdir}/icon.png" "$ICON_FILE"
return 0
fi
# Best-effort fallback if no conversion available
cp -f "${tmpdir}/favicon.ico" "$ICON_FILE" || true
return 0
fi
if curl -fsSL "${base}/apple-touch-icon.png" -o "${tmpdir}/icon.png" 2>/dev/null; then
cp -f "${tmpdir}/icon.png" "$ICON_FILE"
return 0
fi
# Parse HTML for <link rel="icon"...> or <link rel="apple-touch-icon"...>
html="$(curl -fsSL "$url" 2>/dev/null || true)"
[[ -z "$html" ]] && return 0
href="$(echo "$html" | tr '\n' ' ' \
| grep -oiE '<link[^>]+rel="(apple-touch-icon|icon)"[^>]*>' \
| head -n 1 \
| sed -nE 's/.*href="([^"]+)".*/\1/p' || true)"
[[ -z "$href" ]] && return 0
icon_url="$href"
if [[ "$icon_url" =~ ^// ]]; then
icon_url="https:${icon_url}"
elif [[ "$icon_url" =~ ^/ ]]; then
icon_url="${base}${icon_url}"
elif [[ ! "$icon_url" =~ ^https?:// ]]; then
icon_url="${base}/${icon_url}"
fi
ext="$(echo "$icon_url" | sed -nE 's/.*\.([a-zA-Z0-9]+)(\?.*)?$/\1/p' | tr '[:upper:]' '[:lower:]')"
curl -fsSL "$icon_url" -o "${tmpdir}/icon.${ext:-bin}" 2>/dev/null || true
[[ ! -f "${tmpdir}/icon.${ext:-bin}" ]] && return 0
# ✅ FIX: don't mix command calls inside [[ ... ]]
if [[ "$ext" == "svg" ]] && have convert; then
convert "${tmpdir}/icon.svg" "${tmpdir}/icon.png" 2>/dev/null || true
[[ -f "${tmpdir}/icon.png" ]] && cp -f "${tmpdir}/icon.png" "$ICON_FILE"
else
cp -f "${tmpdir}/icon.${ext:-bin}" "$ICON_FILE" || true
fi
}
download_icon "$URL" || true
# If icon download failed, use a fallback icon name
ICON_FIELD="$ICON_FILE"
if [[ ! -s "$ICON_FILE" ]]; then
ICON_FIELD="web-browser"
fi
# -------- create desktop launcher --------
cat > "$DESKTOP_FILE" <<EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=${APP_NAME}
Comment=${APP_NAME} (app-mode launcher)
Exec=${BROWSER} --app=${URL} --class=${APP_CLASS} --user-data-dir=${USER_DATA_DIR}
Terminal=false
Icon=${ICON_FIELD}
Categories=Network;Development;
StartupWMClass=${APP_CLASS}
EOF
chmod +x "$DESKTOP_FILE"
# -------- optional: copy to Desktop (Ubuntu) --------
if [[ -d "$HOME/Desktop" ]]; then
cp -f "$DESKTOP_FILE" "$HOME/Desktop/${APP_ID}.desktop"
chmod +x "$HOME/Desktop/${APP_ID}.desktop"
echo "Desktop shortcut created at: $HOME/Desktop/${APP_ID}.desktop"
echo "Tip: Right-click it and choose 'Allow Launching' if Ubuntu prompts you."
fi
# -------- launch normal tab + app window --------
"${BROWSER}" "$URL" >/dev/null 2>&1 &
"${BROWSER}" --app="${URL}" --class="${APP_CLASS}" --user-data-dir="${USER_DATA_DIR}" >/dev/null 2>&1 &
echo "Created/updated launcher:"
echo " $DESKTOP_FILE"
echo "App Name: $APP_NAME"
echo "URL: $URL"
echo "Browser: $BROWSER"
echo "Icon: $ICON_FIELD"