Add StartOS 0.4.0 packaging
This commit is contained in:
Executable
+194
@@ -0,0 +1,194 @@
|
||||
#!/bin/bash
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# Creates "YouTube Summarizer.app" — a proper macOS app bundle
|
||||
# that you can put in your Dock, Desktop, or Applications folder.
|
||||
#
|
||||
# Usage: Run this once from the project folder:
|
||||
# chmod +x create-app.sh && ./create-app.sh
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
APP_NAME="YouTube Summarizer"
|
||||
APP_PATH="$PROJECT_DIR/$APP_NAME.app"
|
||||
|
||||
echo ""
|
||||
echo "Creating $APP_NAME.app..."
|
||||
echo ""
|
||||
|
||||
# ── Build the .app bundle structure ──────────────────────────
|
||||
rm -rf "$APP_PATH"
|
||||
mkdir -p "$APP_PATH/Contents/MacOS"
|
||||
mkdir -p "$APP_PATH/Contents/Resources"
|
||||
|
||||
# ── Create the launcher script ───────────────────────────────
|
||||
cat > "$APP_PATH/Contents/MacOS/launcher" << 'LAUNCHER'
|
||||
#!/bin/bash
|
||||
|
||||
# Resolve the real project directory (the .app lives inside it)
|
||||
APP_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||
|
||||
# If the app has been moved (e.g. to /Applications), check for a saved path
|
||||
SAVED_PATH="$HOME/.config/youtube-summarizer/project-path"
|
||||
if [ ! -f "$APP_DIR/server/index.js" ]; then
|
||||
if [ -f "$SAVED_PATH" ]; then
|
||||
APP_DIR="$(cat "$SAVED_PATH")"
|
||||
else
|
||||
# Ask the user to locate the project folder
|
||||
APP_DIR=$(osascript -e 'POSIX path of (choose folder with prompt "Locate your YouTube Summarizer project folder:")')
|
||||
APP_DIR="${APP_DIR%/}"
|
||||
if [ -z "$APP_DIR" ] || [ ! -f "$APP_DIR/server/index.js" ]; then
|
||||
osascript -e 'display alert "YouTube Summarizer" message "Could not find the project folder. Make sure server/index.js exists." as critical'
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$(dirname "$SAVED_PATH")"
|
||||
echo "$APP_DIR" > "$SAVED_PATH"
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "$APP_DIR"
|
||||
|
||||
# Add common Homebrew paths (node, yt-dlp)
|
||||
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
|
||||
|
||||
# Check for Node.js
|
||||
if ! command -v node &> /dev/null; then
|
||||
osascript -e 'display alert "YouTube Summarizer" message "Node.js is not installed. Install it with: brew install node" as critical'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for yt-dlp
|
||||
if ! command -v yt-dlp &> /dev/null; then
|
||||
if command -v brew &> /dev/null; then
|
||||
brew install yt-dlp 2>&1
|
||||
else
|
||||
osascript -e 'display alert "YouTube Summarizer" message "yt-dlp is not installed. Install it with: brew install yt-dlp" as critical'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install npm dependencies if needed
|
||||
if [ ! -d "server/node_modules" ]; then
|
||||
cd server && npm install && cd ..
|
||||
fi
|
||||
|
||||
# Ask user: Home or Traveling?
|
||||
ICON_PATH="$APP_DIR/assets/icon.png"
|
||||
NETWORK_CHOICE=$(osascript -e "
|
||||
set iconFile to POSIX file \"$ICON_PATH\"
|
||||
set theChoice to button returned of (display dialog \"Where are you right now?\" & return & return & \"Home — allows your phone and other devices on your Wi-Fi to use the app.\" & return & return & \"Traveling — locks access to just this laptop for safety on public Wi-Fi.\" buttons {\"Traveling\", \"Home\"} default button \"Traveling\" with title \"YouTube Summarizer\" with icon iconFile)
|
||||
return theChoice
|
||||
" 2>/dev/null)
|
||||
|
||||
# Default to traveling (safe) if dialog was cancelled
|
||||
if [ "$NETWORK_CHOICE" = "Home" ]; then
|
||||
export LAN_MODE=true
|
||||
else
|
||||
export LAN_MODE=false
|
||||
fi
|
||||
|
||||
# Kill any existing instance on port 3001
|
||||
lsof -ti:3001 | xargs kill -9 2>/dev/null
|
||||
sleep 0.3
|
||||
|
||||
# Start the server
|
||||
cd server
|
||||
node index.js &
|
||||
SERVER_PID=$!
|
||||
cd ..
|
||||
|
||||
# Wait for server to be ready (up to 10 seconds)
|
||||
for i in {1..20}; do
|
||||
if curl -s http://localhost:3001/api/health > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
# Open browser
|
||||
open http://localhost:3001
|
||||
|
||||
# Keep alive — when the app is quit, stop the server
|
||||
trap "kill $SERVER_PID 2>/dev/null; exit 0" INT TERM
|
||||
wait $SERVER_PID
|
||||
LAUNCHER
|
||||
|
||||
chmod +x "$APP_PATH/Contents/MacOS/launcher"
|
||||
|
||||
# ── Create Info.plist ────────────────────────────────────────
|
||||
cat > "$APP_PATH/Contents/Info.plist" << PLIST
|
||||
<?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>CFBundleExecutable</key>
|
||||
<string>launcher</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>YouTube Summarizer</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.local.youtube-summarizer</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>AppIcon</string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
|
||||
# ── Create the app icon from the pre-made PNG ───────────────
|
||||
ICON_PNG="$PROJECT_DIR/assets/icon.png"
|
||||
ICON_DIR="$APP_PATH/Contents/Resources"
|
||||
|
||||
if [ -f "$ICON_PNG" ]; then
|
||||
echo "Building app icon..."
|
||||
|
||||
# Create iconset with all required sizes using sips (built into macOS)
|
||||
ICONSET="$ICON_DIR/AppIcon.iconset"
|
||||
mkdir -p "$ICONSET"
|
||||
|
||||
for size in 16 32 64 128 256 512; do
|
||||
sips -z $size $size "$ICON_PNG" --out "$ICONSET/icon_${size}x${size}.png" > /dev/null 2>&1
|
||||
done
|
||||
# @2x variants
|
||||
for size in 16 32 128 256 512; do
|
||||
double=$((size * 2))
|
||||
sips -z $double $double "$ICON_PNG" --out "$ICONSET/icon_${size}x${size}@2x.png" > /dev/null 2>&1
|
||||
done
|
||||
|
||||
# Convert iconset → .icns using iconutil (built into macOS)
|
||||
iconutil -c icns "$ICONSET" -o "$ICON_DIR/AppIcon.icns" 2>/dev/null
|
||||
|
||||
# Clean up the iconset folder
|
||||
rm -rf "$ICONSET"
|
||||
|
||||
if [ -f "$ICON_DIR/AppIcon.icns" ]; then
|
||||
echo " Icon created successfully."
|
||||
else
|
||||
echo " Warning: Could not create .icns icon. The app will use a generic icon."
|
||||
fi
|
||||
else
|
||||
echo " Warning: assets/icon.png not found. The app will use a generic icon."
|
||||
fi
|
||||
|
||||
# ── Remove quarantine so macOS doesn't block it ─────────────
|
||||
xattr -d com.apple.quarantine "$APP_PATH" 2>/dev/null
|
||||
|
||||
# ── Done! ────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " Created: $APP_NAME.app"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "You can now:"
|
||||
echo " 1. Double-click it to launch the app"
|
||||
echo " 2. Drag it to your Dock for quick access"
|
||||
echo " 3. Move it to /Applications if you prefer"
|
||||
echo ""
|
||||
echo "If you move it outside this folder, it will"
|
||||
echo "ask you to locate the project folder once."
|
||||
echo ""
|
||||
echo "Done!"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user