Make start scripts auto-install missing runtime deps
Bootstrap uv, Python 3.13, project deps, and browser when possible so first-run setup works without manual environment setup.
This commit is contained in:
1 parent
c56d0d240a
commit
4feac70c91
2 files changed
+400
-220
No files matched your search
@@ -1,135 +1,213 @@
|
||||
@echo off
|
||||
chcp 65001 >nul 2>&1
|
||||
setlocal enabledelayedexpansion
|
||||
setlocal EnableExtensions EnableDelayedExpansion
|
||||
title Grok 注册机 - 一键启动
|
||||
|
||||
echo ============================================
|
||||
echo Grok 注册机 - 一键启动 (Windows)
|
||||
echo ============================================
|
||||
echo.
|
||||
echo 首次运行会自动:
|
||||
echo 1. 安装 uv(如缺失)
|
||||
echo 2. 安装 Python 3.13(如缺失,经 uv 管理)
|
||||
echo 3. 同步 Python 依赖
|
||||
echo 4. 尝试安装 Chrome(如缺失且可用 winget)
|
||||
echo 5. 从模板复制 .env / config.json(如缺失)
|
||||
echo.
|
||||
|
||||
cd /d "%~dp0"
|
||||
|
||||
:: ── 1. 检测 Python 3.13+ ──
|
||||
echo [1/5] 检测 Python 环境...
|
||||
set PYTHON_BIN=
|
||||
:: 预置 uv 常见路径
|
||||
set "PATH=%USERPROFILE%\.local\bin;%USERPROFILE%\.cargo\bin;%LOCALAPPDATA%\uv;%USERPROFILE%\.uv\bin;%PATH%"
|
||||
|
||||
:: 尝试常见 Python 路径
|
||||
for %%P in (
|
||||
"%LOCALAPPDATA%\Programs\Python\Python313\python.exe"
|
||||
"%LOCALAPPDATA%\Programs\Python\Python314\python.exe"
|
||||
"python3.13"
|
||||
"python3"
|
||||
"python"
|
||||
"py"
|
||||
) do (
|
||||
if not defined PYTHON_BIN (
|
||||
where %%~P >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
call :check_python_version %%~P
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
:: 检查 .venv
|
||||
if not defined PYTHON_BIN (
|
||||
if exist ".venv\Scripts\python.exe" (
|
||||
call :check_python_version ".venv\Scripts\python.exe"
|
||||
)
|
||||
)
|
||||
|
||||
if not defined PYTHON_BIN (
|
||||
echo [X] 未找到 Python 3.13+
|
||||
echo.
|
||||
echo 请通过以下任一方式安装 Python 3.13:
|
||||
echo.
|
||||
echo 方式 1: 官方安装包 (推荐)
|
||||
echo https://www.python.org/downloads/
|
||||
echo 下载 Python 3.13.x,安装时勾选 "Add Python to PATH"
|
||||
echo.
|
||||
echo 方式 2: 使用 uv 自动获取
|
||||
echo powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
||||
echo uv python install 3.13
|
||||
echo.
|
||||
echo 方式 3: winget
|
||||
echo winget install Python.Python.3.13
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [OK] Python: %PYTHON_BIN%
|
||||
echo.
|
||||
|
||||
:: ── 2. 检测/安装 uv ──
|
||||
echo [2/5] 检测 uv 包管理器...
|
||||
:: ── 1. 检测/安装 uv ──
|
||||
echo [1/5] 检测/安装 uv 包管理器...
|
||||
where uv >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
if !errorlevel! equ 0 (
|
||||
for /f "tokens=*" %%V in ('uv --version 2^>nul') do echo [OK] uv: %%V
|
||||
goto :uv_ok
|
||||
)
|
||||
|
||||
echo [!] 未检测到 uv,正在自动安装...
|
||||
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
||||
if %errorlevel% neq 0 (
|
||||
echo [X] uv 安装失败,请手动安装:
|
||||
echo powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://astral.sh/uv/install.ps1 | iex"
|
||||
if !errorlevel! neq 0 (
|
||||
echo [X] uv 安装失败,请手动执行:
|
||||
echo powershell -ExecutionPolicy Bypass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: 刷新 PATH
|
||||
call :refresh_path
|
||||
|
||||
where uv >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
if !errorlevel! equ 0 (
|
||||
for /f "tokens=*" %%V in ('uv --version 2^>nul') do echo [OK] uv 安装成功: %%V
|
||||
) else (
|
||||
echo [X] uv 安装后仍未找到,请重启终端后重试
|
||||
echo [X] uv 安装后仍未找到,请关闭本窗口后重新运行 start.bat
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
:uv_ok
|
||||
echo.
|
||||
|
||||
:: ── 2. 检测/安装 Python 3.13 ──
|
||||
echo [2/5] 检测/安装 Python 3.13...
|
||||
set "PYTHON_OK=0"
|
||||
|
||||
:: 系统 / py launcher
|
||||
for %%P in (
|
||||
"%LOCALAPPDATA%\Programs\Python\Python313\python.exe"
|
||||
"%LOCALAPPDATA%\Programs\Python\Python314\python.exe"
|
||||
"%ProgramFiles%\Python313\python.exe"
|
||||
"python"
|
||||
"python3"
|
||||
"py"
|
||||
) do (
|
||||
if !PYTHON_OK! equ 0 (
|
||||
call :try_python "%%~P"
|
||||
)
|
||||
)
|
||||
|
||||
:: 项目 venv
|
||||
if !PYTHON_OK! equ 0 (
|
||||
if exist ".venv\Scripts\python.exe" (
|
||||
call :try_python ".venv\Scripts\python.exe"
|
||||
)
|
||||
)
|
||||
|
||||
:: uv 已管理的 3.13
|
||||
if !PYTHON_OK! equ 0 (
|
||||
for /f "delims=" %%P in ('uv python find 3.13 2^>nul') do (
|
||||
if exist "%%~P" (
|
||||
call :try_python "%%~P"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if !PYTHON_OK! equ 1 (
|
||||
echo [OK] Python 3.13+ 已可用
|
||||
goto :python_ok
|
||||
)
|
||||
|
||||
echo [!] 未找到 Python 3.13+,正在通过 uv 安装...
|
||||
uv python install 3.13
|
||||
if !errorlevel! neq 0 (
|
||||
echo [X] uv python install 3.13 失败
|
||||
echo 也可尝试: winget install Python.Python.3.13
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :refresh_path
|
||||
for /f "delims=" %%P in ('uv python find 3.13 2^>nul') do (
|
||||
if exist "%%~P" (
|
||||
call :try_python "%%~P"
|
||||
)
|
||||
)
|
||||
|
||||
if !PYTHON_OK! equ 1 (
|
||||
echo [OK] Python 3.13 已由 uv 安装完成
|
||||
) else (
|
||||
:: uv run 仍可能解析到托管 Python
|
||||
uv run --python 3.13 python -c "import sys; raise SystemExit(0 if sys.version_info >= (3,13) else 1)" >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
set "PYTHON_OK=1"
|
||||
echo [OK] Python 3.13 已由 uv 管理(将通过 uv run 调用)
|
||||
) else (
|
||||
echo [X] 无法安装或定位 Python 3.13
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
:python_ok
|
||||
echo.
|
||||
|
||||
:: ── 3. 同步依赖 ──
|
||||
echo [3/5] 同步 Python 依赖...
|
||||
uv sync
|
||||
if %errorlevel% neq 0 (
|
||||
uv sync --python 3.13
|
||||
if !errorlevel! neq 0 (
|
||||
echo [!] uv sync --python 3.13 失败,尝试默认 uv sync...
|
||||
uv sync
|
||||
if !errorlevel! neq 0 (
|
||||
echo [X] 依赖同步失败
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
echo [OK] 依赖同步完成
|
||||
echo.
|
||||
|
||||
:: ── 4. 检测浏览器 ──
|
||||
echo [4/5] 检测浏览器...
|
||||
set BROWSER_FOUND=0
|
||||
:: ── 4. 检测/尝试安装浏览器 ──
|
||||
echo [4/5] 检测/安装浏览器...
|
||||
set "BROWSER_FOUND=0"
|
||||
set "BROWSER_PATH="
|
||||
|
||||
for %%B in (
|
||||
"C:\Program Files\Google\Chrome\Application\chrome.exe"
|
||||
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
|
||||
"%ProgramFiles%\Google\Chrome\Application\chrome.exe"
|
||||
"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"
|
||||
"%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe"
|
||||
"chrome"
|
||||
"chromium"
|
||||
"%ProgramFiles%\Chromium\Application\chrome.exe"
|
||||
"%LOCALAPPDATA%\Chromium\Application\chrome.exe"
|
||||
) do (
|
||||
if !BROWSER_FOUND! equ 0 (
|
||||
if exist %%B (
|
||||
echo [OK] 浏览器: %%B
|
||||
set BROWSER_FOUND=1
|
||||
if exist "%%~B" (
|
||||
set "BROWSER_FOUND=1"
|
||||
set "BROWSER_PATH=%%~B"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if %BROWSER_FOUND% equ 0 (
|
||||
echo [!] 未检测到 Chrome/Chromium 浏览器
|
||||
echo.
|
||||
echo DrissionPage 需要 Chrome 才能运行。
|
||||
echo 请安装 Google Chrome: https://www.google.com/chrome/
|
||||
echo.
|
||||
echo 脚本将继续,但注册可能因缺少浏览器而失败。
|
||||
if !BROWSER_FOUND! equ 1 (
|
||||
echo [OK] 浏览器: !BROWSER_PATH!
|
||||
goto :browser_ok
|
||||
)
|
||||
|
||||
where chrome >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
for /f "delims=" %%C in ('where chrome 2^>nul') do (
|
||||
echo [OK] 浏览器: %%C
|
||||
set "BROWSER_FOUND=1"
|
||||
goto :browser_ok
|
||||
)
|
||||
)
|
||||
|
||||
echo [!] 未检测到 Chrome,尝试自动安装...
|
||||
|
||||
:: 优先 winget
|
||||
where winget >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
echo → 使用 winget 安装 Google Chrome...
|
||||
winget install -e --id Google.Chrome --accept-package-agreements --accept-source-agreements
|
||||
if !errorlevel! equ 0 (
|
||||
echo [OK] winget 安装命令已完成
|
||||
) else (
|
||||
echo [!] winget 安装可能未成功(权限/策略限制)
|
||||
)
|
||||
) else (
|
||||
echo [!] 未找到 winget,跳过自动安装
|
||||
echo 请手动安装: https://www.google.com/chrome/
|
||||
)
|
||||
|
||||
:: 再扫一次
|
||||
set "BROWSER_FOUND=0"
|
||||
for %%B in (
|
||||
"%ProgramFiles%\Google\Chrome\Application\chrome.exe"
|
||||
"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"
|
||||
"%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe"
|
||||
) do (
|
||||
if !BROWSER_FOUND! equ 0 (
|
||||
if exist "%%~B" (
|
||||
set "BROWSER_FOUND=1"
|
||||
echo [OK] 浏览器已就绪: %%~B
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if !BROWSER_FOUND! equ 0 (
|
||||
echo [!] 仍未检测到 Chrome
|
||||
echo DrissionPage 需要 Chrome;协议 mint 不强制浏览器,回退流程需要。
|
||||
echo 脚本将继续,注册可能因缺少浏览器而失败。
|
||||
)
|
||||
:browser_ok
|
||||
echo.
|
||||
|
||||
:: ── 5. 配置文件模板 ──
|
||||
@@ -137,8 +215,10 @@ echo [5/5] 检查配置文件...
|
||||
|
||||
if not exist ".env" (
|
||||
if exist ".env.example" (
|
||||
copy ".env.example" ".env" >nul
|
||||
copy /Y ".env.example" ".env" >nul
|
||||
echo [!] 已从 .env.example 创建 .env,请编辑填入真实配置
|
||||
) else (
|
||||
echo [!] 无 .env / .env.example(可直接写 config.json)
|
||||
)
|
||||
) else (
|
||||
echo [OK] .env 已存在
|
||||
@@ -146,8 +226,12 @@ if not exist ".env" (
|
||||
|
||||
if not exist "config.json" (
|
||||
if exist "config.example.json" (
|
||||
copy "config.example.json" "config.json" >nul
|
||||
copy /Y "config.example.json" "config.json" >nul
|
||||
echo [!] 已从 config.example.json 创建 config.json,请编辑填入真实配置
|
||||
) else (
|
||||
echo [X] 缺少 config.json 与 config.example.json
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
) else (
|
||||
echo [OK] config.json 已存在
|
||||
@@ -163,27 +247,40 @@ echo.
|
||||
if "%~1"=="" (
|
||||
echo [*] 默认模式:不限数量,持续注册(Ctrl+C 停止)
|
||||
echo.
|
||||
uv run python -u register_cli.py --count 0
|
||||
uv run --python 3.13 python -u register_cli.py --count 0
|
||||
) else (
|
||||
uv run python -u register_cli.py %*
|
||||
uv run --python 3.13 python -u register_cli.py %*
|
||||
)
|
||||
|
||||
set "EXIT_CODE=!errorlevel!"
|
||||
echo.
|
||||
if !EXIT_CODE! neq 0 (
|
||||
echo [X] 进程退出码: !EXIT_CODE!
|
||||
) else (
|
||||
echo [OK] 已结束
|
||||
)
|
||||
pause
|
||||
exit /b 0
|
||||
exit /b !EXIT_CODE!
|
||||
|
||||
:: ── 辅助函数 ──
|
||||
|
||||
:check_python_version
|
||||
:: 检查指定 Python 版本是否 >= 3.13
|
||||
set "PY_PATH=%~1"
|
||||
"%PY_PATH%" -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
set "PYTHON_BIN=%PY_PATH%"
|
||||
:try_python
|
||||
:: 检查指定解释器是否 >= 3.13
|
||||
set "PY_CAND=%~1"
|
||||
if "%PY_CAND%"=="" exit /b 0
|
||||
where "%PY_CAND%" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
if not exist "%PY_CAND%" exit /b 0
|
||||
)
|
||||
"%PY_CAND%" -c "import sys; raise SystemExit(0 if sys.version_info >= (3,13) else 1)" >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
set "PYTHON_OK=1"
|
||||
for /f "tokens=*" %%V in ('"%PY_CAND%" --version 2^>^&1') do echo [OK] %%V ^(%PY_CAND%^)
|
||||
)
|
||||
exit /b 0
|
||||
|
||||
:refresh_path
|
||||
:: 刷新 PATH,加入 uv 安装路径
|
||||
set "PATH=%USERPROFILE%\.local\bin;%USERPROFILE%\.cargo\bin;%PATH%"
|
||||
:: 合并用户/机器 PATH,并补上 uv 默认目录
|
||||
for /f "usebackq delims=" %%A in (`powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable('Path','User') + ';' + [Environment]::GetEnvironmentVariable('Path','Machine')"`) do set "PATH=%%A"
|
||||
set "PATH=%USERPROFILE%\.local\bin;%USERPROFILE%\.cargo\bin;%LOCALAPPDATA%\uv;%USERPROFILE%\.uv\bin;%PATH%"
|
||||
exit /b 0
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================================
|
||||
# Grok 注册机 - 一键启动脚本 (Linux)
|
||||
# 自动检测/安装环境依赖,然后启动 register_cli.py
|
||||
# Grok 注册机 - 一键启动脚本 (Linux / macOS)
|
||||
# 自动检测并安装缺失环境,然后启动 register_cli.py
|
||||
#
|
||||
# 用法:
|
||||
# ./start.sh # 默认不限数量(持续注册)
|
||||
@@ -10,10 +10,10 @@
|
||||
# ./start.sh --extra 5 # 在已有基础上再注册 5 个
|
||||
#
|
||||
# 首次运行会自动:
|
||||
# 1. 检测 Python 3.13+
|
||||
# 2. 安装 uv 包管理器
|
||||
# 1. 安装 uv(如缺失)
|
||||
# 2. 安装 Python 3.13(如缺失,经 uv 管理)
|
||||
# 3. 同步 Python 依赖
|
||||
# 4. 检测 Chrome/Chromium 浏览器
|
||||
# 4. 尝试安装 Chrome/Chromium(如缺失且有权限)
|
||||
# 5. 从模板复制 .env / config.json(如缺失)
|
||||
# ============================================================================
|
||||
set -euo pipefail
|
||||
@@ -29,107 +29,132 @@ NC='\033[0m'
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
# uv 常见安装路径,确保后续命令能找到
|
||||
export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
|
||||
|
||||
echo -e "${CYAN}${BOLD}============================================${NC}"
|
||||
echo -e "${CYAN}${BOLD} Grok 注册机 - 一键启动 (Linux)${NC}"
|
||||
echo -e "${CYAN}${BOLD} Grok 注册机 - 一键启动 (Linux/macOS)${NC}"
|
||||
echo -e "${CYAN}${BOLD}============================================${NC}"
|
||||
echo ""
|
||||
|
||||
# ── 1. 检测 Python 3.13+ ──
|
||||
step1_check_python() {
|
||||
echo -e "${CYAN}[1/5] 检测 Python 环境...${NC}"
|
||||
|
||||
# 优先使用 mise(如果已安装)
|
||||
if command -v mise &>/dev/null && mise which python &>/dev/null 2>&1; then
|
||||
local py
|
||||
py=$(mise which python 2>/dev/null || true)
|
||||
if [ -n "$py" ] && "$py" -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" 2>/dev/null; then
|
||||
echo -e " ${GREEN}✓${NC} Python (mise): $($py --version 2>&1) at $py"
|
||||
PYTHON_BIN="$py"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 检查系统 Python
|
||||
for candidate in python3.13 python3.14 python3 python; do
|
||||
if command -v "$candidate" &>/dev/null; then
|
||||
local ver
|
||||
ver=$("$candidate" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>/dev/null || echo "0")
|
||||
local major
|
||||
major=$(echo "$ver" | cut -d. -f1)
|
||||
if [ "$major" -ge 3 ]; then
|
||||
local minor
|
||||
minor=$(echo "$ver" | cut -d. -f2)
|
||||
if [ "$minor" -ge 13 ]; then
|
||||
echo -e " ${GREEN}✓${NC} Python $ver: $("$candidate" --version 2>&1)"
|
||||
PYTHON_BIN="$candidate"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# 检查 .venv
|
||||
if [ -f "$PROJECT_DIR/.venv/bin/python3" ]; then
|
||||
local py="$PROJECT_DIR/.venv/bin/python3"
|
||||
if "$py" -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" 2>/dev/null; then
|
||||
echo -e " ${GREEN}✓${NC} Python (.venv): $("$py" --version 2>&1)"
|
||||
PYTHON_BIN="$py"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e " ${RED}✗${NC} 未找到 Python 3.13+"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}请通过以下任一方式安装 Python 3.13:${NC}"
|
||||
echo ""
|
||||
echo " # 方式 1: 使用 mise(推荐,自动管理版本+venv)"
|
||||
echo " curl https://mise.run | sh"
|
||||
echo " mise install python@3.13"
|
||||
echo " mise trust"
|
||||
echo ""
|
||||
echo " # 方式 2: Ubuntu/Debian deadsnakes PPA"
|
||||
echo " sudo add-apt-repository -y ppa:deadsnakes/ppa"
|
||||
echo " sudo apt update && sudo apt install -y python3.13 python3.13-venv"
|
||||
echo ""
|
||||
echo " # 方式 3: 使用 uv 自动获取 Python"
|
||||
echo " curl -LsSf https://astral.sh/uv/install.sh | sh"
|
||||
echo " uv python install 3.13"
|
||||
echo ""
|
||||
echo " # 方式 4: Arch Linux"
|
||||
echo " sudo pacman -S python"
|
||||
echo ""
|
||||
return 1
|
||||
have_cmd() {
|
||||
command -v "$1" &>/dev/null
|
||||
}
|
||||
|
||||
# ── 2. 检测/安装 uv ──
|
||||
step2_check_uv() {
|
||||
echo -e "${CYAN}[2/5] 检测 uv 包管理器...${NC}"
|
||||
# ── 0. 基础工具 ──
|
||||
step0_basics() {
|
||||
echo -e "${CYAN}[0/5] 检查基础工具...${NC}"
|
||||
if ! have_cmd curl && ! have_cmd wget; then
|
||||
echo -e " ${RED}✗${NC} 需要 curl 或 wget 才能自动安装环境"
|
||||
echo " 请先安装: sudo apt install -y curl 或 sudo yum install -y curl"
|
||||
return 1
|
||||
fi
|
||||
if have_cmd curl; then
|
||||
echo -e " ${GREEN}✓${NC} curl 可用"
|
||||
else
|
||||
echo -e " ${GREEN}✓${NC} wget 可用"
|
||||
fi
|
||||
}
|
||||
|
||||
if command -v uv &>/dev/null; then
|
||||
# ── 1. 检测/安装 uv ──
|
||||
step1_install_uv() {
|
||||
echo -e "${CYAN}[1/5] 检测/安装 uv 包管理器...${NC}"
|
||||
|
||||
if have_cmd uv; then
|
||||
echo -e " ${GREEN}✓${NC} uv: $(uv --version 2>&1)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e " ${YELLOW}⚠${NC} 未检测到 uv,正在自动安装..."
|
||||
if command -v curl &>/dev/null; then
|
||||
if have_cmd curl; then
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
elif command -v wget &>/dev/null; then
|
||||
wget -qO- https://astral.sh/uv/install.sh | sh
|
||||
else
|
||||
echo -e " ${RED}✗${NC} 需要 curl 或 wget 来安装 uv"
|
||||
echo " 请手动安装: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
||||
return 1
|
||||
wget -qO- https://astral.sh/uv/install.sh | sh
|
||||
fi
|
||||
|
||||
# 重新加载 PATH(uv 安装到 ~/.local/bin 或 ~/.cargo/bin)
|
||||
export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
|
||||
|
||||
if command -v uv &>/dev/null; then
|
||||
# 部分环境写到 ~/.profile,再补一次常见路径
|
||||
if [ -f "$HOME/.local/bin/env" ]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$HOME/.local/bin/env" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if have_cmd uv; then
|
||||
echo -e " ${GREEN}✓${NC} uv 安装成功: $(uv --version 2>&1)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e " ${RED}✗${NC} uv 安装失败,请手动安装: https://docs.astral.sh/uv/"
|
||||
echo -e " ${RED}✗${NC} uv 安装失败,请手动: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
||||
return 1
|
||||
}
|
||||
|
||||
# ── 2. 检测/安装 Python 3.13 ──
|
||||
# 策略: 优先系统/mise 已有 3.13;否则用 uv 下载管理 Python
|
||||
step2_install_python() {
|
||||
echo -e "${CYAN}[2/5] 检测/安装 Python 3.13...${NC}"
|
||||
PYTHON_BIN=""
|
||||
|
||||
# mise 托管的 python
|
||||
if have_cmd mise && [ -f "$PROJECT_DIR/mise.toml" ]; then
|
||||
# 尝试按项目配置安装工具链
|
||||
if mise install 2>/dev/null; then
|
||||
local py
|
||||
py=$(mise which python 2>/dev/null || true)
|
||||
if [ -n "$py" ] && "$py" -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" 2>/dev/null; then
|
||||
PYTHON_BIN="$py"
|
||||
echo -e " ${GREEN}✓${NC} Python (mise): $($py --version 2>&1) at $py"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# 系统 / PATH 上的 3.13+
|
||||
local candidate
|
||||
for candidate in python3.13 python3.14 python3 python; do
|
||||
if have_cmd "$candidate"; then
|
||||
if "$candidate" -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" 2>/dev/null; then
|
||||
PYTHON_BIN="$candidate"
|
||||
echo -e " ${GREEN}✓${NC} Python: $($candidate --version 2>&1)"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# 项目 .venv
|
||||
if [ -x "$PROJECT_DIR/.venv/bin/python" ]; then
|
||||
if "$PROJECT_DIR/.venv/bin/python" -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" 2>/dev/null; then
|
||||
PYTHON_BIN="$PROJECT_DIR/.venv/bin/python"
|
||||
echo -e " ${GREEN}✓${NC} Python (.venv): $($PYTHON_BIN --version 2>&1)"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 用 uv 安装托管的 Python 3.13
|
||||
echo -e " ${YELLOW}⚠${NC} 未找到 Python 3.13+,正在通过 uv 安装..."
|
||||
if ! uv python install 3.13; then
|
||||
echo -e " ${RED}✗${NC} uv python install 3.13 失败"
|
||||
echo " 也可手动: uv python install 3.13"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 解析 uv 管理的 python 路径
|
||||
local uv_py
|
||||
uv_py=$(uv python find 3.13 2>/dev/null || true)
|
||||
if [ -n "$uv_py" ] && [ -x "$uv_py" ]; then
|
||||
PYTHON_BIN="$uv_py"
|
||||
echo -e " ${GREEN}✓${NC} Python (uv): $($uv_py --version 2>&1) at $uv_py"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# uv python find 失败时,后续 uv run 仍可自动解析
|
||||
if uv run --python 3.13 python -c "import sys; sys.exit(0 if sys.version_info >= (3,13) else 1)" 2>/dev/null; then
|
||||
PYTHON_BIN="uv-managed"
|
||||
echo -e " ${GREEN}✓${NC} Python 3.13 已由 uv 管理(将通过 uv run 调用)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e " ${RED}✗${NC} 无法安装或定位 Python 3.13"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -137,53 +162,101 @@ step2_check_uv() {
|
||||
step3_sync_deps() {
|
||||
echo -e "${CYAN}[3/5] 同步 Python 依赖...${NC}"
|
||||
|
||||
if command -v mise &>/dev/null && [ -f "$PROJECT_DIR/mise.toml" ]; then
|
||||
# mise 管理 venv,直接用 uv sync
|
||||
if [ -n "${PYTHON_BIN:-}" ]; then
|
||||
"$PYTHON_BIN" -m uv sync 2>/dev/null || uv sync
|
||||
else
|
||||
uv sync
|
||||
# 固定使用 3.13,避免系统默认 python 过旧
|
||||
if ! uv sync --python 3.13; then
|
||||
echo -e " ${YELLOW}⚠${NC} uv sync --python 3.13 失败,尝试默认 uv sync..."
|
||||
if ! uv sync; then
|
||||
echo -e " ${RED}✗${NC} 依赖同步失败"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# 纯 uv 模式
|
||||
uv sync
|
||||
fi
|
||||
|
||||
echo -e " ${GREEN}✓${NC} 依赖同步完成"
|
||||
}
|
||||
|
||||
# ── 4. 检测浏览器 ──
|
||||
# ── 4. 检测/尝试安装浏览器 ──
|
||||
step4_check_browser() {
|
||||
echo -e "${CYAN}[4/5] 检测浏览器...${NC}"
|
||||
echo -e "${CYAN}[4/5] 检测/安装浏览器...${NC}"
|
||||
|
||||
local found=false
|
||||
local candidate
|
||||
for candidate in \
|
||||
google-chrome-stable google-chrome chromium chromium-browser \
|
||||
/usr/bin/google-chrome-stable /usr/bin/google-chrome \
|
||||
/snap/bin/chromium /usr/bin/chromium /usr/bin/chromium-browser; do
|
||||
if command -v "$candidate" &>/dev/null || [ -x "$candidate" ] 2>/dev/null; then
|
||||
/snap/bin/chromium /usr/bin/chromium /usr/bin/chromium-browser \
|
||||
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; do
|
||||
if have_cmd "$candidate" || [ -x "$candidate" ] 2>/dev/null; then
|
||||
echo -e " ${GREEN}✓${NC} 浏览器: $(command -v "$candidate" 2>/dev/null || echo "$candidate")"
|
||||
found=true
|
||||
break
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
if ! $found; then
|
||||
echo -e " ${YELLOW}⚠${NC} 未检测到 Chrome/Chromium 浏览器"
|
||||
echo ""
|
||||
echo " DrissionPage 需要 Chrome 或 Chromium 才能运行。"
|
||||
echo ""
|
||||
echo " 安装方式:"
|
||||
echo " # Ubuntu/Debian"
|
||||
echo " sudo apt install -y chromium-browser"
|
||||
echo " # 或安装 Google Chrome:"
|
||||
echo " wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
|
||||
echo " sudo dpkg -i /tmp/chrome.deb"
|
||||
echo ""
|
||||
echo " # Arch Linux"
|
||||
echo " sudo pacman -S chromium"
|
||||
echo ""
|
||||
echo " ${YELLOW}脚本将继续,但注册可能因缺少浏览器而失败。${NC}"
|
||||
echo -e " ${YELLOW}⚠${NC} 未检测到 Chrome/Chromium,尝试自动安装..."
|
||||
|
||||
local installed=false
|
||||
|
||||
# Debian/Ubuntu
|
||||
if have_cmd apt-get; then
|
||||
if have_cmd sudo; then
|
||||
if sudo -n true 2>/dev/null; then
|
||||
echo " → 使用 apt 安装 chromium(免密 sudo)..."
|
||||
if sudo apt-get update -qq && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq chromium-browser chromium 2>/dev/null; then
|
||||
installed=true
|
||||
fi
|
||||
else
|
||||
echo -e " ${YELLOW}⚠${NC} 检测到 apt,但需要交互 sudo,跳过自动安装浏览器"
|
||||
echo " 可手动: sudo apt install -y chromium-browser"
|
||||
fi
|
||||
fi
|
||||
# Arch
|
||||
elif have_cmd pacman; then
|
||||
if have_cmd sudo && sudo -n true 2>/dev/null; then
|
||||
echo " → 使用 pacman 安装 chromium..."
|
||||
if sudo pacman -Sy --noconfirm chromium 2>/dev/null; then
|
||||
installed=true
|
||||
fi
|
||||
else
|
||||
echo " 可手动: sudo pacman -S chromium"
|
||||
fi
|
||||
# Fedora/RHEL
|
||||
elif have_cmd dnf; then
|
||||
if have_cmd sudo && sudo -n true 2>/dev/null; then
|
||||
echo " → 使用 dnf 安装 chromium..."
|
||||
if sudo dnf install -y chromium 2>/dev/null; then
|
||||
installed=true
|
||||
fi
|
||||
else
|
||||
echo " 可手动: sudo dnf install -y chromium"
|
||||
fi
|
||||
# macOS Homebrew
|
||||
elif have_cmd brew; then
|
||||
echo " → 使用 Homebrew 安装 Google Chrome..."
|
||||
if brew install --cask google-chrome 2>/dev/null; then
|
||||
installed=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# 再检测一次
|
||||
for candidate in \
|
||||
google-chrome-stable google-chrome chromium chromium-browser \
|
||||
/usr/bin/google-chrome-stable /usr/bin/google-chrome \
|
||||
/snap/bin/chromium /usr/bin/chromium /usr/bin/chromium-browser \
|
||||
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; do
|
||||
if have_cmd "$candidate" || [ -x "$candidate" ] 2>/dev/null; then
|
||||
echo -e " ${GREEN}✓${NC} 浏览器已就绪: $(command -v "$candidate" 2>/dev/null || echo "$candidate")"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
if $installed; then
|
||||
echo -e " ${YELLOW}⚠${NC} 安装命令已执行,但仍未在 PATH 中找到浏览器,请重启终端后重试"
|
||||
else
|
||||
echo -e " ${YELLOW}⚠${NC} 未能自动安装浏览器"
|
||||
echo " DrissionPage 需要 Chrome/Chromium;协议 mint 不强制浏览器,回退流程需要。"
|
||||
echo " 手动安装示例:"
|
||||
echo " Ubuntu/Debian: sudo apt install -y chromium-browser"
|
||||
echo " Arch: sudo pacman -S chromium"
|
||||
echo " macOS: brew install --cask google-chrome"
|
||||
echo " ${YELLOW}脚本将继续,注册可能因缺少浏览器而失败。${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -196,6 +269,8 @@ step5_config_templates() {
|
||||
echo -e " ${YELLOW}⚠${NC} 已从 .env.example 创建 .env,请编辑填入真实配置"
|
||||
elif [ -f "$PROJECT_DIR/.env" ]; then
|
||||
echo -e " ${GREEN}✓${NC} .env 已存在"
|
||||
else
|
||||
echo -e " ${YELLOW}⚠${NC} 无 .env / .env.example(可直接写 config.json)"
|
||||
fi
|
||||
|
||||
if [ ! -f "$PROJECT_DIR/config.json" ] && [ -f "$PROJECT_DIR/config.example.json" ]; then
|
||||
@@ -203,20 +278,25 @@ step5_config_templates() {
|
||||
echo -e " ${YELLOW}⚠${NC} 已从 config.example.json 创建 config.json,请编辑填入真实配置"
|
||||
elif [ -f "$PROJECT_DIR/config.json" ]; then
|
||||
echo -e " ${GREEN}✓${NC} config.json 已存在"
|
||||
else
|
||||
echo -e " ${RED}✗${NC} 缺少 config.json 与 config.example.json"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ── 主流程 ──
|
||||
main() {
|
||||
step1_check_python || exit 1
|
||||
step0_basics || exit 1
|
||||
echo ""
|
||||
step2_check_uv || exit 1
|
||||
step1_install_uv || exit 1
|
||||
echo ""
|
||||
step3_sync_deps
|
||||
step2_install_python || exit 1
|
||||
echo ""
|
||||
step3_sync_deps || exit 1
|
||||
echo ""
|
||||
step4_check_browser
|
||||
echo ""
|
||||
step5_config_templates
|
||||
step5_config_templates || exit 1
|
||||
echo ""
|
||||
|
||||
echo -e "${CYAN}${BOLD}============================================${NC}"
|
||||
@@ -225,19 +305,22 @@ main() {
|
||||
echo ""
|
||||
|
||||
# 默认不限数量(--count 0),除非用户显式传参
|
||||
local -a args
|
||||
if [ $# -eq 0 ]; then
|
||||
echo -e "${YELLOW}[*] 默认模式:不限数量,持续注册(Ctrl+C 停止)${NC}"
|
||||
echo ""
|
||||
ARGS="--count 0"
|
||||
args=(--count 0)
|
||||
else
|
||||
ARGS="$*"
|
||||
args=("$@")
|
||||
fi
|
||||
|
||||
if command -v mise &>/dev/null && [ -f "$PROJECT_DIR/mise.toml" ]; then
|
||||
exec mise run register -- -- $ARGS
|
||||
else
|
||||
exec uv run python -u register_cli.py $ARGS
|
||||
# 统一走 uv run,确保用项目 venv + 正确 Python
|
||||
# mise 仅作可选加速;有 mise.toml 时先确保工具已装,仍用 uv 启动更稳
|
||||
if have_cmd mise && [ -f "$PROJECT_DIR/mise.toml" ]; then
|
||||
mise install >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
exec uv run --python 3.13 python -u register_cli.py "${args[@]}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in new issue
Block a user