#!/usr/bin/env bash # gniza4linux/lib/ui_remotes.sh — Remote management TUI [[ -n "${_GNIZA4LINUX_UI_REMOTES_LOADED:-}" ]] && return 0 _GNIZA4LINUX_UI_REMOTES_LOADED=1 ui_remotes_menu() { while true; do local -a items=() local remotes remotes=$(list_remotes) if [[ -n "$remotes" ]]; then while IFS= read -r r; do items+=("$r" "Remote: $r") done <<< "$remotes" fi items+=("ADD" "Add new remote") items+=("BACK" "Return to main menu") local choice choice=$(ui_menu "Remotes" "${items[@]}") || return 0 case "$choice" in ADD) ui_remote_add ;; BACK) return 0 ;; *) local action action=$(ui_menu "Remote: $choice" \ "EDIT" "Edit remote" \ "DELETE" "Delete remote" \ "TEST" "Test connection" \ "BACK" "Back") || continue case "$action" in EDIT) ui_remote_edit "$choice" ;; DELETE) ui_remote_delete "$choice" ;; TEST) ui_remote_test "$choice" ;; BACK) continue ;; esac ;; esac done } ui_remote_add() { local name name=$(ui_inputbox "Add Remote" "Enter remote name (letters, digits, _ -):" "") || return 0 [[ -z "$name" ]] && return 0 if ! validate_target_name "$name" 2>/dev/null; then ui_msgbox "Invalid remote name. Must start with a letter and contain only letters, digits, underscore, or hyphen (max 32 chars)." return 0 fi if [[ -f "$CONFIG_DIR/remotes.d/${name}.conf" ]]; then ui_msgbox "Remote '$name' already exists." return 0 fi local rtype rtype=$(ui_radiolist "Remote Type" \ "ssh" "SSH remote" "ON" \ "local" "Local directory" "OFF" \ "s3" "Amazon S3 / compatible" "OFF" \ "gdrive" "Google Drive" "OFF") || return 0 local conf="$CONFIG_DIR/remotes.d/${name}.conf" case "$rtype" in ssh) _ui_remote_add_ssh "$name" "$conf" ;; local) _ui_remote_add_local "$name" "$conf" ;; s3) _ui_remote_add_s3 "$name" "$conf" ;; gdrive) _ui_remote_add_gdrive "$name" "$conf" ;; esac } _ui_remote_add_ssh() { local name="$1" conf="$2" local host; host=$(ui_inputbox "SSH Remote" "Hostname or IP:" "") || return 0 [[ -z "$host" ]] && { ui_msgbox "Host is required."; return 0; } local port; port=$(ui_inputbox "SSH Remote" "Port:" "$DEFAULT_REMOTE_PORT") || port="$DEFAULT_REMOTE_PORT" local user; user=$(ui_inputbox "SSH Remote" "Username:" "$DEFAULT_REMOTE_USER") || user="$DEFAULT_REMOTE_USER" local base; base=$(ui_inputbox "SSH Remote" "Base path on remote:" "$DEFAULT_REMOTE_BASE") || base="$DEFAULT_REMOTE_BASE" local auth_method auth_method=$(ui_radiolist "Authentication" \ "key" "SSH key" "ON" \ "password" "Password" "OFF") || auth_method="key" local key="" password="" if [[ "$auth_method" == "key" ]]; then key=$(ui_inputbox "SSH Remote" "Path to SSH key:" "$HOME/.ssh/id_rsa") || key="" else password=$(ui_password "Enter SSH password:") || password="" fi local bwlimit; bwlimit=$(ui_inputbox "SSH Remote" "Bandwidth limit (KB/s, 0=unlimited):" "$DEFAULT_BWLIMIT") || bwlimit="$DEFAULT_BWLIMIT" local retention; retention=$(ui_inputbox "SSH Remote" "Retention count:" "$DEFAULT_RETENTION_COUNT") || retention="$DEFAULT_RETENTION_COUNT" # Test connection before saving if ui_yesno "Test connection to ${user}@${host}:${port} before saving?"; then local test_result local -a ssh_cmd=(ssh -o BatchMode=yes -o ConnectTimeout=10 -p "$port") if [[ "$auth_method" == "key" && -n "$key" ]]; then ssh_cmd+=(-i "$key") fi ssh_cmd+=("${user}@${host}" "echo OK") if test_result=$("${ssh_cmd[@]}" 2>&1); then ui_msgbox "Connection successful!" else ui_msgbox "Connection failed:\n\n$test_result" if ! ui_yesno "Save remote anyway?"; then return 0 fi fi fi cat > "$conf" < "$conf" </dev/null && ui_yesno "Test S3 connection before saving?"; then # Set globals temporarily for test_rclone_connection REMOTE_TYPE="s3" S3_BUCKET="$bucket" S3_REGION="$region" \ S3_ENDPOINT="$endpoint" S3_ACCESS_KEY_ID="$access_key" \ S3_SECRET_ACCESS_KEY="$secret_key" REMOTE_BASE="$base" local test_result if test_result=$(test_rclone_connection 2>&1); then ui_msgbox "S3 connection successful!" else ui_msgbox "S3 connection failed:\n\n$test_result" if ! ui_yesno "Save remote anyway?"; then return 0 fi fi fi cat > "$conf" </dev/null && ui_yesno "Test Google Drive connection before saving?"; then REMOTE_TYPE="gdrive" GDRIVE_SERVICE_ACCOUNT_FILE="$sa_file" \ GDRIVE_ROOT_FOLDER_ID="$folder_id" REMOTE_BASE="$base" local test_result if test_result=$(test_rclone_connection 2>&1); then ui_msgbox "Google Drive connection successful!" else ui_msgbox "Google Drive connection failed:\n\n$test_result" if ! ui_yesno "Save remote anyway?"; then return 0 fi fi fi cat > "$conf" < "$conf" < "$conf" < "$conf" < "$conf" <&1) \ && ui_msgbox "Connection to '$name' successful.\n\nResponse: $result" \ || ui_msgbox "Connection to '$name' failed.\n\nError: $result" ;; local) if [[ -d "$REMOTE_BASE" ]]; then ui_msgbox "Local directory '$REMOTE_BASE' exists and is accessible." else ui_msgbox "Local directory '$REMOTE_BASE' does NOT exist." fi ;; s3|gdrive) if command -v rclone &>/dev/null; then # Use the proper rclone transport layer (temp config file, not CLI args) load_remote "$name" || { ui_msgbox "Failed to load remote."; break; } if result=$(test_rclone_connection 2>&1); then ui_msgbox "${REMOTE_TYPE} connection to '$name' successful." else ui_msgbox "${REMOTE_TYPE} connection to '$name' failed.\n\nError: $result" fi else ui_msgbox "rclone is not installed. Cannot test ${REMOTE_TYPE} connection." fi ;; *) ui_msgbox "Unknown remote type: ${REMOTE_TYPE}" ;; esac }