Files
luci-app-openclaw/scripts/upload_openlist.sh

222 lines
6.7 KiB
Bash
Executable File
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.
#!/bin/sh
# ============================================================================
# OpenList 网盘上传脚本
# 将构建产物上传到 OpenList (AList) 网盘,便于国内用户下载
#
# 用法:
# sh scripts/upload_openlist.sh [dist_dir]
#
# 环境变量 (必须):
# OPENLIST_URL — OpenList 服务地址 (如 https://pan.example.com)
# OPENLIST_USER — 登录用户名
# OPENLIST_PASS — 登录密码
#
# 环境变量 (可选):
# OPENLIST_PATH — 上传根路径 (默认: /Quark)
# OPENLIST_TOKEN — 直接提供 token, 跳过登录
# UPLOAD_MODE — 上传模式: offline / online / auto (默认 auto)
# auto 模式自动检测: 有 *_offline.run 则离线, 有 .run/.ipk 则在线
# ============================================================================
set -e
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
PKG_DIR=$(cd "$SCRIPT_DIR/.." && pwd)
DIST_DIR="${1:-$PKG_DIR/dist}"
case "$DIST_DIR" in
/*) ;;
*) DIST_DIR="$PKG_DIR/$DIST_DIR" ;;
esac
# 检查必要的环境变量
if [ -z "$OPENLIST_URL" ]; then
echo "错误: 请设置 OPENLIST_URL 环境变量"
echo " 例: export OPENLIST_URL=https://pan.example.com"
exit 1
fi
if [ -z "$OPENLIST_TOKEN" ] && { [ -z "$OPENLIST_USER" ] || [ -z "$OPENLIST_PASS" ]; }; then
echo "错误: 请设置登录凭据"
echo " 方式一: export OPENLIST_USER=xxx OPENLIST_PASS=xxx"
echo " 方式二: export OPENLIST_TOKEN=xxx"
exit 1
fi
UPLOAD_ROOT="${OPENLIST_PATH:-/Quark}"
UPLOAD_MODE="${UPLOAD_MODE:-auto}"
PKG_VERSION=$(cat "$PKG_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' || echo "unknown")
# 去除路径末尾的 /
UPLOAD_ROOT="${UPLOAD_ROOT%/}"
# 自动检测上传模式
if [ "$UPLOAD_MODE" = "auto" ]; then
if ls "$DIST_DIR"/*_offline.run >/dev/null 2>&1; then
UPLOAD_MODE="offline"
elif ls "$DIST_DIR"/*.run >/dev/null 2>&1 || ls "$DIST_DIR"/*.ipk >/dev/null 2>&1; then
UPLOAD_MODE="online"
else
echo "错误: 无法自动检测上传模式dist 目录中无可识别文件"
exit 1
fi
fi
# 根据模式设置子目录和文件匹配规则
case "$UPLOAD_MODE" in
offline)
UPLOAD_SUBDIR="openclaw-离线安装"
;;
online)
UPLOAD_SUBDIR="openclaw-在线安装"
;;
*)
echo "错误: 无效的 UPLOAD_MODE: $UPLOAD_MODE (可选: offline / online / auto)"
exit 1
;;
esac
OPENLIST_URL="${OPENLIST_URL%/}"
log_info() { echo " [✓] $1"; }
log_warn() { echo " [!] $1"; }
log_error() { echo " [✗] $1"; }
# ── 获取 Token ──
get_token() {
if [ -n "$OPENLIST_TOKEN" ]; then
echo "$OPENLIST_TOKEN"
return
fi
log_info "正在登录 OpenList..." >&2
local resp
resp=$(curl -s -X POST "${OPENLIST_URL}/api/auth/login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"${OPENLIST_USER}\",\"password\":\"${OPENLIST_PASS}\"}" 2>/dev/null)
local token
# 尝试解析 JSON 响应 (兼容多种 alist 版本)
# alist v3 响应格式: {"code":200,"data":{"token":"xxx"},"message":"success"}
if command -v jq >/dev/null 2>&1; then
token=$(echo "$resp" | jq -r '.data.token // empty' 2>/dev/null)
else
# 无 jq 时用 grep/sed 提取
token=$(echo "$resp" | grep -o '"token":"[^"]*"' | sed 's/"token":"//;s/"//')
fi
if [ -z "$token" ]; then
log_error "登录失败" >&2
echo " 响应: $resp" >&2
exit 1
fi
log_info "登录成功" >&2
echo "$token"
}
# ── 创建远程目录 ──
create_remote_dir() {
local token="$1"
local remote_path="$2"
curl -s -X POST "${OPENLIST_URL}/api/fs/mkdir" \
-H "Authorization: ${token}" \
-H "Content-Type: application/json" \
-d "{\"path\":\"${remote_path}\"}" >/dev/null 2>&1 || true
}
# ── 上传单个文件 ──
upload_file() {
local token="$1"
local local_file="$2"
local remote_path="$3"
local filename=$(basename "$local_file")
local fsize=$(du -h "$local_file" | cut -f1)
echo " 上传: ${filename} (${fsize})..."
local resp
resp=$(curl -s -X PUT "${OPENLIST_URL}/api/fs/put" \
-H "Authorization: ${token}" \
-H "File-Path: ${remote_path}/${filename}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@${local_file}" \
--max-time 3600 2>/dev/null)
# 检查响应
local code=""
if command -v jq >/dev/null 2>&1; then
code=$(echo "$resp" | jq -r '.code // empty' 2>/dev/null)
else
code=$(echo "$resp" | grep -o '"code":[0-9]*' | grep -o '[0-9]*')
fi
if [ "$code" = "200" ]; then
log_info "${filename} 上传成功"
else
log_error "${filename} 上传失败"
echo " 响应: $resp"
fi
}
# ── 主流程 ──
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ 上传到 OpenList 网盘 ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo " 服务地址: ${OPENLIST_URL}"
echo " 上传模式: ${UPLOAD_MODE}"
echo " 上传路径: ${UPLOAD_ROOT}/${UPLOAD_SUBDIR}/v${PKG_VERSION}"
echo " 本地目录: ${DIST_DIR}"
echo ""
# 查找要上传的文件
UPLOAD_FILES=""
case "$UPLOAD_MODE" in
offline)
# 离线包: 仅 *_offline.run 文件
UPLOAD_FILES=$(find "$DIST_DIR" -name "*_offline.run" 2>/dev/null)
;;
online)
# 在线包: .run (非 offline) + .ipk
for f in "$DIST_DIR"/*.run "$DIST_DIR"/*.ipk; do
[ -f "$f" ] || continue
case "$(basename "$f")" in *_offline.run) continue ;; esac
UPLOAD_FILES="$UPLOAD_FILES $f"
done
UPLOAD_FILES=$(echo "$UPLOAD_FILES" | sed 's/^ //')
;;
esac
if [ -z "$UPLOAD_FILES" ]; then
echo "错误: 未找到可上传的文件"
echo " 模式: $UPLOAD_MODE"
echo " 目录: $DIST_DIR"
exit 1
fi
# 获取 token
TOKEN=$(get_token)
# 创建远程目录
REMOTE_DIR="${UPLOAD_ROOT}/${UPLOAD_SUBDIR}/v${PKG_VERSION}"
echo ""
echo "创建远程目录: ${REMOTE_DIR}"
create_remote_dir "$TOKEN" "$REMOTE_DIR"
# 上传文件
echo ""
echo "开始上传..."
UPLOAD_COUNT=0
for f in $UPLOAD_FILES; do
upload_file "$TOKEN" "$f" "$REMOTE_DIR"
UPLOAD_COUNT=$((UPLOAD_COUNT + 1))
done
echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
printf "║ ✅ 上传完成!共 %-2s 个文件 ║\n" "$UPLOAD_COUNT"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "下载地址: ${OPENLIST_URL}${REMOTE_DIR}"