-
Notifications
You must be signed in to change notification settings - Fork 0
Collapse file tree
Files
Search this repository
/
Copy pathgdrive-get.sh
More file actions
More file actions
Latest commit
194 lines (163 loc) · 5.43 KB
/
gdrive-get.sh
File metadata and controls
194 lines (163 loc) · 5.43 KB
You must be signed in to make or propose changes
More edit options
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/bin/bash
# Improved Google Drive file downloader script
# Supports multiple URL formats and provides better error handling
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Function to extract the file ID from various Google Drive URL formats
extract_file_id() {
local file_url="$1"
local file_id=""
# Handle different Google Drive URL formats
if [[ "$file_url" =~ drive\.google\.com/file/d/([a-zA-Z0-9_-]+) ]]; then
file_id="${BASH_REMATCH[1]}"
elif [[ "$file_url" =~ drive\.google\.com/open\?id=([a-zA-Z0-9_-]+) ]]; then
file_id="${BASH_REMATCH[1]}"
elif [[ "$file_url" =~ id=([a-zA-Z0-9_-]+) ]]; then
file_id="${BASH_REMATCH[1]}"
else
# Try the original sed approach as fallback
file_id=$(echo "$file_url" | sed -n 's/.*\/file\/d\/\([a-zA-Z0-9_-]*\).*/\1/p')
fi
echo "$file_id"
}
# Function to get filename from Google Drive
get_filename() {
local file_id="$1"
local filename
# Try to get the filename from Google Drive
filename=$(curl -s "https://drive.google.com/file/d/$file_id/view" |
grep -oP '(?<=<title>).*?(?= - Google Drive</title>)' |
head -n1 || echo "")
if [ -z "$filename" ]; then
filename="gdrive_file_$file_id"
fi
# Sanitize filename (remove/replace invalid characters)
filename=$(echo "$filename" | sed 's/[<>:"/\\|?*]/_/g')
echo "$filename"
}
# Function to download the file with improved error handling
download_google_drive_file() {
local file_url="$1"
local output_file="${2:-}"
echo "Processing Google Drive URL..."
# Extract the file ID from the URL
local file_id
file_id=$(extract_file_id "$file_url")
if [ -z "$file_id" ]; then
echo "Error: Could not extract file ID from URL: $file_url" >&2
echo "Supported formats:" >&2
echo " - https://drive.google.com/file/d/FILE_ID/view" >&2
echo " - https://drive.google.com/open?id=FILE_ID" >&2
return 1
fi
echo "Extracted file ID: $file_id"
# Determine output filename
if [ -z "$output_file" ]; then
echo "Getting filename from Google Drive..."
output_file=$(get_filename "$file_id")
echo "Detected filename: $output_file"
fi
# Create a unique temporary directory for cookies
local temp_dir
temp_dir=$(mktemp -d)
local cookies_file="$temp_dir/cookies.txt"
# Cleanup function
cleanup() {
rm -rf "$temp_dir"
}
trap cleanup EXIT
echo "Downloading file..."
# First, try direct download (works for small files)
if wget --quiet --load-cookies "$cookies_file" \
--save-cookies "$cookies_file" \
--keep-session-cookies \
--no-check-certificate \
"https://drive.google.com/uc?export=download&id=$file_id" \
-O "$output_file" 2>/dev/null; then
# Check if we got an HTML page instead of the file (indicates large file)
if file "$output_file" | grep -q "HTML"; then
echo "Large file detected, using confirmation token method..."
rm "$output_file"
# Get confirmation token for large files
local confirm_token
confirm_token=$(wget --quiet --save-cookies "$cookies_file" \
--keep-session-cookies \
--no-check-certificate \
"https://drive.google.com/uc?export=download&id=$file_id" \
-O- |
grep -oP 'confirm=\K[0-9A-Za-z_]+' | head -n1)
if [ -n "$confirm_token" ]; then
echo "Using confirmation token: $confirm_token"
wget --load-cookies "$cookies_file" \
--no-check-certificate \
"https://drive.google.com/uc?export=download&confirm=$confirm_token&id=$file_id" \
-O "$output_file"
else
echo "Error: Could not get confirmation token for large file" >&2
return 1
fi
fi
else
echo "Error: Failed to download file" >&2
return 1
fi
# Verify download
if [ -s "$output_file" ]; then
local file_size
file_size=$(du -h "$output_file" | cut -f1)
echo "Download completed successfully!"
echo "File: $output_file"
echo "Size: $file_size"
# Show file type
local file_type
file_type=$(file -b "$output_file")
echo "Type: $file_type"
else
echo "Error: Downloaded file is empty or doesn't exist" >&2
rm -f "$output_file"
return 1
fi
}
# Function to show usage
show_usage() {
echo "Usage: $0 <Google Drive URL> [output_filename]"
echo ""
echo "Examples:"
echo " $0 https://drive.google.com/file/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/view"
echo " $0 https://drive.google.com/open?id=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
echo " $0 'https://drive.google.com/file/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/view' 'my_file.pdf'"
echo ""
echo "Note: The file must be publicly accessible or shared with 'Anyone with the link'"
}
# Main script execution
main() {
# Check if required tools are available
for tool in wget curl sed grep file; do
if ! command -v "$tool" &>/dev/null; then
echo "Error: Required tool '$tool' is not installed" >&2
exit 1
fi
done
# Check arguments
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
show_usage
exit 1
fi
local file_url="$1"
local output_file="${2:-}"
# Validate URL format
if [[ ! "$file_url" =~ drive\.google\.com ]]; then
echo "Error: Not a valid Google Drive URL" >&2
show_usage
exit 1
fi
# Call the download function
if download_google_drive_file "$file_url" "$output_file"; then
echo "Script completed successfully!"
exit 0
else
echo "Script failed!" >&2
exit 1
fi
}
# Run main function with all arguments
main "$@"