diff --git a/Qortal-Setup-Linux.sh b/Qortal-Setup-Linux.sh new file mode 100644 index 0000000..5c68fc0 --- /dev/null +++ b/Qortal-Setup-Linux.sh @@ -0,0 +1,227 @@ +#!/bin/bash +set -e +trap 'echo -e "\n${RED}❌ Setup cancelled by user. Exiting...${NC}"; exit 1' INT + +# Color Codes +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +CYAN='\033[0;36m' +RED='\033[0;31m' +NC='\033[0m' + +BACKUP_EXECUTED=false + +echo -e "${CYAN}🚀 Qortal Core + Hub Setup Script (Universal Linux) 🚀${NC}\n" + +# Detect Distro +if [ -f /etc/os-release ]; then + . /etc/os-release + DISTRO=$ID + VERSION=$VERSION_ID +else + echo -e "${RED}❌ Cannot detect Linux distribution. Please install dependencies manually.${NC}" + exit 1 +fi + +echo -e "${YELLOW}📋 Detected distro: ${DISTRO} ${VERSION}${NC}" + +# Install Required Packages +echo -e "${CYAN}🔧 Installing dependencies...${NC}" +case "$DISTRO" in + ubuntu|debian) + sudo apt update + sudo apt install -y openjdk-17-jre curl unzip libfuse2 jq zlib1g-dev + ;; + fedora) + sudo dnf install -y java-17-openjdk curl unzip fuse jq zlib-devel + ;; + arch) + sudo pacman -Sy --noconfirm jre17-openjdk curl unzip fuse2 jq zlib + ;; + alpine) + sudo apk add --no-cache openjdk17 curl unzip fuse jq zlib-dev + ;; + *) + echo -e "${RED}âš ī¸ Unsupported distro: ${DISTRO}. Please install openjdk-17, curl, unzip, jq, zlib1g-dev and fuse manually.${NC}" + ;; +esac + +# Download and Install Qortal Core +echo -e "${CYAN}âŦ‡ī¸ Downloading Qortal Core...${NC}" +cd "$HOME" +if [ -d "$HOME/qortal" ]; then + "${HOME}/qortal/stop.sh" + mkdir -p "$HOME/backups" + echo -e "${YELLOW}âš ī¸ Existing 'qortal' folder found. Backing it up...${NC}" + mv "$HOME/qortal" "$HOME/backups/qortal-$(date +%s)" + BACKUP_EXECUTED=true +fi + +curl -LO https://github.com/Qortal/qortal/releases/latest/download/qortal.zip +unzip qortal.zip +rm qortal.zip +chmod +x "$HOME/qortal/"*.sh + +# Download Architecture-specific Qortal Hub +echo -e "\n ${CYAN}Checking for Desktop Environment..." +if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ] || [ -n "$XDG_CURRENT_DESKTOP" ]; then + echo -e "\n ${YELLOW} Setting up Qortal Icon Theme..." + curl -LO https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/create-icon-theme.sh + chmod +x create-icon-theme.sh + ./create-icon-theme.sh + echo -e "\n ${GREEN} DESKTOP ENVIRONMENT FOUND, INSTALLING QORTAL HUB..." + + ARCH=$(uname -m) + echo -e "\n ${CYAN}🔍 Detected architecture: $ARCH${NC}" + cd "$HOME/qortal" + if [ "$ARCH" = "aarch64" ]; then + echo -e "ARM64 NEEDED. Making required modifications to url..." + HUB_URL="https://github.com/Qortal/Qortal-Hub/releases/latest/download/Qortal-Hub-arm64/AppImage" + else + HUB_URL="https://github.com/Qortal/Qortal-Hub/releases/latest/download/Qortal-Hub.AppImage" + fi + + echo -e "\n ${CYAN}âŦ‡ī¸ Downloading Qortal Hub...${NC}" + curl -LO "$HUB_URL" + mv Qortal-Hub* Qortal-Hub + chmod +x Qortal-Hub + + cd ${HOME} + + echo -e "\n ${CYAN}🚀 Testing Qortal Hub launch to check if no-sandbox flag is required...${NC}" + + "$HOME/qortal/Qortal-Hub" & + HUB_PID=$! + sleep 5 + if ! ps -p "$HUB_PID" > /dev/null; then + echo -e "${YELLOW}âš ī¸ Qortal Hub failed without --no-sandbox. Updating launcher accordingly...${NC}" + SANDBOX_FLAG=" --no-sandbox" + else + echo -e "${GREEN}✅ Qortal Hub launched successfully without --no-sandbox. Killing running test instance...${NC}" + SANDBOX_FLAG="" + kill -15 ${HUB_PID} + killall -15 "Qortal Hub" + fi + + echo -e "${GREEN}✅ Qortal Core + Hub downloaded and ready!${NC}" + + # Optional: Install Desktop Launchers if desktop detected + if command -v xdg-desktop-menu >/dev/null 2>&1; then + echo -e "${CYAN}đŸ–Ĩī¸ Setting up desktop launchers...${NC}" + mkdir -p "$HOME/.local/share/applications" + + cat > "$HOME/.local/share/applications/qortal-hub.desktop" < "${HOME}/Desktop/qortal-hub.desktop" </dev/null 2>&1; then + if jq -e 'has("dataPath")' "${LATEST_BACKUP}/settings.json" >/dev/null 2>&1; then + echo -e "\n ✅ dataPath found in backup settings." + DATA_PATH=$(jq -r '.dataPath' "${LATEST_BACKUP}/settings.json") + echo -e "\n 📁 dataPath: $DATA_PATH" + echo -e "\n 🔁 Putting dataPath into new settings.json..." + + # Apply to the new settings safely + jq --arg path "$DATA_PATH" '.dataPath = $path' \ + "${HOME}/qortal/settings.json" > "${HOME}/qortal/settings.tmp" && \ + mv "${HOME}/qortal/settings.tmp" "${HOME}/qortal/settings.json" + else + echo -e "\n ❌ dataPath not found in settings.json (data likely default, already restored). Proceeding..." + DATA_PATH="" + fi + else + echo -e "${RED}âš ī¸ jq not installed. Cannot extract dataPath safely.${NC}" + echo -e "${YELLOW}If you used a custom data path, you'll need to manually restore it into settings.json.${NC}" + DATA_PATH="" + fi + echo -e "\n${YELLOW} Data should have been restored, however, please verify this if it matters to you. QDN data can usually be re-obtained from Qortal, but if you are the only publisher of the data, may not be able to be, just FYI..." +fi + +echo -e "\n${GREEN}🎉 Qortal setup complete! You can now start Qortal Core and Qortal Hub.${NC}" +echo -e "\n${YELLOW}đŸ› ī¸ Would you like to install Qortal Automation scripts by crowetic?${NC}" +echo -e "${CYAN}This will:\n - Ensure Qortal is always running\n - Stay within 1500 blocks of the network\n - Auto-update Core + potentially settings\n - Recover from common issues\n - Configure autostart or cron${NC}" +echo -e "${YELLOW}Install automation now? (y/N) — auto-skip in 20 seconds...${NC}" +read -t 20 -r -p "âžĄī¸ Your choice (y/N): " INSTALL_AUTOFIX + +# Check for timeout or input +if [ $? -eq 0 ]; then + if [[ "$INSTALL_AUTOFIX" =~ ^[Yy]$ ]]; then + INSTALL_AUTOMATION=true + else + INSTALL_AUTOMATION=false + fi +else + echo -e "\n${YELLOW}âŗ Timeout reached. Installing automation by default${NC}" + INSTALL_AUTOMATION=true +fi + +if [[ "$INSTALL_AUTOMATION" = true ]]; then + echo -e "${CYAN}About to run automation... Press Ctrl+C now to cancel (20s delay)...${NC}" + sleep 5 + echo -e "\n 15 seconds left to cancel automation..." + sleep 5 + echo -e "\n 10 seconds left to cancel automation..." + sleep 5 + echo -e "\n push cntrl+c within 5 seconds or automation will continue..." + sleep 1 + echo -e "4..." + sleep 1 + echo -e "...3..." + sleep 1 + echo -e "...2..." + sleep 1 + echo -e "...1" + sleep 1 + echo -e "\n automation continuing!" + echo -e "\n ${CYAN}đŸ“Ĩ Downloading auto-fix-qortal.sh...${NC}" + curl -L -o "$HOME/auto-fix-qortal.sh" https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/auto-fix-qortal.sh + chmod +x "$HOME/auto-fix-qortal.sh" + echo -e "\n ${GREEN}✅ Automation script downloaded.✅ ${NC}" + echo -e "\n ${CYAN}🚀 Running auto-fix-qortal.sh...${NC}" + "$HOME/auto-fix-qortal.sh" +else + echo -e "${YELLOW}Skipping automation setup. You can install it later by running:${NC}" + echo -e "\n ${GREEN}curl -L -o ~/auto-fix-qortal.sh https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/auto-fix-qortal.sh && chmod +x ~/auto-fix-qortal.sh && cd && ./auto-fix-qortal.sh${NC}" +fi + diff --git a/auto-fix-qortal.sh b/auto-fix-qortal.sh index b7192f3..13ba577 100644 --- a/auto-fix-qortal.sh +++ b/auto-fix-qortal.sh @@ -143,7 +143,7 @@ check_qortal() { echo "${CYAN} NODE DOES NOT SEEM TO BE RUNNING? CHECKING IF NODE IS BOOTSTRAPPING...${NC}\n" - if tail -n 10 "${HOME}/qortal/qortal.log" | grep -Ei 'bootstrap|bootstrapping' > /dev/null; then + if tail -n 20 "${HOME}/qortal/qortal.log" | grep -Ei 'bootstrap|bootstrapping' > /dev/null; then echo "${RED}Node seems to be bootstrapping, updating script and exiting...${NC}\n" update_script fi @@ -201,7 +201,7 @@ check_hash_update_qortal() { } check_for_GUI() { - if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then + if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ] || [ -n "$XDG_CURRENT_DESKTOP" ]; then echo "${CYAN}Machine has GUI, setting up auto-fix-visible for GUI-based machines...${NC}\n" if [ "${RASPI_32_DETECTED}" = true ] || [ "${RASPI_64_DETECTED}" = true ]; then echo "${YELLOW}Pi machine with GUI, skipping autostart GUI setup, setting cron jobs instead...${NC}\n" @@ -237,15 +237,15 @@ setup_raspi_cron() { echo "${YELLOW}Checking if autostart desktop shortcut exists to avoid double-launch...${NC}\n" if find "${HOME}/.config/autostart" -maxdepth 1 -name "start-qortal*.desktop" | grep -q .; then - echo "${RED}Autostart desktop entry found! Removing that and replacing with cron entry${NC}\n" + echo "${RED}Autostart desktop entry found! Adding automatic run every 3 days for auto-fix script in cron...${NC}\n" # rm -rf "${HOME}/.config/autostart/start-qortal*.desktop" "${HOME}/.config/autostart/auto-fix-qortal*.desktop" - curl -L -O https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/auto-fix-GUI-cron - crontab auto-fix-GUI-cron - rm -f auto-fix-GUI-cron + curl -L -O https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/auto-fix-GUI-cron + crontab auto-fix-GUI-cron + rm -f auto-fix-GUI-cron # curl -L -O https://raw.githubusercontent.com/crowetic/QORTector-scripts/refs/heads/main/auto-fix-cron # crontab auto-fix-cron # rm -f auto-fix-cron - check_height + check_height fi echo "${BLUE}No autostart entries found. Setting up full headless cron...${NC}\n" @@ -268,8 +268,14 @@ check_height() { checked_height=$(curl -s "http://localhost:12391/blocks/height") sleep 2 if [ "$checked_height" = "$previous_local_height" ]; then - echo "${RED}Block height still unchanged... forcing bootstrap...${NC}\n" - force_bootstrap + echo "${RED}Block height still unchanged... final sanity check in 10 seconds..${NC}\n" + sleep 10 + new_check_again=$(curl -sS "http://localhost:12391/blocks/height") + echo "new height = $new_check_again | previously checked height = $previous_local_height" + if [ "$new_check_again" = "$previous_local_height" ]; then + echo "${RED}Block height still unchanged... forcing bootstrap...${NC}\n" + force_bootstrap + fi fi fi fi @@ -288,7 +294,7 @@ no_local_height() { echo "${WHITE}Checking if node is bootstrapping or not...${NC}\n" if [ -f "${HOME}/qortal/qortal.log" ]; then - if tail -n 10 "${HOME}/qortal/qortal.log" | grep -Ei 'bootstrap|bootstrapping' > /dev/null; then + if tail -n 30 "${HOME}/qortal/qortal.log" | grep -Ei 'bootstrap|bootstrapping' > /dev/null; then echo "${RED}Node seems to be bootstrapping, updating script and exiting...${NC}\n" update_script fi @@ -369,7 +375,7 @@ force_bootstrap() { cd "${HOME}/qortal" || exit 1 killall -9 java sleep 3 - rm -rf db log.t* qortal.log run.log run.pid + rm -rf db log.t* qortal.log run.log run.pid *.gz sleep 5 ./start.sh cd || exit 1 @@ -389,9 +395,9 @@ potentially_update_settings() { mkdir -p "${BACKUP_FOLDER}" # Step 1: Backup settings.json - cp "${SETTINGS_FILE}" "${BACKUP_FILE}" + cp "${SETTINGS_FILE}" "${BACKUP_FOLDER}/${BACKUP_FILE}" - ### Step 2: Validate with jq or fallback ### + # Step 2: Validate with jq is_valid_json=false if command -v jq &>/dev/null; then echo "${YELLOW}Using jq to validate JSON...${NC}" @@ -402,48 +408,38 @@ potentially_update_settings() { fi fi else - echo "${YELLOW}jq not found, doing basic manual check...${NC}" - if grep -q '^{.*}$' "${SETTINGS_FILE}"; then - is_valid_json=true - echo "${GREEN}Basic structure appears valid (manual fallback).${NC}" - fi + echo "${RED}jq not found. Skipping JSON validation.${NC}" fi - ### Step 3: If invalid, try to fix ### + # Step 3: If invalid, try to fix if [ "${is_valid_json}" != true ]; then - echo "${RED}settings.json is invalid. Attempting fix...${NC}" + echo "${RED}settings.json is invalid or validation skipped. Attempting fix...${NC}" echo "${YELLOW}Trying to restore from backup: ${BACKUP_FILE}${NC}" - cp "${BACKUP_FILE}" "${SETTINGS_FILE}" + cp "${BACKUP_FOLDER}/${BACKUP_FILE}" "${SETTINGS_FILE}" - # Re-validate after restoring backup if command -v jq &>/dev/null && jq empty "${SETTINGS_FILE}" 2>/dev/null; then echo "${GREEN}Backup restored successfully and is valid.${NC}" else echo "${RED}Backup also invalid. Downloading default settings.json...${NC}" - curl -L -O "https://raw.githubusercontent.com/crowetic/QORTector-scripts/refs/heads/main/settings.json" + curl -L -o "${SETTINGS_FILE}" "https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/settings.json" - # Final validation if command -v jq &>/dev/null && jq empty "${SETTINGS_FILE}" 2>/dev/null; then echo "${GREEN}Default settings.json downloaded and is valid.${NC}" else echo "${RED}Failed to recover a valid settings.json. Manual intervention required.${NC}" - cd || exit 1 return 1 fi fi fi - ### Step 4: Rotate backups (keep 2 newest) ### - + # Step 4: Rotate backups (keep 2 newest) echo "${YELLOW}Rotating old backups (keeping only 2)...${NC}" cd "${BACKUP_FOLDER}" || exit 1 - backup_count=$(ls -1 backup-settings-*.json 2>/dev/null | wc -l) - - if [ "$backup_count" -gt 2 ]; then - # List oldest first, delete all but the 2 most recent - for old_backup in $(ls -1tr backup-settings-*.json | head -n -$((backup_count - 2))); do + to_delete=$((backup_count - 2)) + if [ "$to_delete" -gt 0 ]; then + for old_backup in $(ls -1tr backup-settings-*.json | head -n "$to_delete"); do echo "Deleting old backup: $old_backup" rm -f "$old_backup" done @@ -451,10 +447,7 @@ potentially_update_settings() { echo "${BLUE}No old backups to delete.${NC}" fi - cd - >/dev/null || exit 1 - echo "${GREEN}Settings file is now valid. Proceeding...${NC}" - cd || exit 1 return 0 } @@ -476,7 +469,7 @@ update_script() { sleep 2 potentially_update_settings rm -rf "${HOME}/qortal.jar" "${HOME}/run.pid" "${HOME}/run.log" "${HOME}/remote.md5" "${HOME}/qortal/local.md5" - mkdir -p ${HOME}/backups && mv ${HOME}/qortal/backup-settings* ${HOME}/backups + rm -rf ${HOME}/backups/backup-settings* echo "${YELLOW}Auto-fix script run complete.${NC}\n" sleep 5 exit diff --git a/create-icon-theme.sh b/create-icon-theme.sh new file mode 100644 index 0000000..00d70ff --- /dev/null +++ b/create-icon-theme.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +for cmd in rsync curl unzip convert; do + if ! command -v $cmd >/dev/null; then + echo "[!] Required command '$cmd' is not installed. Please install it and re-run." + exit 1 + fi +done + +# Customize Yaru-blue-dark icon theme locally and add Qortal icons +ICON_THEME_NAME="Yaru-blue-qortal" +ICON_SOURCE_DIR="${HOME}/Pictures/icons/icons_theme" +ICON_CACHE_DIR="${HOME}/.icons/${ICON_THEME_NAME}" +TARGET_THEME_DIR="${ICON_CACHE_DIR}/48x48/apps" + +if [ ! -d "${ICON_SOURCE_DIR}" ]; then + echo "downloading icon files..." + mkdir -p "${HOME}/iconTemp" + trap 'rm -rf "${HOME}/iconTemp"' EXIT + cd "${HOME}/iconTemp" + curl -L -O https://cloud.qortal.org/s/machinePicturesFolder/download + unzip download + mv Pictures/* "${HOME}/Pictures/" + rm -rf "${HOME}/iconTemp" + cd +fi + +# Mapping of source icons to icon names +declare -A ICON_MAP=( + ["qortal-menu-button.png"]="qortal-menu-button" + ["qortal-menu-button-2.png"]="qortal-menu-button-2" + ["qortal-menu-button-3.png"]="qortal-menu-button-3" + ["qortal-menu-button-4.png"]="qortal-menu-button-4" + ["qortal-ui.png"]="qortal-ui" + ["qortal-hub.png"]="qortal-hub" + ["qortal.png"]="qortal" +) + +# Step 1: Copy system Yaru-dark theme as base +if [ ! -d "${ICON_CACHE_DIR}" ]; then + echo "[*] Creating local copy of Yaru-dark theme as '${ICON_THEME_NAME}'..." + mkdir -p "${ICON_CACHE_DIR}" + rsync -a /usr/share/icons/Yaru-dark/ "${ICON_CACHE_DIR}/" + + # Copy index.theme from Yaru-blue-dark if it exists + if [ -f /usr/share/icons/Yaru-blue-dark/index.theme ]; then + cp /usr/share/icons/Yaru-blue-dark/index.theme "${ICON_CACHE_DIR}/index.theme" + fi + + # Update index.theme metadata + sed -i 's/^Name=.*/Name=Yaru-blue-qortal/' "${ICON_CACHE_DIR}/index.theme" + sed -i 's/^Inherits=.*/Inherits=Yaru-blue-dark,Yaru-dark,Yaru,hicolor/' "${ICON_CACHE_DIR}/index.theme" + + # Ensure Directories includes 48x48/apps + if ! grep -q "48x48/apps" "${ICON_CACHE_DIR}/index.theme"; then + echo "Directories=48x48/apps" >> "${ICON_CACHE_DIR}/index.theme" + echo " +[48x48/apps] +Size=48 +Context=Applications +Type=Fixed" >> "${ICON_CACHE_DIR}/index.theme" + fi +fi + +# Step 2: Ensure target icon directory exists +mkdir -p "${TARGET_THEME_DIR}" + +# Step 3: Install icons (resized if possible) +install_icon() { + local src="$1" + local name="$2" + local dest="${TARGET_THEME_DIR}/${name}.png" + + if [ ! -f "$src" ]; then + echo "[!] Source icon not found: $src" + return + fi + + if command -v convert &>/dev/null; then + echo "[*] Resizing and installing $name to ${TARGET_THEME_DIR}" + convert "$src" -resize 48x48 "$dest" + else + echo "[*] Copying $name without resizing to ${TARGET_THEME_DIR}" + cp "$src" "$dest" + fi +} + +# Step 4: Loop through and install icons +for src in "${!ICON_MAP[@]}"; do + install_icon "${ICON_SOURCE_DIR}/${src}" "${ICON_MAP[$src]}" +done + +# Step 5: Update the icon cache +if [ -f "${ICON_CACHE_DIR}/index.theme" ]; then + echo "[*] Updating icon cache for '${ICON_THEME_NAME}'..." + gtk-update-icon-cache -f "${ICON_CACHE_DIR}" || echo "[!] gtk-update-icon-cache failed or not found." +else + echo "[!] No index.theme file found. Cannot update icon cache." +fi + +# Step 6: Set as active icon theme +if [ -z "$CURRENT_DESKTOP" ]; then + echo "[!] XDG_CURRENT_DESKTOP not set. Unable to auto-detect DE. Set icon theme manually if needed." +else + echo "[*] Setting '${ICON_THEME_NAME}' as the current icon theme..." + CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP,,}" + + if command -v gsettings >/dev/null; then + case "$CURRENT_DESKTOP" in + cinnamon) + gsettings set org.cinnamon.desktop.interface icon-theme "${ICON_THEME_NAME}" + ;; + gnome) + gsettings set org.gnome.desktop.interface icon-theme "${ICON_THEME_NAME}" + ;; + xfce|xfce4) + xfconf-query -c xsettings -p /Net/IconThemeName -s "${ICON_THEME_NAME}" 2>/dev/null + ;; + kde|plasma) + kwriteconfig5 --file kdeglobals --group Icons --key Theme "${ICON_THEME_NAME}" + ;; + *) + echo "[!] Unsupported or unknown DE: '$CURRENT_DESKTOP'. Set icon theme manually if needed." + ;; + esac + else + echo "[!] gsettings not found. Cannot apply icon theme automatically." + fi +fi + + +echo "✅ Qortal icons installed into local theme: ${ICON_THEME_NAME}" +echo " You can now use Icon=qortal-ui (etc.) in .desktop files." +echo " Theme is now active with blue-dark base styling." +echo "â„šī¸ If icons don't update immediately, try logging out and back in." + diff --git a/rebuilt-machine.sh b/rebuilt-machine.sh index 2c3b862..824933b 100644 --- a/rebuilt-machine.sh +++ b/rebuilt-machine.sh @@ -52,9 +52,9 @@ echo "${GREEN} Cinnamon session will be loaded by default on next login! ${NC}\n echo "${YELLOW} âŦ‡ī¸ DOWNLOADING QORTAL CORE AND QORT SCRIPT ${NC}\n" cd "${HOME}" -mkdir -p backups if [ -d qortal ]; then + mkdir -p backups echo "${PURPLE} qortal DIRECTORY FOUND, BACKING UP ORIGINAL TO '~/backups' AND RE-INSTALLING ${NC}\n" mv qortal "backups/qortal-$(date +%s)" BACKUP_EXECUTED=true @@ -96,7 +96,33 @@ if [ "$BACKUP_EXECUTED" = true ]; then LATEST_BACKUP=$(ls -td "${HOME}"/backups/qortal-* | head -n 1) rsync -raPz "${LATEST_BACKUP}/qortal-backup" "${HOME}/qortal/qortal-backup" rsync -raPz "${LATEST_BACKUP}/lists" "${HOME}/qortal/lists" - echo "${GREEN} ✅ Backup minting accounts, trade states, and follow/block lists restored from ${LATEST_BACKUP} ${NC}" + if [ -d ${LATEST_BACKUP}/data ]; then + echo "...moving data folder from backup..." + mv ${LATEST_BACKUP}/data ${HOME}/qortal/data + fi + echo "${GREEN} ✅ Backup minting accounts, trade states, follow/block lists, and data (if in default location) restored from ${LATEST_BACKUP} ${NC}" + echo "${YELLOW} Checking for 'dataPath' setting in ${LATEST_BACKUP}/settings.json... ${NC}" + if command -v jq >/dev/null 2>&1; then + if jq -e 'has("dataPath")' "${LATEST_BACKUP}/settings.json" >/dev/null 2>&1; then + echo "✅ dataPath found in backup settings." + DATA_PATH=$(jq -r '.dataPath' "${LATEST_BACKUP}/settings.json") + echo "📁 dataPath: $DATA_PATH" + echo "🔁 Putting dataPath into new settings.json..." + + # Apply to the new settings safely + jq --arg path "$DATA_PATH" '.dataPath = $path' \ + "${HOME}/qortal/settings.json" > "${HOME}/qortal/settings.tmp" && \ + mv "${HOME}/qortal/settings.tmp" "${HOME}/qortal/settings.json" + else + echo "❌ dataPath not found in settings.json (data likely default, already restored). Proceeding..." + DATA_PATH="" + fi + else + echo -e "${RED}âš ī¸ jq not installed. Cannot extract dataPath safely.${NC}" + echo -e "${YELLOW}If you used a custom data path, you'll need to manually restore it into settings.json.${NC}" + DATA_PATH="" + fi + echo "\n${YELLOW} Data should have been restored, however, please verify this if it matters to you. QDN data can usually be re-obtained from Qortal, but if you are the only publisher of the data, may not be able to be, just FYI..." fi