Created new Qortal Setup script for all linux versions, and create-icon-theme.sh for all linux versions, updated auto-fix and rebuilt-machine scripts to handle more adequate backup scenarios.
This commit is contained in:
parent
90b52f67e8
commit
7202ddb83f
227
Qortal-Setup-Linux.sh
Normal file
227
Qortal-Setup-Linux.sh
Normal file
@ -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" <<EOL
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Qortal Hub
|
||||||
|
Comment=Launch Qortal Hub
|
||||||
|
Exec=$HOME/qortal/Qortal-Hub$SANDBOX_FLAG
|
||||||
|
Icon=utilities-terminal
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Utility;
|
||||||
|
EOL
|
||||||
|
|
||||||
|
echo -e "\n ${GREEN}✅ Desktop launcher created at ~/.local/share/applications/qortal-hub.desktop${NC}"
|
||||||
|
else
|
||||||
|
echo -e "\n ${YELLOW}ℹ️ No desktop environment detected or missing xdg tools. Skipping applications menu launcher setup.${NC}"
|
||||||
|
echo -e "\n ${CYAN} Checking for Desktop folder..."
|
||||||
|
if [ -d "${HOME}/Desktop" ]; then
|
||||||
|
echo -e "Desktop folder found, creating desktop launcher..."
|
||||||
|
cat > "${HOME}/Desktop/qortal-hub.desktop" <<EOL
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Qortal Hub
|
||||||
|
Comment=Launch Qortal Hub
|
||||||
|
Exec=$HOME/qortal/Qortal-Hub$SANDBOX_FLAG
|
||||||
|
Icon=utilities-terminal
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Utility;
|
||||||
|
EOL
|
||||||
|
else
|
||||||
|
echo -e "${RED} Display found, but no Desktop folder found? Skipping Launcher creation..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BACKUP_EXECUTED" = true ]; then
|
||||||
|
echo -e "\n ${GREEN} BACKUP DETECTED! Restoring backed-up qortal folder content... ${NC}"
|
||||||
|
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"
|
||||||
|
if [ -d "${LATEST_BACKUP}/data" ]; then
|
||||||
|
echo -e "\n...moving data folder from backup..."
|
||||||
|
mv "${LATEST_BACKUP}/data" "${HOME}/qortal/data"
|
||||||
|
fi
|
||||||
|
echo -e "\n ${GREEN} ✅ Backup minting accounts, trade states, follow/block lists, and data (if in default location) restored from ${LATEST_BACKUP} ${NC}"
|
||||||
|
echo -e "\n ${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 -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
|
||||||
|
|
@ -143,7 +143,7 @@ check_qortal() {
|
|||||||
|
|
||||||
echo "${CYAN} NODE DOES NOT SEEM TO BE RUNNING? CHECKING IF NODE IS BOOTSTRAPPING...${NC}\n"
|
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"
|
echo "${RED}Node seems to be bootstrapping, updating script and exiting...${NC}\n"
|
||||||
update_script
|
update_script
|
||||||
fi
|
fi
|
||||||
@ -201,7 +201,7 @@ check_hash_update_qortal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_for_GUI() {
|
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"
|
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
|
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"
|
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"
|
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
|
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"
|
# 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
|
curl -L -O https://raw.githubusercontent.com/crowetic/QORTector-scripts/main/auto-fix-GUI-cron
|
||||||
crontab auto-fix-GUI-cron
|
crontab auto-fix-GUI-cron
|
||||||
rm -f 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
|
# curl -L -O https://raw.githubusercontent.com/crowetic/QORTector-scripts/refs/heads/main/auto-fix-cron
|
||||||
# crontab auto-fix-cron
|
# crontab auto-fix-cron
|
||||||
# rm -f auto-fix-cron
|
# rm -f auto-fix-cron
|
||||||
check_height
|
check_height
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "${BLUE}No autostart entries found. Setting up full headless cron...${NC}\n"
|
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")
|
checked_height=$(curl -s "http://localhost:12391/blocks/height")
|
||||||
sleep 2
|
sleep 2
|
||||||
if [ "$checked_height" = "$previous_local_height" ]; then
|
if [ "$checked_height" = "$previous_local_height" ]; then
|
||||||
echo "${RED}Block height still unchanged... forcing bootstrap...${NC}\n"
|
echo "${RED}Block height still unchanged... final sanity check in 10 seconds..${NC}\n"
|
||||||
force_bootstrap
|
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
|
fi
|
||||||
fi
|
fi
|
||||||
@ -288,7 +294,7 @@ no_local_height() {
|
|||||||
echo "${WHITE}Checking if node is bootstrapping or not...${NC}\n"
|
echo "${WHITE}Checking if node is bootstrapping or not...${NC}\n"
|
||||||
|
|
||||||
if [ -f "${HOME}/qortal/qortal.log" ]; then
|
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"
|
echo "${RED}Node seems to be bootstrapping, updating script and exiting...${NC}\n"
|
||||||
update_script
|
update_script
|
||||||
fi
|
fi
|
||||||
@ -369,7 +375,7 @@ force_bootstrap() {
|
|||||||
cd "${HOME}/qortal" || exit 1
|
cd "${HOME}/qortal" || exit 1
|
||||||
killall -9 java
|
killall -9 java
|
||||||
sleep 3
|
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
|
sleep 5
|
||||||
./start.sh
|
./start.sh
|
||||||
cd || exit 1
|
cd || exit 1
|
||||||
@ -389,9 +395,9 @@ potentially_update_settings() {
|
|||||||
mkdir -p "${BACKUP_FOLDER}"
|
mkdir -p "${BACKUP_FOLDER}"
|
||||||
|
|
||||||
# Step 1: Backup settings.json
|
# 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
|
is_valid_json=false
|
||||||
if command -v jq &>/dev/null; then
|
if command -v jq &>/dev/null; then
|
||||||
echo "${YELLOW}Using jq to validate JSON...${NC}"
|
echo "${YELLOW}Using jq to validate JSON...${NC}"
|
||||||
@ -402,48 +408,38 @@ potentially_update_settings() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "${YELLOW}jq not found, doing basic manual check...${NC}"
|
echo "${RED}jq not found. Skipping JSON validation.${NC}"
|
||||||
if grep -q '^{.*}$' "${SETTINGS_FILE}"; then
|
|
||||||
is_valid_json=true
|
|
||||||
echo "${GREEN}Basic structure appears valid (manual fallback).${NC}"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### Step 3: If invalid, try to fix ###
|
# Step 3: If invalid, try to fix
|
||||||
if [ "${is_valid_json}" != true ]; then
|
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}"
|
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
|
if command -v jq &>/dev/null && jq empty "${SETTINGS_FILE}" 2>/dev/null; then
|
||||||
echo "${GREEN}Backup restored successfully and is valid.${NC}"
|
echo "${GREEN}Backup restored successfully and is valid.${NC}"
|
||||||
else
|
else
|
||||||
echo "${RED}Backup also invalid. Downloading default settings.json...${NC}"
|
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
|
if command -v jq &>/dev/null && jq empty "${SETTINGS_FILE}" 2>/dev/null; then
|
||||||
echo "${GREEN}Default settings.json downloaded and is valid.${NC}"
|
echo "${GREEN}Default settings.json downloaded and is valid.${NC}"
|
||||||
else
|
else
|
||||||
echo "${RED}Failed to recover a valid settings.json. Manual intervention required.${NC}"
|
echo "${RED}Failed to recover a valid settings.json. Manual intervention required.${NC}"
|
||||||
cd || exit 1
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
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}"
|
echo "${YELLOW}Rotating old backups (keeping only 2)...${NC}"
|
||||||
cd "${BACKUP_FOLDER}" || exit 1
|
cd "${BACKUP_FOLDER}" || exit 1
|
||||||
|
|
||||||
backup_count=$(ls -1 backup-settings-*.json 2>/dev/null | wc -l)
|
backup_count=$(ls -1 backup-settings-*.json 2>/dev/null | wc -l)
|
||||||
|
to_delete=$((backup_count - 2))
|
||||||
if [ "$backup_count" -gt 2 ]; then
|
if [ "$to_delete" -gt 0 ]; then
|
||||||
# List oldest first, delete all but the 2 most recent
|
for old_backup in $(ls -1tr backup-settings-*.json | head -n "$to_delete"); do
|
||||||
for old_backup in $(ls -1tr backup-settings-*.json | head -n -$((backup_count - 2))); do
|
|
||||||
echo "Deleting old backup: $old_backup"
|
echo "Deleting old backup: $old_backup"
|
||||||
rm -f "$old_backup"
|
rm -f "$old_backup"
|
||||||
done
|
done
|
||||||
@ -451,10 +447,7 @@ potentially_update_settings() {
|
|||||||
echo "${BLUE}No old backups to delete.${NC}"
|
echo "${BLUE}No old backups to delete.${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd - >/dev/null || exit 1
|
|
||||||
|
|
||||||
echo "${GREEN}Settings file is now valid. Proceeding...${NC}"
|
echo "${GREEN}Settings file is now valid. Proceeding...${NC}"
|
||||||
cd || exit 1
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +469,7 @@ update_script() {
|
|||||||
sleep 2
|
sleep 2
|
||||||
potentially_update_settings
|
potentially_update_settings
|
||||||
rm -rf "${HOME}/qortal.jar" "${HOME}/run.pid" "${HOME}/run.log" "${HOME}/remote.md5" "${HOME}/qortal/local.md5"
|
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"
|
echo "${YELLOW}Auto-fix script run complete.${NC}\n"
|
||||||
sleep 5
|
sleep 5
|
||||||
exit
|
exit
|
||||||
|
136
create-icon-theme.sh
Normal file
136
create-icon-theme.sh
Normal file
@ -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."
|
||||||
|
|
@ -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"
|
echo "${YELLOW} ⬇️ DOWNLOADING QORTAL CORE AND QORT SCRIPT ${NC}\n"
|
||||||
|
|
||||||
cd "${HOME}"
|
cd "${HOME}"
|
||||||
mkdir -p backups
|
|
||||||
|
|
||||||
if [ -d qortal ]; then
|
if [ -d qortal ]; then
|
||||||
|
mkdir -p backups
|
||||||
echo "${PURPLE} qortal DIRECTORY FOUND, BACKING UP ORIGINAL TO '~/backups' AND RE-INSTALLING ${NC}\n"
|
echo "${PURPLE} qortal DIRECTORY FOUND, BACKING UP ORIGINAL TO '~/backups' AND RE-INSTALLING ${NC}\n"
|
||||||
mv qortal "backups/qortal-$(date +%s)"
|
mv qortal "backups/qortal-$(date +%s)"
|
||||||
BACKUP_EXECUTED=true
|
BACKUP_EXECUTED=true
|
||||||
@ -96,7 +96,33 @@ if [ "$BACKUP_EXECUTED" = true ]; then
|
|||||||
LATEST_BACKUP=$(ls -td "${HOME}"/backups/qortal-* | head -n 1)
|
LATEST_BACKUP=$(ls -td "${HOME}"/backups/qortal-* | head -n 1)
|
||||||
rsync -raPz "${LATEST_BACKUP}/qortal-backup" "${HOME}/qortal/qortal-backup"
|
rsync -raPz "${LATEST_BACKUP}/qortal-backup" "${HOME}/qortal/qortal-backup"
|
||||||
rsync -raPz "${LATEST_BACKUP}/lists" "${HOME}/qortal/lists"
|
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
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user