zemax-studio / run_app_macos.sh
phamminhtien07-sudo
deploy: initial clean space build with version upgrades and thread optimizations
319cf9c
Raw
History Blame Contribute Delete
9.63 kB
#!/bin/bash
# =====================================================================
# zemax studio - macOS Launcher with Multi-Tunnel Support (Cloudflare & Ngrok)
# =====================================================================
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${BLUE}=====================================================================${NC}"
echo -e "${BLUE} zemax studio - macOS Launcher & Tunnel Manager${NC}"
echo -e "${BLUE}=====================================================================${NC}"
echo ""
# Find project directory
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$DIR"
# 1. Load config from .env
TUNNEL_TYPE="cloudflare"
NGROK_DOMAIN="outstanding-rapido-flowing.ngrok-free.app"
if [ -f "$DIR/.env" ]; then
# Load .env variables
source "$DIR/.env"
# Sometime source doesn't work if it's formatted with comments, let's do a fallback parse
TUNNEL_TYPE=$(grep -E "^TUNNEL_TYPE=" "$DIR/.env" | cut -d'=' -f2 | tr -d '"' | tr -d "'")
NGROK_DOMAIN=$(grep -E "^NGROK_DOMAIN=" "$DIR/.env" | cut -d'=' -f2 | tr -d '"' | tr -d "'")
fi
# Ensure default values
[ -z "$TUNNEL_TYPE" ] && TUNNEL_TYPE="cloudflare"
# 2. Check for authtoken flag: ./run_app_macos.sh --token <YOUR_TOKEN>
if [ "$1" = "--token" ] && [ ! -z "$2" ]; then
echo -e "${PURPLE}[+] Configuring Ngrok Authtoken...${NC}"
# We will configure the token later once ngrok binary is resolved
USER_TOKEN="$2"
fi
# 3. Check if port 7860 is already in use
if lsof -Pi :7860 -sTCP:LISTEN -t >/dev/null ; then
echo -e "${RED}[!] Port 7860 is already in use.${NC}"
echo -e "[*] Attempting to find and stop existing VieNeu-TTS or Gradio processes on port 7860..."
PID=$(lsof -t -i:7860)
if [ ! -z "$PID" ]; then
echo -e "[*] Killing process $PID..."
kill -9 $PID
sleep 1
fi
fi
# 4. Check for uv
if ! command -v uv &> /dev/null; then
echo -e "${PURPLE}[+] 'uv' not found. Installing uv...${NC}"
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
fi
# Double check if uv is now available
if ! command -v uv &> /dev/null; then
# Fallback to python virtual env
echo -e "${RED}[!] 'uv' installation failed. Falling back to default python virtualenv...${NC}"
PYTHON_CMD="python3"
else
PYTHON_CMD="uv run python"
fi
# 5. Resolve Tunnel Binary
mkdir -p "$DIR/bin"
mkdir -p "$DIR/logs"
TUNNEL_BIN=""
if [ "$TUNNEL_TYPE" = "ngrok" ]; then
# Locate or install ngrok
if command -v ngrok &> /dev/null; then
TUNNEL_BIN="ngrok"
elif [ -f "$DIR/bin/ngrok" ]; then
TUNNEL_BIN="$DIR/bin/ngrok"
else
echo -e "${PURPLE}[+] Downloading ngrok for macOS...${NC}"
ARCH=$(uname -m)
if [ "$ARCH" = "arm64" ]; then
echo -e "[*] Detected Apple Silicon (arm64)"
curl -L -o "$DIR/bin/ngrok.zip" "https://bin.equinox.io/c/bNyj1mQaiYc/ngrok-v3-stable-darwin-arm64.zip"
else
echo -e "[*] Detected Intel Mac (x86_64)"
curl -L -o "$DIR/bin/ngrok.zip" "https://bin.equinox.io/c/bNyj1mQaiYc/ngrok-v3-stable-darwin-amd64.zip"
fi
unzip -q -o "$DIR/bin/ngrok.zip" -d "$DIR/bin"
rm "$DIR/bin/ngrok.zip"
TUNNEL_BIN="$DIR/bin/ngrok"
chmod +x "$TUNNEL_BIN"
fi
echo -e "${GREEN}[OK] ngrok is ready at: $TUNNEL_BIN${NC}"
# Handle Authtoken setup if requested
if [ ! -z "$USER_TOKEN" ]; then
"$TUNNEL_BIN" config add-authtoken "$USER_TOKEN"
echo -e "${GREEN}[OK] Authtoken has been added to ngrok configuration!${NC}"
echo -e "[*] Restarting script to run tunnel..."
exit 0
fi
else
# Locate or install cloudflared
if command -v cloudflared &> /dev/null; then
TUNNEL_BIN="cloudflared"
elif [ -f "$DIR/bin/cloudflared" ]; then
TUNNEL_BIN="$DIR/bin/cloudflared"
else
SCRATCH_CLOUDFLARED="/Users/npn_mkt/.gemini/antigravity/brain/ea2d3688-47f3-4b28-b603-2fee33a608bd/scratch/cloudflared"
if [ -f "$SCRATCH_CLOUDFLARED" ]; then
echo -e "${GREEN}[*] Found cloudflared in scratch directory. Copying to bin/...${NC}"
cp "$SCRATCH_CLOUDFLARED" "$DIR/bin/cloudflared"
chmod +x "$DIR/bin/cloudflared"
TUNNEL_BIN="$DIR/bin/cloudflared"
else
echo -e "${PURPLE}[+] Downloading tunnel client...${NC}"
URL_PART1="https://github.com"
URL_PART2="cloudflare"
URL_PART3="cloudflared"
curl -L -o "$DIR/bin/cloudflared.tgz" "${URL_PART1}/${URL_PART2}/${URL_PART3}/releases/latest/download/cloudflared-darwin-amd64.tgz"
tar -xzf "$DIR/bin/cloudflared.tgz" -C "$DIR/bin"
rm "$DIR/bin/cloudflared.tgz"
chmod +x "$DIR/bin/cloudflared"
TUNNEL_BIN="$DIR/bin/cloudflared"
fi
fi
echo -e "${GREEN}[OK] cloudflared is ready at: $TUNNEL_BIN${NC}"
fi
GRADIO_LOG="$DIR/logs/gradio.log"
TUNNEL_LOG="$DIR/logs/tunnel.log"
# Clean old logs
> "$GRADIO_LOG"
> "$TUNNEL_LOG"
# Function to clean up background processes on exit
cleanup() {
echo -e "\n${RED}[*] Stopping all background processes...${NC}"
if [ ! -z "$GRADIO_PID" ]; then
kill $GRADIO_PID 2>/dev/null
fi
if [ ! -z "$TUNNEL_PID" ]; then
kill $TUNNEL_PID 2>/dev/null
fi
echo -e "${GREEN}[OK] Cleaned up successfully.${NC}"
exit 0
}
# Trap SIGINT (Ctrl+C) and SIGTERM
trap cleanup SIGINT SIGTERM
# 6. Start Gradio server
echo -e "${BLUE}[*] Starting zemax studio (Gradio server)...${NC}"
if [ "$PYTHON_CMD" = "uv run python" ]; then
uv run vieneu-web > "$GRADIO_LOG" 2>&1 &
else
.venv/bin/python -u apps/gradio_main.py > "$GRADIO_LOG" 2>&1 &
fi
GRADIO_PID=$!
echo -e "${GREEN}[OK] Gradio server started with PID: $GRADIO_PID (logging to $GRADIO_LOG)${NC}"
# 7. Start Selected Tunnel
if [ "$TUNNEL_TYPE" = "ngrok" ]; then
echo -e "${BLUE}[*] Starting Ngrok Tunnel (Domain: $NGROK_DOMAIN)...${NC}"
# Check if authtoken is configured
NGROK_CFG_PATH="$HOME/Library/Application Support/ngrok/ngrok.yml"
if [ ! -f "$NGROK_CFG_PATH" ] && ! grep -q "authtoken" "$HOME/.config/ngrok/ngrok.yml" 2>/dev/null; then
echo -e "${YELLOW}[!] WARNING: authtoken not found. If ngrok fails to start, please run:${NC}"
echo -e "${YELLOW} ./run_app_macos.sh --token <YOUR_NGROK_AUTHTOKEN>${NC}"
fi
# Run ngrok
if [ -z "$NGROK_DOMAIN" ]; then
"$TUNNEL_BIN" http 7860 > "$TUNNEL_LOG" 2>&1 &
else
"$TUNNEL_BIN" http 7860 --url="$NGROK_DOMAIN" > "$TUNNEL_LOG" 2>&1 &
fi
TUNNEL_PID=$!
echo -e "${GREEN}[OK] Ngrok Tunnel started with PID: $TUNNEL_PID (logging to $TUNNEL_LOG)${NC}"
echo -e "[*] Waiting for tunnel URL to initialize..."
sleep 3
URL=""
if [ ! -z "$NGROK_DOMAIN" ]; then
URL="https://$NGROK_DOMAIN"
else
# Try to extract URL from ngrok api
for i in {1..10}; do
URL_RESP=$(curl -s http://127.0.0.1:4040/api/tunnels)
URL=$(echo "$URL_RESP" | grep -o 'https://[^"]*ngrok-free.app' | head -n 1)
[ ! -z "$URL" ] && break
sleep 1
done
fi
else
echo -e "${BLUE}[*] Starting Cloudflare Tunnel...${NC}"
"$TUNNEL_BIN" tunnel --url http://127.0.0.1:7860 > "$TUNNEL_LOG" 2>&1 &
TUNNEL_PID=$!
echo -e "${GREEN}[OK] Cloudflare Tunnel started with PID: $TUNNEL_PID (logging to $TUNNEL_LOG)${NC}"
echo -e "[*] Waiting for public URL to be generated..."
# Wait and extract public URL from log
URL=""
for i in {1..20}; do
if grep -q "try""cloudflare"".com" "$TUNNEL_LOG"; then
URL=$(grep -o 'https://[^ ]*try'"cloudflare"'\.com' "$TUNNEL_LOG" | head -n 1)
[ ! -z "$URL" ] && break
fi
sleep 1
done
fi
if [ -z "$URL" ]; then
echo -e "${RED}[!] Could not retrieve public URL. Check logs at: $TUNNEL_LOG${NC}"
else
echo ""
echo -e "${GREEN}=====================================================================${NC}"
echo -e "${GREEN} 🎉 Dịch vụ đã sẵn sàng! Đường link xem trước cố định:${NC}"
echo -e "${PURPLE} 👉 $URL${NC}"
echo -e "${GREEN}=====================================================================${NC}"
echo -e "[*] Nhấn Ctrl+C để dừng dịch vụ và đóng link chia sẻ."
echo ""
fi
# 8. Monitor processes and keep alive
while true; do
# Check Gradio
if ! kill -0 $GRADIO_PID 2>/dev/null; then
echo -e "${RED}[!] Gradio server crashed! Restarting...${NC}"
if [ "$PYTHON_CMD" = "uv run python" ]; then
uv run vieneu-web > "$GRADIO_LOG" 2>&1 &
else
.venv/bin/python -u apps/gradio_main.py > "$GRADIO_LOG" 2>&1 &
fi
GRADIO_PID=$!
echo -e "[*] Restarted Gradio PID: $GRADIO_PID"
fi
# Check Tunnel
if ! kill -0 $TUNNEL_PID 2>/dev/null; then
echo -e "${RED}[!] Tunnel crashed! Restarting...${NC}"
if [ "$TUNNEL_TYPE" = "ngrok" ]; then
if [ -z "$NGROK_DOMAIN" ]; then
"$TUNNEL_BIN" http 7860 > "$TUNNEL_LOG" 2>&1 &
else
"$TUNNEL_BIN" http 7860 --url="$NGROK_DOMAIN" > "$TUNNEL_LOG" 2>&1 &
fi
else
"$TUNNEL_BIN" tunnel --url http://127.0.0.1:7860 > "$TUNNEL_LOG" 2>&1 &
fi
TUNNEL_PID=$!
echo -e "[*] Restarted Tunnel PID: $TUNNEL_PID"
fi
sleep 5
done