79 lines
2.9 KiB
Bash
79 lines
2.9 KiB
Bash
#!/bin/bash
|
|
# Shared by post.sh and terms.sh: layered config loading and base URL
|
|
# construction. The caller sets SITE (possibly empty) and CONFIG_DIR before
|
|
# calling wp_load_config, and USER/PASSWORD/SERVER/... end up in scope.
|
|
|
|
CONFIG_DIR="${WORDPRESS_REST_CURL_CONFIG_DIR:-$HOME/.config/wordpress-rest-curl}"
|
|
|
|
wp_load_config() {
|
|
local default_config_file="$CONFIG_DIR/config.sh"
|
|
[[ -e "$default_config_file" ]] && source "$default_config_file"
|
|
|
|
if [[ -n "$SITE" ]]; then
|
|
local site_config_file="$CONFIG_DIR/$SITE.sh"
|
|
[[ -e "$site_config_file" ]] || { echo "Config file not found: $site_config_file" >&2; exit 1; }
|
|
source "$site_config_file"
|
|
elif [[ ! -e "$default_config_file" ]]; then
|
|
echo "No site specified and no default config found. Pass --site NAME or create $default_config_file" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Prints $SERVER normalized into a scheme-qualified, slash-trimmed base URL.
|
|
wp_base_url() {
|
|
local base_url="$SERVER"
|
|
[[ "$base_url" != http://* && "$base_url" != https://* ]] && base_url="https://$base_url"
|
|
echo "${base_url%/}"
|
|
}
|
|
|
|
# Runs curl against the WP REST API with shared auth/UA/error-handling.
|
|
# Usage: wp_api_call METHOD PATH [curl-args...]
|
|
# Prints the response body on success; on a non-2xx status prints the error
|
|
# to stderr and returns 1 (does not exit, so callers can decide what to do).
|
|
wp_api_call() {
|
|
local method="$1" path="$2"
|
|
shift 2
|
|
local response http_code body
|
|
response=$(curl --silent --show-error --user "$USER:$PASSWORD" -X "$method" \
|
|
-A "$USER_AGENT" \
|
|
-w '\n%{http_code}' \
|
|
"$@" \
|
|
"$(wp_base_url)$path")
|
|
http_code=$(echo "$response" | tail -n1)
|
|
body=$(echo "$response" | sed '$d')
|
|
if [[ "$http_code" -lt 200 || "$http_code" -ge 300 ]]; then
|
|
echo "Error: WordPress API returned HTTP $http_code" >&2
|
|
echo "$body" >&2
|
|
return 1
|
|
fi
|
|
echo "$body"
|
|
}
|
|
|
|
# Prints every item across all pages of a paginated WP list endpoint at
|
|
# PATH, one JSON object per line.
|
|
wp_api_list_all() {
|
|
local path="$1" page=1 count body
|
|
while :; do
|
|
body=$(wp_api_call GET "$path?per_page=100&page=$page") || exit 1
|
|
count=$(echo "$body" | jq 'length')
|
|
[[ "$count" -eq 0 ]] && break
|
|
echo "$body" | jq -c '.[]'
|
|
[[ "$count" -lt 100 ]] && break
|
|
page=$((page + 1))
|
|
done
|
|
}
|
|
|
|
# Resolves NAME to a numeric term ID under taxonomy endpoint PATH (e.g.
|
|
# /wp-json/wp/v2/categories), creating the term first if it doesn't exist.
|
|
wp_resolve_term() {
|
|
local path="$1" name="$2" found_id payload body
|
|
found_id=$(wp_api_list_all "$path" | jq -r --arg name "$name" 'select(.name == $name) | .id' | head -n1)
|
|
if [[ -n "$found_id" ]]; then
|
|
echo "$found_id"
|
|
return
|
|
fi
|
|
payload=$(jq -n --arg name "$name" '{name: $name}')
|
|
body=$(wp_api_call POST "$path" -H "Content-Type: application/json" --data "$payload") || exit 1
|
|
echo "$body" | jq -r '.id'
|
|
}
|