Last active
December 20, 2025 09:23
-
-
Save Saik0s/c47e1eaf3bb077cee558b1e8e196665e to your computer and use it in GitHub Desktop.
Interactive ComfyUI model sync from Google Drive with rclone
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # Interactive Model Sync from Google Drive | |
| # Usage: ./sync-models.sh [destination_path] | |
| # | |
| set -e | |
| DEST_PATH="${1:-./models}" | |
| REMOTE_NAME="drive" | |
| REMOTE_PATH="models" | |
| # Colors | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| CYAN='\033[0;36m' | |
| NC='\033[0m' | |
| print_header() { | |
| echo -e "${CYAN}" | |
| echo "╔═══════════════════════════════════════════════════════════════╗" | |
| echo "║ ComfyUI Model Sync from Google Drive ║" | |
| echo "╚═══════════════════════════════════════════════════════════════╝" | |
| echo -e "${NC}" | |
| } | |
| print_step() { | |
| echo -e "${BLUE}▶ $1${NC}" | |
| } | |
| print_success() { | |
| echo -e "${GREEN}✓ $1${NC}" | |
| } | |
| print_warning() { | |
| echo -e "${YELLOW}⚠ $1${NC}" | |
| } | |
| print_error() { | |
| echo -e "${RED}✗ $1${NC}" | |
| } | |
| # Check and install rclone | |
| install_rclone() { | |
| if command -v rclone &> /dev/null; then | |
| print_success "rclone is already installed ($(rclone version | head -1))" | |
| return 0 | |
| fi | |
| print_step "Installing rclone..." | |
| if [[ "$OSTYPE" == "darwin"* ]]; then | |
| if command -v brew &> /dev/null; then | |
| brew install rclone | |
| else | |
| curl https://rclone.org/install.sh | sudo bash | |
| fi | |
| elif [[ "$OSTYPE" == "linux-gnu"* ]]; then | |
| curl https://rclone.org/install.sh | sudo bash | |
| else | |
| print_error "Unsupported OS. Install rclone manually: https://rclone.org/install/" | |
| exit 1 | |
| fi | |
| print_success "rclone installed" | |
| } | |
| # Check if running headless | |
| is_headless() { | |
| if [[ -z "$DISPLAY" ]] || [[ -n "$SSH_CLIENT" && -z "$DISPLAY" ]]; then | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| # Configure rclone for Google Drive | |
| configure_rclone() { | |
| local config_file | |
| config_file=$(rclone config file 2>/dev/null | grep -v "^Configuration" | head -1) | |
| print_step "Config file: ${config_file:-default location}" | |
| local existing_remotes | |
| existing_remotes=$(rclone listremotes 2>/dev/null) | |
| if [[ -z "$existing_remotes" ]]; then | |
| echo " No remotes configured" | |
| else | |
| echo " Found remotes: $(echo $existing_remotes | tr '\n' ' ')" | |
| fi | |
| # Check if drive remote exists and works | |
| if echo "$existing_remotes" | grep -q "^${REMOTE_NAME}:$"; then | |
| print_step "Testing '${REMOTE_NAME}:' connection..." | |
| if rclone lsd "${REMOTE_NAME}:" &> /dev/null; then | |
| print_success "Google Drive connected" | |
| return 0 | |
| else | |
| print_warning "Remote exists but connection failed" | |
| read -p "Delete and reconfigure? [y/N]: " confirm | |
| if [[ ! "$confirm" =~ ^[Yy] ]]; then | |
| exit 1 | |
| fi | |
| rclone config delete "${REMOTE_NAME}" 2>/dev/null || true | |
| fi | |
| fi | |
| print_step "Configuring Google Drive access..." | |
| echo "" | |
| if is_headless; then | |
| echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" | |
| echo -e "${CYAN} HEADLESS AUTHENTICATION${NC}" | |
| echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" | |
| echo "" | |
| echo -e "${GREEN}Step 1:${NC} On your LOCAL machine (with browser), run:" | |
| echo -e " ${CYAN}rclone authorize \"drive\"${NC}" | |
| echo "" | |
| echo -e "${GREEN}Step 2:${NC} Complete Google sign-in in browser" | |
| echo "" | |
| echo -e "${GREEN}Step 3:${NC} Copy the token rclone prints" | |
| echo "" | |
| echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" | |
| echo "" | |
| echo -e "${YELLOW}Now running 'rclone config' - answer 'n' to browser question${NC}" | |
| echo -e "${YELLOW}and paste your token at the config_token> prompt${NC}" | |
| echo "" | |
| read -p "Press Enter when ready..." | |
| rclone config | |
| else | |
| echo -e "${YELLOW}Opening browser for authentication...${NC}" | |
| rclone config create "${REMOTE_NAME}" drive | |
| fi | |
| # Verify | |
| print_step "Verifying connection..." | |
| if rclone lsd "${REMOTE_NAME}:" &> /dev/null; then | |
| print_success "Google Drive configured" | |
| else | |
| print_error "Configuration failed" | |
| exit 1 | |
| fi | |
| } | |
| # Main | |
| main() { | |
| print_header | |
| install_rclone | |
| configure_rclone | |
| print_step "Fetching models from Google Drive..." | |
| # Get list into array - simple and reliable | |
| local models_raw | |
| models_raw=$(rclone lsf "${REMOTE_NAME}:${REMOTE_PATH}" -R 2>/dev/null | grep -E '\.(safetensors|pth|pt|gguf|onnx|bin)$' | sort) | |
| if [[ -z "$models_raw" ]]; then | |
| print_error "No models found in ${REMOTE_NAME}:${REMOTE_PATH}" | |
| exit 1 | |
| fi | |
| # Convert to array | |
| local -a MODELS | |
| while IFS= read -r line; do | |
| [[ -n "$line" ]] && MODELS+=("$line") | |
| done <<< "$models_raw" | |
| print_success "Found ${#MODELS[@]} models" | |
| echo "" | |
| # Print numbered list | |
| echo -e "${CYAN}Available models:${NC}" | |
| echo "─────────────────────────────────────────────────────────────────" | |
| local i=1 | |
| for model in "${MODELS[@]}"; do | |
| echo -e " ${YELLOW}${i}${NC}) ${model}" | |
| i=$((i + 1)) | |
| done | |
| echo "" | |
| echo "Enter numbers separated by spaces (e.g., 1 3 5)" | |
| echo "Or 'all' to download everything, 'q' to quit" | |
| echo "" | |
| read -p "> " INPUT | |
| [[ "$INPUT" = "q" ]] && exit 0 | |
| # Build download list | |
| local -a TO_DOWNLOAD | |
| if [[ "$INPUT" = "all" ]]; then | |
| TO_DOWNLOAD=("${MODELS[@]}") | |
| else | |
| for num in $INPUT; do | |
| local idx=$((num - 1)) | |
| if [[ $idx -ge 0 ]] && [[ $idx -lt ${#MODELS[@]} ]]; then | |
| TO_DOWNLOAD+=("${MODELS[$idx]}") | |
| fi | |
| done | |
| fi | |
| if [[ ${#TO_DOWNLOAD[@]} -eq 0 ]]; then | |
| print_warning "Nothing selected" | |
| exit 0 | |
| fi | |
| echo "" | |
| print_step "Downloading ${#TO_DOWNLOAD[@]} model(s) to ${DEST_PATH}..." | |
| mkdir -p "$DEST_PATH" | |
| local current=0 | |
| for model in "${TO_DOWNLOAD[@]}"; do | |
| current=$((current + 1)) | |
| echo "" | |
| echo -e "${BLUE}[$current/${#TO_DOWNLOAD[@]}]${NC} $model" | |
| local dir | |
| dir=$(dirname "$model") | |
| mkdir -p "${DEST_PATH}/${dir}" | |
| rclone copy "${REMOTE_NAME}:${REMOTE_PATH}/${model}" "${DEST_PATH}/${dir}" -P | |
| done | |
| echo "" | |
| print_success "All downloads complete!" | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment