big-bear-interactive-rsync-with-file-sizes (#25)

*  feat: Add interactive rsync script

This commit introduces a new interactive rsync script that allows users to
visually select specific files and directories for synchronization. The
script provides the following features:

- Interactive file/directory selection
- Color-coded interface for better visibility
- Multiple file selection support
- Progress indication during transfer
- Automatic destination directory creation
- Input validation and error handling

The script is designed to simplify the rsync process by eliminating the need
for complex command-line arguments, making it more user-friendly and
accessible for a wider audience.

*  feat: Add file size display and transfer confirmation

This commit adds the following improvements to the interactive-rsync script:

- Displays the file/directory size next to each item in the selection menu.
- Adds a confirmation prompt before starting the transfer to ensure the user is ready.
- Allows the user to specify file patterns to exclude from the transfer.
- Displays a summary of the successful and failed transfers at the end of the process.

These changes enhance the user experience by providing more information and control over the file transfer process.
This commit is contained in:
Christopher
2024-12-06 10:15:36 -06:00
committed by GitHub
parent e8d37541ef
commit 7ffdd617f4
2 changed files with 279 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
# Big Bear Interactive Rsync
## Why?
This script provides an interactive way to select specific files and directories for rsync operations. Instead of syncing entire directories or writing complex rsync commands, you can visually select which items you want to sync.
## Features
- Interactive file/directory selection with size information
- Color-coded interface for better visibility
- Multiple file selection support
- File/directory size display
- Pattern-based file exclusion (e.g., _.tmp, _.log)
- Transfer confirmation and progress tracking
- Detailed transfer summary with success/failure reporting
- Automatic destination directory creation
- Input validation and error handling
## How to use?
1. Make the script executable:
```bash
chmod +x run.sh
```
2. Run the script (optionally with a source directory):
```bash
./run.sh # Uses current directory as source
./run.sh /path/to/directory # Uses specified directory as source
```
3. Follow the interactive prompts:
- Enter file patterns to exclude (optional)
- Select items by entering their numbers (space-separated)
- Type 'a' to select all items
- Type 'q' to quit
- Enter the destination path
- Confirm the transfer
## Example
```bash
./run.sh ~/Documents
```
Example session:
```
1) document.pdf (1.2M)
2) images (2.3G)
3) notes.txt (45K)
Enter file patterns to exclude: *.tmp *.log
Enter numbers to select: 1 3
Selected items: 2
- document.pdf (1.2M)
- notes.txt (45K)
Enter destination: ~/backup
Start transfer? (y/n): y
Transfer Summary:
Successfully transferred: 2/2
```
## Requirements
- Bash shell
- rsync installed on your system
## One-line Installation
```bash
bash -c "$(wget -qLO - https://raw.githubusercontent.com/bigbeartechworld/big-bear-scripts/master/interactive-rsync/run.sh)"
```

202
interactive-rsync/run.sh Normal file
View File

@@ -0,0 +1,202 @@
#!/bin/bash
# Function to print header
print_header() {
echo "================================================"
echo "$1"
echo "================================================"
echo
}
# Colors for better visibility
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to display menu
show_menu() {
clear
print_header "Big Bear Interactive Rsync V0.0.1"
echo "Here are some links:"
echo "https://community.bigbeartechworld.com"
echo "https://github.com/BigBearTechWorld"
echo ""
echo "If you would like to support me, please consider buying me a tea:"
echo "https://ko-fi.com/bigbeartechworld"
echo ""
}
# Function to get file size in human readable format
get_size() {
local size
size=$(du -sh "$1" 2>/dev/null | cut -f1)
echo "${size:-0B}"
}
# Function to confirm action
confirm_action() {
local message="$1"
local response
echo -e "\n${YELLOW}$message${NC} (y/n): "
read -r response
case "$response" in
[yY]|[yY][eE][sS]) return 0 ;;
*) return 1 ;;
esac
}
# Set source directory to current directory if not provided
SOURCE_DIR="${1:-.}"
# Check if source directory exists
if [ ! -d "$SOURCE_DIR" ]; then
show_menu
echo -e "${RED}Error: Source directory '$SOURCE_DIR' does not exist${NC}"
exit 1
fi
# Function to display numbered list of files/directories
display_items() {
local dir="$1"
local i=1
show_menu
echo -e "\n${GREEN}Available items in $dir:${NC}"
echo "--------------------------------"
# Store items in an array
items=()
sizes=()
while IFS= read -r item; do
items+=("$item")
sizes+=("$(get_size "$dir/$item")")
echo -e "${YELLOW}$i)${NC} $item (${sizes[$((i-1))]})"
((i++))
done < <(ls -A "$dir")
}
# Function to get selected items
get_selections() {
local selections=()
local selection_sizes=()
local done=false
local exclude_pattern=""
# Ask for exclude pattern
echo -e "\n${GREEN}Enter file patterns to exclude (e.g., '*.tmp *.log', or press Enter for none):${NC}"
read -r exclude_pattern
while [ "$done" = false ]; do
echo -e "\nEnter the numbers of items you want to sync (space-separated)"
echo "Or press Enter when done, 'a' for all, 'q' to quit"
read -r input
# Convert to lowercase
input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
case "$input" in
"q")
show_menu
echo "Quitting..."
exit 0
;;
"a")
echo "Selected all items"
selections=("${items[@]}")
selection_sizes=("${sizes[@]}")
done=true
;;
"")
if [ ${#selections[@]} -gt 0 ]; then
done=true
else
echo -e "${RED}No items selected. Please select at least one item.${NC}"
fi
;;
*)
selections=()
selection_sizes=()
valid_selections=true
for num in $input; do
if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#items[@]} ]; then
selections+=("${items[$((num-1))]}")
selection_sizes+=("${sizes[$((num-1))]}")
else
echo -e "${RED}Invalid selection: $num${NC}"
valid_selections=false
break
fi
done
if [ "$valid_selections" = true ]; then
done=true
fi
;;
esac
done
show_menu
echo -e "\n${GREEN}Selected items:${NC}"
local total_count=${#selections[@]}
echo -e "${YELLOW}Total files/directories: $total_count${NC}"
for i in "${!selections[@]}"; do
echo "${selections[$i]} (${selection_sizes[$i]})"
done
# Ask for destination
echo -e "\n${GREEN}Enter destination path:${NC}"
read -r destination
# Validate destination
if [ -z "$destination" ]; then
echo -e "${RED}Error: Destination cannot be empty${NC}"
exit 1
fi
# Create destination if it doesn't exist
mkdir -p "$destination"
# Confirm transfer
if ! confirm_action "Start transfer of $total_count items to $destination?"; then
echo -e "${YELLOW}Transfer cancelled${NC}"
exit 0
fi
# Prepare rsync exclude options
local exclude_opts=""
if [ -n "$exclude_pattern" ]; then
for pattern in $exclude_pattern; do
exclude_opts="$exclude_opts --exclude='$pattern'"
done
fi
# Perform rsync for each selected item
local success_count=0
local failed_items=()
for item in "${selections[@]}"; do
echo -e "\n${GREEN}Syncing: $item${NC}"
if eval rsync -av --info=progress2 $exclude_opts \""$SOURCE_DIR/$item"\" \""$destination/"\"; then
((success_count++))
else
failed_items+=("$item")
fi
done
# Show summary
echo -e "\n${GREEN}Transfer Summary:${NC}"
echo -e "Successfully transferred: $success_count/$total_count"
if [ ${#failed_items[@]} -gt 0 ]; then
echo -e "\n${RED}Failed transfers:${NC}"
printf '%s\n' "${failed_items[@]}"
fi
}
# Main execution
display_items "$SOURCE_DIR"
get_selections