diff --git a/modules/rclone-wizard b/modules/rclone-wizard index 4a1f276..ac0c2a5 100644 --- a/modules/rclone-wizard +++ b/modules/rclone-wizard @@ -1,38 +1,58 @@ #!/bin/bash -# DYNR Module: Rclone Wizard v2.3.7pre +# DYNR Module: Rclone Wizard v2.3.7 run_rclone_wizard() { BLUE='\033[38;5;45m'; PURPLE='\033[38;5;127m'; GOLD='\033[38;5;178m'; RED='\033[38;5;196m'; NC='\033[0m' LOG_DIR="/root/.dynr/logs/rclone-wizard" mkdir -p "$LOG_DIR" - # --- Dynamic Dependency Check --- + # --- Dependency Check --- MISSING=() command -v rclone &> /dev/null || MISSING+=("rclone") command -v fzf &> /dev/null || MISSING+=("fzf") - if [ ${#MISSING[@]} -gt 0 ]; then echo -e "${RED}⚠️ Required tools missing: ${MISSING[*]}${NC}" read -p "Manifest these scrolls now? (y/n): " choice [[ "$choice" == "y" ]] && sudo apt update -qq && sudo apt install -y -qq "${MISSING[@]}" || { dynr; return; } fi - # --- Deep Navigation Engine (Stderr redirected to protect variables) --- + # --- Deep Navigator Engine --- navigate_path() { local type=$1; local base=$2; local current_dir="/" while true; do + # Use stderr (>&2) for UI to keep stdout clean for path capture echo -e "${PURPLE}Navigation: ${GOLD}$type${NC} | ${BLUE}Path: ${GOLD}${base}${current_dir}${NC}" >&2 + if [[ "$type" == "LOCAL" ]]; then + # printf %f captures just the folder name, handling special chars perfectly local options=$(find "$current_dir" -maxdepth 1 -type d -not -path "$current_dir" -printf "%f\n" 2>/dev/null) else - local options=$(rclone lsd "${base}${current_dir}" 2>/dev/null | awk '{print substr($0, index($0, $5))}' | awk '{$1=$1;print}') + # substr($0, 32) captures everything after the rclone timestamp/size prefix + local options=$(rclone lsd "${base}${current_dir}" 2>/dev/null | awk '{print substr($0, 32)}') fi + local choice=$(printf "✅ SELECT THIS FOLDER\n..\nQUIT\n%s" "$options" | fzf --height 15 --reverse --header "Targeting Folder...") + case "$choice" in - "✅ SELECT THIS FOLDER") echo "${current_dir}"; return ;; - "..") current_dir=$(dirname "$current_dir"); [[ "$current_dir" != "/" ]] && current_dir="${current_dir}/"; clear >&2 ;; - "QUIT"|"") echo "CANCEL"; return ;; - *) current_dir="${current_dir%/}/${choice}/"; current_dir=$(echo "$current_dir" | sed 's|//|/|g'); clear >&2 ;; + "✅ SELECT THIS FOLDER") + echo "${current_dir}" + return + ;; + "..") + current_dir=$(dirname "$current_dir") + [[ "$current_dir" != "/" ]] && current_dir="${current_dir}/" + clear >&2 + ;; + "QUIT"|"") + echo "CANCEL" + return + ;; + *) + # tr -s ensures we never have double slashes (//) in the path + current_dir="${current_dir%/}/${choice}/" + current_dir=$(echo "$current_dir" | tr -s '/') + clear >&2 + ;; esac done } @@ -48,7 +68,7 @@ run_rclone_wizard() { case "$CHOICE" in "Safe Transfer (Copy Only)") REMOTES=$(rclone listremotes) - # Source Select + # Source selection S_BASE=$(printf "QUIT\nLOCAL_FILESYSTEM\n%s" "$REMOTES" | fzf --prompt="Select Source > ") [[ "$S_BASE" == "QUIT" || -z "$S_BASE" ]] && { run_rclone_wizard; return; } [[ "$S_BASE" != "LOCAL_FILESYSTEM" && "$S_BASE" != *":" ]] && S_BASE="${S_BASE}:" @@ -56,7 +76,7 @@ run_rclone_wizard() { [[ "$S_SUB" == "CANCEL" ]] && { run_rclone_wizard; return; } F_SRC="$([[ "$S_BASE" == "LOCAL_FILESYSTEM" ]] && echo "$S_SUB" || echo "${S_BASE}${S_SUB}")" - # Destination Select + # Destination selection D_BASE=$(printf "QUIT\nLOCAL_FILESYSTEM\n%s" "$REMOTES" | fzf --prompt="Select Destination > ") [[ "$D_BASE" == "QUIT" || -z "$D_BASE" ]] && { run_rclone_wizard; return; } [[ "$D_BASE" != "LOCAL_FILESYSTEM" && "$D_BASE" != *":" ]] && D_BASE="${D_BASE}:" @@ -66,13 +86,19 @@ run_rclone_wizard() { clear echo -e "${RED}🛡️ DYNASTY DATA SAFETY LOCK${NC}" - echo -e "${BLUE}FROM: ${GOLD}\"$F_SRC\"${NC}\n${BLUE}TO: ${GOLD}\"$F_DEST\"${NC}" - echo -e "-------------------------------------------------\n${GOLD}Mode: Additive Copy (No Deletions)${NC}" + echo -e "-------------------------------------------------" + echo -e "${BLUE}COPY FROM: ${GOLD}\"$F_SRC\"${NC}" + echo -e "${BLUE}COPY TO: ${GOLD}\"$F_DEST\"${NC}" + echo -e "-------------------------------------------------" + echo -e "${GOLD}Mode: Additive Copy (No Deletions)${NC}" read -p "Type 'SAFE' to manifest: " VAL + if [[ "$VAL" == "SAFE" ]]; then - TS=$(date +"%Y%m%d_%H%M%S"); LOG="$LOG_DIR/copy_$TS.log" - rclone copy -vP "$F_SRC" "$F_DEST" 2>&1 | tee "$LOG" - read -p "Transfer Complete. Enter to return..." + TS=$(date +"%Y%m%d_%H%M%S") + LOG_FILE="$LOG_DIR/copy_$TS.log" + # Quoting variables in rclone is vital for spaces/special chars + rclone copy -vP "$F_SRC" "$F_DEST" 2>&1 | tee "$LOG_FILE" + read -p "Transfer Complete. Enter..." else echo -e "${RED}Aborted.${NC}"; sleep 1 fi