Files
poke-mail/start.sh
T
2026-08-02 14:12:36 -04:00

153 lines
6.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
# ── OTA update ────────────────────────────────────────────────────────────────
# Uses curl + Python stdlib tarfile — no git or unzip required.
#
# Flow:
# 1. Fetch latest GitHub Release tag via API (tiny JSON, 5 s timeout).
# 2. Compare against .poke_version (last installed version tag). Skip if
# already up to date or if the remote is unreachable.
# 3. Download the release tarball only when an update exists (30 s timeout).
# 4. Extract with Python tarfile, stripping the GitHub top-level prefix and
# skipping protected local files (.env, config.yml, .venv).
# 5. Persist new version tag to .poke_version and reinstall deps if
# requirements.txt changed.
if command -v curl &>/dev/null && command -v python3 &>/dev/null; then
_OTA_REPO="kacperkwapisz/poke-mail"
_VERSION_FILE=".poke_version"
echo "Checking for updates..."
# Step 1: fetch latest release tag and tarball URL (fail silently if offline)
_RELEASE_JSON=$(curl -sf --max-time 5 \ "https://api.github.com/repos/${_OTA_REPO}/releases/latest" \ 2>/dev/null || echo "")
_REMOTE_TAG=""
_TARBALL_URL=""
if [ -n "$_RELEASE_JSON" ]; then
_REMOTE_TAG=$(echo "$_RELEASE_JSON" | python3 -c \ "import json,sys; print(json.load(sys.stdin).get('tag_name',''))" \ 2>/dev/null || echo "")
_TARBALL_URL=$(echo "$_RELEASE_JSON" | python3 -c \ "import json,sys; print(json.load(sys.stdin).get('tarball_url',''))" \ 2>/dev/null || echo "")
fi
_LOCAL_TAG=$(cat "$_VERSION_FILE" 2>/dev/null || echo "")
if [ -z "$_REMOTE_TAG" ]; then
echo " Could not reach remote — continuing with local version."
echo ""
elif [ "$_REMOTE_TAG" = "$_LOCAL_TAG" ]; then
echo " ✓ Already up to date (${_LOCAL_TAG})"
echo ""
else
if [ -n "$_LOCAL_TAG" ]; then
echo " ↳ Update found (${_LOCAL_TAG}${_REMOTE_TAG}), downloading..."
else
echo " ↳ Update found (${_REMOTE_TAG}), downloading..."
fi
# Hash requirements.txt before extraction so we can detect changes
_REQS_BEFORE=$(python3 -c \ "import hashlib; print(hashlib.md5(open('requirements.txt','rb').read()).hexdigest())" \ 2>/dev/null || echo "")
_TMP_TAR=$(mktemp /tmp/poke-mail-update.XXXXXX.tar.gz)
if curl -sfL --max-time 30 \ "$_TARBALL_URL" \ -o "$_TMP_TAR" 2>/dev/null; then
# Extract with Python: strip GitHub's top-level dir, skip protected paths
python3 - <<'PYEOF'
import tarfile, sys
TMP_TAR = sys.argv[1]
PROTECTED = {'.env', 'config.yml', '.venv'}
with tarfile.open(TMP_TAR, 'r:gz') as tf:
members = tf.getmembers()
prefix = members[0].name.split('/')[0] + '/'
for m in members:
if not m.name.startswith(prefix):
continue
rel = m.name[len(prefix):]
if not rel:
continue
top = rel.split('/')[0]
if top in PROTECTED:
continue
m.name = rel
try:
tf.extract(m, path='.', set_attrs=False)
except Exception:
pass
PYEOF "$_TMP_TAR"
# Persist new version tag
echo "$_REMOTE_TAG" > "$_VERSION_FILE"
echo " ✓ Updated to ${_REMOTE_TAG}"
# Reinstall deps if requirements.txt changed
_REQS_AFTER=$(python3 -c \ "import hashlib; print(hashlib.md5(open('requirements.txt','rb').read()).hexdigest())" \ 2>/dev/null || echo "")
if [ -n "$_REQS_BEFORE" ] && [ "$_REQS_BEFORE" != "$_REQS_AFTER" ]; then
echo " ↳ requirements.txt changed — reinstalling dependencies..."
[ -d .venv ] && source .venv/bin/activate
pip install -q -r requirements.txt
echo " ✓ Dependencies updated"
fi
else
echo " Download failed — continuing with local version."
fi
rm -f "$_TMP_TAR"
echo ""
fi
fi
# ── One-time setup (skipped on subsequent runs) ───────────────────────────────
# 1. Python virtualenv + dependencies
if [ ! -d .venv ]; then
echo "First run — setting up poke-mail..."
echo ""
echo "Creating Python virtualenv (.venv)..."
python3 -m venv .venv
fi
source .venv/bin/activate
if ! python3 -c "import fastmcp" &>/dev/null 2>&1; then
echo "Installing Python dependencies..."
pip install -q -r requirements.txt
echo " ✓ Dependencies installed"
echo ""
fi
# 2. config.yml — copy example if missing
if [ ! -f config.yml ]; then
echo "Copying config.example.yml → config.yml..."
cp config.example.yml config.yml
echo " ✓ config.yml created"
echo ""
fi
# 3. Poke API key — read from 'poke login' credentials, inject into config.yml
if grep -q 'your-api-key-here' config.yml 2>/dev/null; then
POKE_CREDENTIALS_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/poke/credentials.json"
POKE_TOKEN=""
if [ -f "$POKE_CREDENTIALS_FILE" ]; then
POKE_TOKEN=$(python3 -c "import json,sys; print(json.load(open('$POKE_CREDENTIALS_FILE')).get('token',''))" 2>/dev/null || echo "")
fi
if [ -n "$POKE_TOKEN" ]; then
echo " ✓ Poke API key detected from 'poke login'"
# Generate MCP_API_KEY if not set
if ! grep -Eq '^[[:space:]]*MCP_API_KEY=' .env 2>/dev/null; then
RANDOM_KEY=$(python3 -c "import secrets, string; print(''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(48)))")
echo "MCP_API_KEY=$RANDOM_KEY" >> .env
echo " ✓ MCP_API_KEY generated and saved to .env"
echo ""
fi
export POKE_TUNNEL=1
fi
fi
# ── Tunnel-mode enforcement ───────────────────────────────────────────────────
if [ "${POKE_TUNNEL}" != "1" ]; then
: "${MCP_API_KEY:?MCP_API_KEY is not set — add it to .env or export it}"
else
if [ -z "${MCP_API_KEY:-}" ]; then
echo " MCP_API_KEY not set — server runs unauthenticated (safe: poke tunnel handles auth)."
fi
export POKE_TUNNEL
fi
# ── Start server + tunnel ─────────────────────────────────────────────────────
echo "Starting poke-mail server..."
python3 src/server.py & SERVER_PID=$!
trap "kill $SERVER_PID 2>/dev/null" EXIT
sleep 2
echo "Starting tunnel to Poke..."
if command -v poke &>/dev/null; then
poke tunnel http://localhost:3000/mcp --name "poke-mail"
else
echo " 'poke' binary not found in PATH — using npx poke (requires Node.js)."
if ! command -v npx &>/dev/null; then
echo " ✗ Neither 'poke' nor 'npx' found. Install Node.js (nodejs.org) and run:"
echo " npm install -g poke OR npx poke tunnel ..."
exit 1
fi
npx --yes poke tunnel http://localhost:3000/mcp --name "poke-mail"
fi