153 lines
2.9 KiB
Bash
Executable File
153 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ENV_FILE="${SHX_ENV_FILE:-/root/.openclaw/.env}"
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
set -a
|
|
source "$ENV_FILE"
|
|
set +a
|
|
fi
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
shx-upload <file> [more files...]
|
|
shx-upload --json <file>
|
|
|
|
Env:
|
|
SHX_URL Base URL, e.g. https://shx.reversed.dev
|
|
SHX_TOKEN Zipline API token from the dashboard
|
|
|
|
Notes:
|
|
- Username/password are only for dashboard login.
|
|
- Uploads use an API token.
|
|
EOF
|
|
}
|
|
|
|
have_jq() {
|
|
command -v jq >/dev/null 2>&1
|
|
}
|
|
|
|
print_server_message() {
|
|
local response="$1"
|
|
local message=""
|
|
|
|
[[ -n "$response" ]] || return 0
|
|
|
|
if have_jq; then
|
|
message="$(
|
|
printf '%s\n' "$response" |
|
|
jq -r 'if type=="object" then .error // .message // .reason // empty else empty end' 2>/dev/null ||
|
|
true
|
|
)"
|
|
fi
|
|
|
|
if [[ -n "$message" ]]; then
|
|
echo "server: $message" >&2
|
|
else
|
|
echo "server response: $response" >&2
|
|
fi
|
|
}
|
|
|
|
response_has_files() {
|
|
local response="$1"
|
|
|
|
if have_jq; then
|
|
printf '%s\n' "$response" | jq -e '.files | arrays and length > 0' >/dev/null 2>&1
|
|
return $?
|
|
fi
|
|
|
|
[[ "$response" == *'"files"'* ]] || return 1
|
|
[[ "$response" =~ \"files\"[[:space:]]*:[[:space:]]*\[[[:space:]]*\] ]] && return 1
|
|
return 0
|
|
}
|
|
|
|
want_json=0
|
|
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${1:-}" == "--json" ]]; then
|
|
want_json=1
|
|
shift
|
|
fi
|
|
|
|
if [[ $# -lt 1 ]]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
: "${SHX_URL:=}"
|
|
: "${SHX_TOKEN:=${ZIPLINE_TOKEN:-}}"
|
|
|
|
if [[ -z "$SHX_URL" ]]; then
|
|
echo "error: SHX_URL is not set" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "$SHX_TOKEN" ]]; then
|
|
cat >&2 <<EOF
|
|
error: SHX_TOKEN is not set
|
|
|
|
Create one in the Zipline dashboard, then add it to $ENV_FILE like:
|
|
SHX_TOKEN=your_token_here
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
upload_one() {
|
|
local file="$1"
|
|
local body_file http_code response
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "error: file not found: $file" >&2
|
|
return 1
|
|
fi
|
|
|
|
body_file="$(mktemp)"
|
|
if ! http_code="$(curl -sS \
|
|
-o "$body_file" \
|
|
-w '%{http_code}' \
|
|
-H "authorization: $SHX_TOKEN" \
|
|
"$SHX_URL/api/upload" \
|
|
-F "file=@$file")"; then
|
|
rm -f "$body_file"
|
|
echo "error: upload request failed for $file" >&2
|
|
return 1
|
|
fi
|
|
|
|
response="$(cat "$body_file")"
|
|
rm -f "$body_file"
|
|
|
|
if [[ ! "$http_code" =~ ^2[0-9][0-9]$ ]]; then
|
|
echo "error: upload failed for $file (HTTP $http_code)" >&2
|
|
print_server_message "$response"
|
|
return 1
|
|
fi
|
|
|
|
if ! response_has_files "$response"; then
|
|
echo "error: upload response missing a non-empty .files array for $file" >&2
|
|
print_server_message "$response"
|
|
return 1
|
|
fi
|
|
|
|
if [[ $want_json -eq 1 ]]; then
|
|
printf '%s\n' "$response"
|
|
else
|
|
if ! have_jq; then
|
|
echo "error: jq is required unless --json is used" >&2
|
|
return 1
|
|
fi
|
|
printf '%s\n' "$response" | jq -r '.files[]'
|
|
fi
|
|
}
|
|
|
|
status=0
|
|
for file in "$@"; do
|
|
if ! upload_one "$file"; then
|
|
status=1
|
|
fi
|
|
done
|
|
|
|
exit $status
|