projects/vpn: browsergebundene VPN-Tray-Apps (Wuerth/Heron) + Build-Scripts
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env bash
|
||||
# Baut HeronVPN.app via py2app (Menuebar-Only, kein Dock via LSUIElement),
|
||||
# generiert ein "H"-Icon, duennt aus, installiert nach ~/Applications und legt
|
||||
# einen LaunchAgent fuer optionalen Autostart bereit.
|
||||
set -euo pipefail
|
||||
|
||||
PY="/Library/Developer/CommandLineTools/usr/bin/python3"
|
||||
APPS="$HOME/apps"
|
||||
APP="$HOME/Applications/HeronVPN.app"
|
||||
BID="com.heron.vpntray"
|
||||
LSREG=/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister
|
||||
|
||||
cd "$APPS"
|
||||
|
||||
# --- 0. Icon erzeugen (H-Badge -> icon_heron.icns) ---
|
||||
TMP="$(mktemp -d)"
|
||||
QT_QPA_PLATFORM=offscreen "$PY" - "$TMP/h.png" <<'PYEOF'
|
||||
import sys
|
||||
from PyQt6.QtGui import QImage, QPainter, QColor, QFont, QGuiApplication
|
||||
from PyQt6.QtCore import Qt
|
||||
_app = QGuiApplication([]) # noetig fuer Font-Zugriff
|
||||
S = 1024
|
||||
img = QImage(S, S, QImage.Format.Format_ARGB32)
|
||||
img.fill(Qt.GlobalColor.transparent)
|
||||
p = QPainter(img)
|
||||
p.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
p.setBrush(QColor("#2e7d32"))
|
||||
p.setPen(Qt.PenStyle.NoPen)
|
||||
m = int(S * 0.09)
|
||||
p.drawRoundedRect(m, m, S - 2 * m, S - 2 * m, S * 0.18, S * 0.18)
|
||||
p.setPen(QColor("#ffffff"))
|
||||
f = QFont(); f.setBold(True); f.setPixelSize(int(S * 0.6)); p.setFont(f)
|
||||
p.drawText(img.rect(), Qt.AlignmentFlag.AlignCenter, "H")
|
||||
p.end()
|
||||
img.save(sys.argv[1])
|
||||
PYEOF
|
||||
ISET="$TMP/icon.iconset"; mkdir -p "$ISET"
|
||||
for s in 16 32 128 256 512; do
|
||||
sips -z $s $s "$TMP/h.png" --out "$ISET/icon_${s}x${s}.png" >/dev/null
|
||||
sips -z $((s*2)) $((s*2)) "$TMP/h.png" --out "$ISET/icon_${s}x${s}@2x.png" >/dev/null
|
||||
done
|
||||
iconutil -c icns "$ISET" -o "$APPS/icon_heron.icns"
|
||||
rm -rf "$TMP"
|
||||
|
||||
# --- 1. Bauen ---
|
||||
rm -rf build dist
|
||||
"$PY" setup_heron.py py2app >/tmp/heron_py2app.log 2>&1 || { tail -20 /tmp/heron_py2app.log; exit 1; }
|
||||
|
||||
# --- 2. Nach ~/Applications uebernehmen ---
|
||||
pkill -f "HeronVPN.app/Contents/MacOS/HeronVPN" 2>/dev/null || true
|
||||
rm -rf "$APP"
|
||||
cp -R "$APPS/dist/HeronVPN.app" "$APP"
|
||||
|
||||
# --- 2b. Ausduennen (wie Wuerth) ---
|
||||
QT="$APP/Contents/Resources/lib/python3.9/PyQt6/Qt6"
|
||||
KEEP="QtCore QtGui QtWidgets QtDBus QtNetwork QtPrintSupport QtSvg QtSvgWidgets"
|
||||
for fw in "$QT/lib"/*.framework; do
|
||||
name="$(basename "$fw" .framework)"
|
||||
echo " $KEEP " | grep -q " $name " || rm -rf "$fw"
|
||||
done
|
||||
rm -rf "$QT/qml" "$QT/translations" "$QT/qsci"
|
||||
if [ -d "$QT/plugins" ]; then
|
||||
for d in "$QT/plugins"/*/; do
|
||||
case "$(basename "$d")" in
|
||||
platforms|styles|imageformats|iconengines) ;;
|
||||
*) rm -rf "$d";;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
PYQT="$APP/Contents/Resources/lib/python3.9/PyQt6"
|
||||
for m in QtQml QtQuick QtQuick3D QtQuickWidgets QtPdf QtPdfWidgets QtDesigner \
|
||||
QtMultimedia QtMultimediaWidgets Qt3DCore QtCharts QtDataVisualization \
|
||||
QtSql QtTest QtBluetooth QtPositioning QtSensors QtWebChannel \
|
||||
QtWebSockets QtNfc QtSpatialAudio QtShaderTools QtOpenGL QtOpenGLWidgets; do
|
||||
find "$PYQT" -maxdepth 1 -name "${m}.*so" -delete 2>/dev/null || true
|
||||
done
|
||||
while IFS= read -r f; do
|
||||
archs="$(lipo -archs "$f" 2>/dev/null || true)"
|
||||
if [[ "$archs" == *x86_64* && "$archs" == *arm64* ]]; then
|
||||
lipo "$f" -thin arm64 -output "$f" 2>/dev/null || true
|
||||
fi
|
||||
done < <(find "$APP" -type f \( -name "*.so" -o -name "*.dylib" -o -perm -u+x \))
|
||||
find "$APP" -type f \( -name "*.so" -o -name "*.dylib" \) -exec strip -x {} \; 2>/dev/null || true
|
||||
codesign --force --deep -s - "$APP" >/dev/null 2>&1
|
||||
|
||||
# --- 3. Build-Ausgabe entfernen ---
|
||||
"$LSREG" -u "$APPS/dist/HeronVPN.app" 2>/dev/null || true
|
||||
rm -rf build dist
|
||||
|
||||
# --- 4. registrieren ---
|
||||
"$LSREG" -f "$APP"
|
||||
|
||||
# --- 5. LaunchAgent ---
|
||||
LA="$HOME/Library/LaunchAgents/$BID.plist"
|
||||
mkdir -p "$HOME/Library/LaunchAgents"
|
||||
cat >"$LA" <<AGENT
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key><string>$BID</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array><string>/usr/bin/open</string><string>-a</string><string>$APP</string></array>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><false/>
|
||||
</dict>
|
||||
</plist>
|
||||
AGENT
|
||||
|
||||
echo "Fertig: $APP"
|
||||
echo "Autostart aktivieren: launchctl load $LA"
|
||||
echo "Autostart deaktivieren: launchctl unload $LA"
|
||||
Reference in New Issue
Block a user