Skip to content

Instantly share code, notes, and snippets.

@DonRichards
Created June 25, 2026 18:55
Show Gist options
  • Select an option

  • Save DonRichards/8f66e392b1e27a018cbd874de8c85fa7 to your computer and use it in GitHub Desktop.

Select an option

Save DonRichards/8f66e392b1e27a018cbd874de8c85fa7 to your computer and use it in GitHub Desktop.
fix Dataverse previewer urls
#!/usr/bin/env bash
# chmod +x fix_previewer_urls.sh
# ./chmod +x fix_previewer_urls.sh
set -euo pipefail
SERVER_URL="${SERVER_URL:-http://localhost:8080}"
OLD_BASE="${OLD_BASE:-https://old-site.jhu.edu}"
NEW_BASE="${NEW_BASE:-https://new-site.jhu.edu}"
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "ERROR: Missing required command: $1" >&2
exit 1
}
}
require_cmd curl
require_cmd jq
require_cmd mktemp
if [[ -z "${API_TOKEN:-}" ]]; then
read -r -s -p "Dataverse superuser API token: " API_TOKEN
echo
fi
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
timestamp="$(date +%Y%m%d-%H%M%S)"
backup_file="external-tools-backup-${timestamp}.json"
echo "Server: ${SERVER_URL}"
echo "Replacing:"
echo " ${OLD_BASE}"
echo "with:"
echo " ${NEW_BASE}"
echo
echo "Downloading current external tools..."
curl -sS "${SERVER_URL}/api/externalTools" > "$backup_file"
jq -e '.status == "OK" and (.data | type == "array")' "$backup_file" >/dev/null
echo "Backup written to: ${backup_file}"
echo
mapfile -t TOOL_IDS < <(
jq -r --arg old "$OLD_BASE" '
.data[]
| select(.toolUrl | type == "string" and startswith($old))
| .id
' "$backup_file"
)
if [[ "${#TOOL_IDS[@]}" -eq 0 ]]; then
echo "No external tools found with toolUrl starting with ${OLD_BASE}"
exit 0
fi
echo "Tools that will be replaced:"
jq -r --arg old "$OLD_BASE" --arg new "$NEW_BASE" '
.data[]
| select(.toolUrl | type == "string" and startswith($old))
| [
("id=" + (.id|tostring)),
.displayName,
.contentType,
.toolUrl,
($new + (.toolUrl | ltrimstr($old)))
]
| @tsv
' "$backup_file" | column -t -s $'\t'
echo
read -r -p "Proceed with deleting/re-adding these tools? Type yes to continue: " CONFIRM
if [[ "$CONFIRM" != "yes" ]]; then
echo "Aborted. No changes made."
exit 0
fi
echo
for tool_id in "${TOOL_IDS[@]}"; do
manifest="${tmpdir}/external-tool-${tool_id}.json"
jq --argjson id "$tool_id" --arg old "$OLD_BASE" --arg new "$NEW_BASE" '
.data[]
| select(.id == $id)
| del(.id)
| .toolUrl = ($new + (.toolUrl | ltrimstr($old)))
' "$backup_file" > "$manifest"
display_name="$(jq -r '.displayName' "$manifest")"
content_type="$(jq -r '.contentType // "no contentType"' "$manifest")"
new_url="$(jq -r '.toolUrl' "$manifest")"
echo "Updating tool id=${tool_id}: ${display_name} (${content_type})"
echo " New URL: ${new_url}"
echo " Deleting old tool..."
curl -sS -f \
-H "X-Dataverse-key: ${API_TOKEN}" \
-X DELETE \
"${SERVER_URL}/api/externalTools/${tool_id}" >/dev/null
echo " Re-adding corrected tool..."
curl -sS -f \
-H "X-Dataverse-key: ${API_TOKEN}" \
-H "Content-Type: application/json" \
-X POST \
--upload-file "$manifest" \
"${SERVER_URL}/api/externalTools" >/dev/null
echo " Done."
echo
done
echo "Verifying remaining references to ${OLD_BASE}..."
remaining="$(
curl -sS "${SERVER_URL}/api/externalTools" \
| jq -r --arg old "$OLD_BASE" '
.data[]
| select(.toolUrl | type == "string" and startswith($old))
| "\(.id) \(.toolUrl)"
'
)"
if [[ -n "$remaining" ]]; then
echo "WARNING: Some tools still point to ${OLD_BASE}:"
echo "$remaining"
exit 1
fi
echo "All matching external tool URLs have been updated."
echo "Backup is available at: ${backup_file}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment