|
11 | 11 |
|
12 | 12 | # Documentation:
|
13 | 13 | # @raycast.description Download from Amazon S3 via URL
|
14 |
| -# @raycast.argument1 { "type": "text", "placeholder": "S3 URL" } |
| 14 | +# @raycast.argument1 { "type": "text", "placeholder": "s3://bucket/key" } |
15 | 15 | # @raycast.author Chris Cook
|
16 | 16 | # @raycast.authorURL https://github.com/zirkelc
|
17 | 17 |
|
|
26 | 26 |
|
27 | 27 | # Try matching different S3 URL patterns
|
28 | 28 | # https://dev.to/aws-builders/format-and-parse-amazon-s3-url-5e10
|
29 |
| -if [[ $URL =~ ^https?://s3\.([a-z0-9-]+)\.amazonaws\.com/([^/]+)/(.*)$ ]]; then |
| 29 | +if [[ $URL =~ ^https?://s3\.([a-z0-9-]+)\.amazonaws\.com/([^/]+)(/(.*))?$ ]]; then |
30 | 30 | # Regional hostname with path-style
|
| 31 | + # Example: https://s3.us-east-1.amazonaws.com/bucket/key |
31 | 32 | BUCKET="${BASH_REMATCH[2]}"
|
32 |
| - KEY="${BASH_REMATCH[3]}" |
33 |
| -elif [[ $URL =~ ^https?://([^/]+)\.s3\.([a-z0-9-]+)\.amazonaws\.com/(.*)$ ]]; then |
| 33 | + KEY="${BASH_REMATCH[4]}" |
| 34 | +elif [[ $URL =~ ^https?://([^/]+)\.s3\.([a-z0-9-]+)\.amazonaws\.com(/(.*))?$ ]]; then |
34 | 35 | # Regional hostname with virtual-hosted-style
|
| 36 | + # Example: https://bucket.s3.us-east-1.amazonaws.com/key |
35 | 37 | BUCKET="${BASH_REMATCH[1]}"
|
36 |
| - KEY="${BASH_REMATCH[3]}" |
37 |
| -elif [[ $URL =~ ^https?://s3\.amazonaws\.com/([^/]+)/(.*)$ ]]; then |
| 38 | + KEY="${BASH_REMATCH[4]}" |
| 39 | +elif [[ $URL =~ ^https?://s3\.amazonaws\.com/([^/]+)(/(.*))?$ ]]; then |
38 | 40 | # Legacy hostname with path-style
|
| 41 | + # Example: https://s3.amazonaws.com/bucket/key |
39 | 42 | BUCKET="${BASH_REMATCH[1]}"
|
40 |
| - KEY="${BASH_REMATCH[2]}" |
41 |
| -elif [[ $URL =~ ^https?://([^/]+)\.s3\.amazonaws\.com/(.*)$ ]]; then |
| 43 | + KEY="${BASH_REMATCH[3]}" |
| 44 | +elif [[ $URL =~ ^https?://([^/]+)\.s3\.amazonaws\.com(/(.*))?$ ]]; then |
42 | 45 | # Legacy hostname with virtual-hosted-style
|
| 46 | + # Example: https://bucket.s3.amazonaws.com/key |
43 | 47 | BUCKET="${BASH_REMATCH[1]}"
|
44 |
| - KEY="${BASH_REMATCH[2]}" |
45 |
| -elif [[ $URL =~ ^s3://([^/]+)/(.*)$ ]]; then |
| 48 | + KEY="${BASH_REMATCH[3]}" |
| 49 | +elif [[ $URL =~ ^s3://([^/]+)(/(.*))?$ ]]; then |
46 | 50 | # S3 URI
|
| 51 | + # Example: s3://bucket/key |
47 | 52 | BUCKET="${BASH_REMATCH[1]}"
|
48 |
| - KEY="${BASH_REMATCH[2]}" |
| 53 | + KEY="${BASH_REMATCH[3]}" |
49 | 54 | else
|
50 | 55 | echo "Invalid URL: $URL"
|
51 | 56 | echo "URL must match recognized S3 patterns."
|
| 57 | + echo "Patterns:" |
| 58 | + echo "- Global S3 URI: s3://bucket/key" |
| 59 | + echo "- Regional Path-Style URL: https://s3.region.amazonaws.com/bucket/key" |
| 60 | + echo "- Regional Virtual-Hosted-Style URL: https://bucket.s3.region.amazonaws.com/key" |
| 61 | + echo "- Legacy Path-Style URL: https://s3.amazonaws.com/bucket/key" |
| 62 | + echo "- Legacy Virtual-Hosted-Style URL: https://bucket.s3.amazonaws.com/key" |
52 | 63 | exit 1
|
53 | 64 | fi
|
54 | 65 |
|
55 |
| -# Check for empty bucket or key |
56 |
| -if [[ -z "$BUCKET" || -z "$KEY" ]]; then |
57 |
| - echo "Error extracting bucket and key from URL: $URL" |
58 |
| - exit 1 |
59 |
| -fi |
| 66 | +# Trim leading slash from KEY if present |
| 67 | +KEY="${KEY#/}" |
60 | 68 |
|
61 |
| -# Remove trailing slash if present and set recursive download flag |
62 |
| -RECURSIVE="" |
63 |
| -if [[ "$KEY" =~ .*/$ ]]; then |
64 |
| - KEY="${KEY%/}" # Remove trailing slash for directory key |
65 |
| - RECURSIVE="--recursive" |
| 69 | +# Check for empty bucket |
| 70 | +if [[ -z "$BUCKET" ]]; then |
| 71 | + echo "Error extracting bucket from URL: $URL" |
| 72 | + exit 1 |
66 | 73 | fi
|
67 | 74 |
|
68 |
| -# Set download path |
69 | 75 | DOWNLOAD_FOLDER="$HOME/Downloads"
|
70 |
| -DOWNLOAD_PATH="$DOWNLOAD_FOLDER/$KEY" |
71 | 76 |
|
72 |
| -if [[ -n "$RECURSIVE" ]]; then |
73 |
| - echo "Downloading directory $URL to $DOWNLOAD_PATH..." |
74 |
| -else |
75 |
| - echo "Downloading file $URL to $DOWNLOAD_PATH..." |
| 77 | +# Ensure download folder exists |
| 78 | +if [ ! -d "$DOWNLOAD_FOLDER" ]; then |
| 79 | + echo "Download folder does not exist" |
| 80 | + exit 1 |
76 | 81 | fi
|
77 | 82 |
|
78 | 83 | # Print bucket and key
|
79 | 84 | echo "Bucket: $BUCKET"
|
80 |
| -echo "Key: $KEY" |
| 85 | +echo "Key: ${KEY:-<entire bucket>}" |
| 86 | +echo "Download: $DOWNLOAD_FOLDER" |
| 87 | +echo "" |
81 | 88 |
|
82 |
| -# Use recursive if necessary |
83 |
| -if aws s3 cp "s3://$BUCKET/$KEY" "$DOWNLOAD_PATH" $RECURSIVE; then |
84 |
| - echo "Downloaded successfully." |
85 |
| - open "$DOWNLOAD_FOLDER" |
| 89 | +if [ -z "$KEY" ]; then |
| 90 | + # No key provided, download entire bucket |
| 91 | + DOWNLOAD_PATH="$DOWNLOAD_FOLDER/$BUCKET" |
| 92 | + echo "Downloading entire bucket s3://$BUCKET to $DOWNLOAD_PATH..." |
| 93 | + RECURSIVE="--recursive" |
86 | 94 | else
|
87 |
| - echo "Download failed." |
88 |
| - exit 1 |
| 95 | + # Check if the key ends with a slash, indicating it's likely a directory |
| 96 | + if [[ "$KEY" == */ ]]; then |
| 97 | + DOWNLOAD_PATH="$DOWNLOAD_FOLDER/$BUCKET/$KEY" |
| 98 | + echo "Downloading directory s3://$BUCKET/$KEY to $DOWNLOAD_PATH..." |
| 99 | + RECURSIVE="--recursive" |
| 100 | + else |
| 101 | + # Check if the object exists as a file |
| 102 | + if aws s3api head-object --bucket "$BUCKET" --key "$KEY" &>/dev/null; then |
| 103 | + # It's a file |
| 104 | + FILENAME=$(basename "$KEY") |
| 105 | + DOWNLOAD_PATH="$DOWNLOAD_FOLDER/$FILENAME" |
| 106 | + echo "Downloading file s3://$BUCKET/$KEY to $DOWNLOAD_PATH..." |
| 107 | + RECURSIVE="" |
| 108 | + else |
| 109 | + # It might be a directory without a trailing slash or it doesn't exist |
| 110 | + # Try to list objects with this prefix |
| 111 | + if aws s3api list-objects-v2 --bucket "$BUCKET" --prefix "$KEY/" --max-items 1 --query 'Contents[0].Key' --output text &>/dev/null; then |
| 112 | + # It's a directory |
| 113 | + DOWNLOAD_PATH="$DOWNLOAD_FOLDER/$BUCKET/$KEY" |
| 114 | + echo "Downloading directory s3://$BUCKET/$KEY to $DOWNLOAD_PATH..." |
| 115 | + RECURSIVE="--recursive" |
| 116 | + else |
| 117 | + echo "Error: No file or directory found at s3://$BUCKET/$KEY" |
| 118 | + exit 1 |
| 119 | + fi |
| 120 | + fi |
| 121 | + fi |
| 122 | +fi |
| 123 | + |
| 124 | +# Perform the download |
| 125 | +if aws s3 cp "s3://$BUCKET/${KEY:+$KEY}" "$DOWNLOAD_PATH" $RECURSIVE; then |
| 126 | + echo "Downloaded successfully." |
| 127 | + if [[ -n "$RECURSIVE" ]]; then |
| 128 | + open "$DOWNLOAD_FOLDER/$BUCKET" |
| 129 | + else |
| 130 | + open "$DOWNLOAD_FOLDER" |
| 131 | + fi |
| 132 | +else |
| 133 | + echo "Download failed. Error code: $?" |
| 134 | + exit 1 |
89 | 135 | fi
|
0 commit comments