260 lines
6.4 KiB
Bash
Executable File
260 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
WSCRAPER_DIR="$ROOT_DIR/bin/wscraper"
|
|
RUNTIME_DIR="$ROOT_DIR/.runtime/wscraper-service"
|
|
VENV_DIR="$RUNTIME_DIR/.venv"
|
|
PID_FILE="$RUNTIME_DIR/wscraper-service.pid"
|
|
LOG_FILE="$RUNTIME_DIR/wscraper-service.log"
|
|
MARKER_FILE="$RUNTIME_DIR/.setup-complete"
|
|
MODE=""
|
|
SKIP_INSTALL="false"
|
|
RESTART_WSCRAPER="false"
|
|
SKIP_FETCH="false"
|
|
UPDATE_WSCRAPER="false"
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
./scripts/bootstrap.sh --dev-mode [--skip-wscraper-fetch] [--update-wscraper] [--skip-wscraper-install] [--restart-wscraper]
|
|
./scripts/bootstrap.sh --prod-mode [--skip-wscraper-fetch] [--update-wscraper] [--skip-wscraper-install] [--restart-wscraper]
|
|
EOF
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--dev-mode)
|
|
MODE="dev"
|
|
;;
|
|
--prod-mode)
|
|
MODE="prod"
|
|
;;
|
|
--skip-wscraper-install)
|
|
SKIP_INSTALL="true"
|
|
;;
|
|
--skip-wscraper-fetch)
|
|
SKIP_FETCH="true"
|
|
;;
|
|
--update-wscraper)
|
|
UPDATE_WSCRAPER="true"
|
|
;;
|
|
--restart-wscraper|--restart)
|
|
RESTART_WSCRAPER="true"
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [[ -z "$MODE" ]]; then
|
|
echo "--dev-mode veya --prod-mode zorunlu." >&2
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$RUNTIME_DIR"
|
|
|
|
if [[ -f "$ROOT_DIR/.env" ]]; then
|
|
set -a
|
|
# shellcheck disable=SC1091
|
|
source "$ROOT_DIR/.env"
|
|
set +a
|
|
fi
|
|
|
|
WSCRAPER_SERVICE_HOST="${WSCRAPER_SERVICE_HOST:-0.0.0.0}"
|
|
WSCRAPER_SERVICE_PORT="${WSCRAPER_SERVICE_PORT:-8787}"
|
|
WSCRAPER_SERVICE_TOKEN="${WSCRAPER_SERVICE_TOKEN:-}"
|
|
WSCRAPER_SERVICE_PYTHON_BIN="${WSCRAPER_SERVICE_PYTHON_BIN:-}"
|
|
WSCRAPER_GIT_URL="${WSCRAPER_GIT_URL:-https://github.com/wisecolt/Bookmark-Tracker.git}"
|
|
WSCRAPER_GIT_REF="${WSCRAPER_GIT_REF:-main}"
|
|
|
|
detect_python_bin() {
|
|
if [[ -n "$WSCRAPER_SERVICE_PYTHON_BIN" ]] && command -v "$WSCRAPER_SERVICE_PYTHON_BIN" >/dev/null 2>&1; then
|
|
echo "$WSCRAPER_SERVICE_PYTHON_BIN"
|
|
return
|
|
fi
|
|
|
|
local candidate
|
|
for candidate in python3.12 python3.11 python3.10 python3; do
|
|
if ! command -v "$candidate" >/dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
if "$candidate" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 10) else 1)' >/dev/null 2>&1; then
|
|
echo "$candidate"
|
|
return
|
|
fi
|
|
done
|
|
|
|
echo "q-buffer watcher icin Python 3.10+ gerekli." >&2
|
|
exit 1
|
|
}
|
|
|
|
PYTHON_BIN="$(detect_python_bin)"
|
|
|
|
ensure_wscraper_repo() {
|
|
if [[ "$SKIP_FETCH" == "true" ]]; then
|
|
echo "wscraper repo kontrolu atlandi."
|
|
return
|
|
fi
|
|
|
|
if [[ ! -d "$WSCRAPER_DIR" ]]; then
|
|
echo "wscraper repo klonlaniyor..."
|
|
git clone --branch "$WSCRAPER_GIT_REF" "$WSCRAPER_GIT_URL" "$WSCRAPER_DIR"
|
|
return
|
|
fi
|
|
|
|
if [[ ! -d "$WSCRAPER_DIR/.git" ]]; then
|
|
echo "bin/wscraper dizini var ama git reposu degil. Lutfen duzeltin veya dizini temizleyin." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$UPDATE_WSCRAPER" != "true" ]]; then
|
|
echo "wscraper repo mevcut, yeniden klonlanmayacak."
|
|
return
|
|
fi
|
|
|
|
local status_output
|
|
status_output="$(git -C "$WSCRAPER_DIR" status --porcelain)"
|
|
if [[ -n "$status_output" ]]; then
|
|
echo "wscraper repo kirli durumda; --update-wscraper uygulanmadi." >&2
|
|
echo "Lutfen bin/wscraper icindeki degisiklikleri commit edin veya temizleyin." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "wscraper repo guncelleniyor..."
|
|
git -C "$WSCRAPER_DIR" pull --ff-only
|
|
}
|
|
|
|
validate_wscraper_repo() {
|
|
local expected_paths=(
|
|
"$WSCRAPER_DIR/pyproject.toml"
|
|
"$WSCRAPER_DIR/setup.py"
|
|
"$WSCRAPER_DIR/src/wscraper/cli.py"
|
|
)
|
|
local path
|
|
for path in "${expected_paths[@]}"; do
|
|
if [[ ! -e "$path" ]]; then
|
|
echo "wscraper repo eksik veya bozuk gorunuyor: $path bulunamadi." >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
service_running() {
|
|
if [[ ! -f "$PID_FILE" ]]; then
|
|
return 1
|
|
fi
|
|
local pid
|
|
pid="$(cat "$PID_FILE")"
|
|
if [[ -z "$pid" ]]; then
|
|
return 1
|
|
fi
|
|
if kill -0 "$pid" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
rm -f "$PID_FILE"
|
|
return 1
|
|
}
|
|
|
|
install_wscraper_service() {
|
|
if [[ "$SKIP_INSTALL" == "true" ]]; then
|
|
echo "wscraper kurulum kontrolu atlandi."
|
|
return
|
|
fi
|
|
|
|
local needs_install="false"
|
|
if [[ ! -x "$VENV_DIR/bin/python3" ]]; then
|
|
needs_install="true"
|
|
elif [[ ! -f "$MARKER_FILE" ]]; then
|
|
needs_install="true"
|
|
elif ! "$VENV_DIR/bin/python3" -c "import scrapling" >/dev/null 2>&1; then
|
|
needs_install="true"
|
|
fi
|
|
|
|
if [[ "$needs_install" == "false" ]]; then
|
|
echo "wscraper kurulumu mevcut, tekrar kurulmayacak."
|
|
return
|
|
fi
|
|
|
|
echo "wscraper host servisi kuruluyor..."
|
|
rm -rf "$VENV_DIR"
|
|
"$PYTHON_BIN" -m venv "$VENV_DIR"
|
|
"$VENV_DIR/bin/pip" install --upgrade pip
|
|
"$VENV_DIR/bin/pip" install "scrapling[fetchers]==0.4.1"
|
|
"$VENV_DIR/bin/scrapling" install
|
|
touch "$MARKER_FILE"
|
|
}
|
|
|
|
stop_wscraper_service() {
|
|
if ! service_running; then
|
|
return
|
|
fi
|
|
local pid
|
|
pid="$(cat "$PID_FILE")"
|
|
echo "wscraper-service durduruluyor (pid=$pid)..."
|
|
kill "$pid" >/dev/null 2>&1 || true
|
|
rm -f "$PID_FILE"
|
|
}
|
|
|
|
start_wscraper_service() {
|
|
if service_running && [[ "$RESTART_WSCRAPER" != "true" ]]; then
|
|
echo "wscraper-service zaten calisiyor."
|
|
return
|
|
fi
|
|
|
|
if [[ "$RESTART_WSCRAPER" == "true" ]]; then
|
|
stop_wscraper_service
|
|
fi
|
|
|
|
echo "wscraper-service baslatiliyor..."
|
|
nohup env \
|
|
WSCRAPER_SERVICE_HOST="$WSCRAPER_SERVICE_HOST" \
|
|
WSCRAPER_SERVICE_PORT="$WSCRAPER_SERVICE_PORT" \
|
|
WSCRAPER_SERVICE_TOKEN="$WSCRAPER_SERVICE_TOKEN" \
|
|
PYTHONPATH="$WSCRAPER_DIR/src" \
|
|
"$VENV_DIR/bin/python3" \
|
|
"$ROOT_DIR/bin/wscraper-service/server.py" \
|
|
>>"$LOG_FILE" 2>&1 &
|
|
echo $! > "$PID_FILE"
|
|
|
|
local health_url="http://127.0.0.1:${WSCRAPER_SERVICE_PORT}/health"
|
|
for _ in $(seq 1 20); do
|
|
if [[ -n "$WSCRAPER_SERVICE_TOKEN" ]]; then
|
|
if curl -fsS -H "Authorization: Bearer ${WSCRAPER_SERVICE_TOKEN}" "$health_url" >/dev/null 2>&1; then
|
|
echo "wscraper-service hazir."
|
|
return
|
|
fi
|
|
elif curl -fsS "$health_url" >/dev/null 2>&1; then
|
|
echo "wscraper-service hazir."
|
|
return
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo "wscraper-service health-check basarisiz. Log: $LOG_FILE" >&2
|
|
exit 1
|
|
}
|
|
|
|
run_docker() {
|
|
if [[ "$MODE" == "dev" ]]; then
|
|
docker compose -f "$ROOT_DIR/docker-compose.dev.yml" up --build
|
|
return
|
|
fi
|
|
docker compose -f "$ROOT_DIR/docker-compose.yml" up --build -d
|
|
}
|
|
|
|
ensure_wscraper_repo
|
|
validate_wscraper_repo
|
|
install_wscraper_service
|
|
start_wscraper_service
|
|
run_docker
|