Files
claudeskill/skills/minio-upload/scripts/upload_to_obsidian.sh
Misaka Company 51eae214cc Add file conflict handling to minio-upload skill
Implement comprehensive file conflict detection and resolution:
- Check for existing files before upload using mc stat (fixes mc ls bug)
- Interactive prompt when conflict detected: overwrite, skip, backup, rename
- Command-line options for non-interactive use: --force, --skip, --backup, --rename
- Auto-rename with numeric suffix when file exists
- Backup existing files with .bak extension before overwriting
- Update SKILL.md with conflict handling documentation and examples

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-28 13:45:43 +08:00

198 lines
5.8 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
#
# Upload files to MinIO obsidian bucket
# Usage: upload_to_obsidian.sh <file_path> [subpath] [options]
#
# Arguments:
# file_path - Path to the file to upload
# subpath - Optional subpath/vault within obsidian bucket (default: main)
#
# Options:
# --force - Overwrite existing files without prompting
# --skip - Skip upload if file already exists
# --backup - Backup existing file before overwriting (.bak extension)
# --rename - Automatically rename if file exists (adds numeric suffix)
#
# Examples:
# upload_to_obsidian.sh temp/file.md
# upload_to_obsidian.sh temp/file.md journal
# upload_to_obsidian.sh temp/file.md main --force
# upload_to_obsidian.sh temp/file.md work --skip
set -e
# Initialize variables
FORCE=false
SKIP=false
BACKUP=false
RENAME=false
FILE_PATH=""
SUBPATH="main"
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--force)
FORCE=true
shift
;;
--skip)
SKIP=true
shift
;;
--backup)
BACKUP=true
shift
;;
--rename)
RENAME=true
shift
;;
-*)
echo "Error: Unknown option '$1'" >&2
echo "Usage: $0 <file_path> [subpath] [--force|--skip|--backup|--rename]" >&2
exit 1
;;
*)
if [ -z "$FILE_PATH" ]; then
FILE_PATH="$1"
elif [ "$SUBPATH" = "main" ]; then
SUBPATH="$1"
else
echo "Error: Too many arguments" >&2
exit 1
fi
shift
;;
esac
done
# Check file path argument
if [ -z "$FILE_PATH" ]; then
echo "Usage: $0 <file_path> [subpath] [--force|--skip|--backup|--rename]" >&2
exit 1
fi
# Validate file exists
if [ ! -f "$FILE_PATH" ]; then
echo "Error: File '$FILE_PATH' does not exist" >&2
exit 1
fi
# Get filename
FILENAME=$(basename "$FILE_PATH")
# Construct target path
TARGET_PATH="minio/obsidian/${SUBPATH}/${FILENAME}"
# Ensure subpath ends without trailing slash for mc
TARGET_PATH=$(echo "$TARGET_PATH" | sed 's://*:/:g')
# Check if file already exists
if mc stat "$TARGET_PATH" >/dev/null 2>&1; then
# User explicitly specified --skip
if [ "$SKIP" = true ]; then
echo " File already exists, skipping upload: $TARGET_PATH"
exit 0
fi
# User explicitly specified --backup
if [ "$BACKUP" = true ]; then
BACKUP_PATH="${TARGET_PATH}.bak"
echo "📦 Backing up existing file: $TARGET_PATH -> $BACKUP_PATH"
mc cp "$TARGET_PATH" "$BACKUP_PATH"
# User explicitly specified --rename
elif [ "$RENAME" = true ]; then
COUNTER=1
BASE_NAME="${FILENAME%.*}"
EXT="${FILENAME##*.}"
if [ "$BASE_NAME" = "$EXT" ]; then
# No extension
BASE_NAME="$FILENAME"
EXT=""
else
EXT=".$EXT"
fi
while true; do
NEW_NAME="${BASE_NAME}-${COUNTER}${EXT}"
NEW_TARGET="minio/obsidian/${SUBPATH}/${NEW_NAME}"
if ! mc stat "$NEW_TARGET" >/dev/null 2>&1; then
TARGET_PATH="$NEW_TARGET"
FILENAME="$NEW_NAME"
echo "📝 Renamed to: $FILENAME"
break
fi
COUNTER=$((COUNTER + 1))
done
# User explicitly specified --force
elif [ "$FORCE" = true ]; then
echo "⚠️ Overwriting existing file: $TARGET_PATH"
else
# No explicit option - prompt user
echo ""
echo "⚠️ File '$FILENAME' already exists in vault '${SUBPATH}'"
echo "Target: $TARGET_PATH"
echo ""
echo "Choose an action:"
echo " [o] Overwrite - Replace existing file"
echo " [s] Skip - Cancel upload"
echo " [b] Backup - Backup existing file (.bak) then overwrite"
echo " [r] Rename - Upload with new name (adds numeric suffix)"
echo ""
while true; do
read -p "Your choice [o/s/b/r]: " choice
case "$choice" in
o|O|overwrite)
echo "Overwriting existing file..."
break
;;
s|S|skip)
echo "❌ Upload cancelled"
exit 0
;;
b|B|backup)
BACKUP_PATH="${TARGET_PATH}.bak"
echo "📦 Backing up existing file: $TARGET_PATH -> $BACKUP_PATH"
mc cp "$TARGET_PATH" "$BACKUP_PATH"
break
;;
r|R|rename)
COUNTER=1
BASE_NAME="${FILENAME%.*}"
EXT="${FILENAME##*.}"
if [ "$BASE_NAME" = "$EXT" ]; then
BASE_NAME="$FILENAME"
EXT=""
else
EXT=".$EXT"
fi
while true; do
NEW_NAME="${BASE_NAME}-${COUNTER}${EXT}"
NEW_TARGET="minio/obsidian/${SUBPATH}/${NEW_NAME}"
if ! mc stat "$NEW_TARGET" >/dev/null 2>&1; then
TARGET_PATH="$NEW_TARGET"
FILENAME="$NEW_NAME"
echo "📝 Renamed to: $FILENAME"
break 2
fi
COUNTER=$((COUNTER + 1))
done
;;
*)
echo "Invalid choice. Please enter o, s, b, or r"
;;
esac
done
fi
fi
# Upload file
mc cp "$FILE_PATH" "$TARGET_PATH"
echo "✅ Uploaded: $FILE_PATH -> $TARGET_PATH"