-
Notifications
You must be signed in to change notification settings - Fork 3
/
curlwc.sh
executable file
·145 lines (118 loc) · 4.12 KB
/
curlwc.sh
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
#! /bin/bash
# ↄ⃝ Murukesh Mohanan
# This scipt will use curl (assuming it's somehwhere in your $PATH) to download
# a file in pieces of 149 MB, or whatever size you specify (in MB).
# Unfortunately, there's not much support for arguments and switches to the
# script. The currently fixed order is (with default values):
# <target URL> [target directory = $PWD] [piece size in MB = 149]
# The intermediate pieces are stored in adirectory named ".tempdir" in the
# target directory, with the part number (starting from 0) appended to it.
# It so happens that the script will try to resume download using any ".0" part
# in that directory, since my string manipulation isn't that good. Sorry!
# You may modify it as you please, so long as you tell me what you did, so that
# I can make use of any improvements you made. :) Happy downloading!
function INT_cleanup()
{
kill `jobs -p`
exit
}
trap INT_cleanup INT
GREP_OPTIONS=
status=0
temp_dir=".tempdir"
if [[ -z $1 ]]; then
echo "Usage: "
echo "<script name> URL [Target Directory] [piece size in MB]"
echo "Please specify a URL to download, if you still wanna continue."
read download_URL
else
download_URL="$1"
fi
working_dir="${2:-$PWD}"
piece_size=$((${3:-149}*1024*1024))
cd "$working_dir"
file_size=$(( $(curl "$download_URL" -s -I -L | awk '/Content-Length:/ {print $2}') ))
num_parts=$((file_size / piece_size))
part_size[$num_parts]=$((file_size % piece_size))
mkdir -p "$temp_dir"
cd "$temp_dir"
for ((i = 0; i < (num_parts - 1); i++)); do
part_size[$i]="$piece_size"
done
shopt -s nullglob
shopt -s dotglob
files=( *.0 )
case ${#files[@]} in
0)
filename=${download_URL##*/}
filename=${download_URL%%\?*}
mv "$filename" -T "${files[0]}.0"
;;
1)
file_name=${files[0]%".0"}
;;
*)
echo "multiple initial parts found. Quitting..."
exit 1
;;
esac
while ((status == 0)); do
loop_iterations=$((loop_iterations + 1))
for ((i = 0; i < num_parts; i++))
do
part_name="$file_name.$i"
if [[ -e "$part_name" ]]; then
current_size=$(stat "$part_name" -c%s)
if (( current_size == part_size[i] )); then
echo "Part $i done!"
continue
elif (( current_size > part_size[i] )); then
echo "Something's wrong with part $i's size. Exiting..."
kill $(jobs -p)
exit
else
echo "Resuming part $i!"
fi
part_begin=$((i * piece_size + current_size))
else
part_begin=$((i * piece_size))
fi
part_end=$((i*piece_size + part_size[i] - 1))
echo "Downloading part $i: From $part_begin till $part_end."
curl "$download_URL" --location --silent --range $part_begin-$part_end >> "$part_name" &
done
wait
echo "Any cURL processes I started have ended. Let me see if the files have been downloaded completely."
status=1
for ((i = 0; i < num_parts; i++))
do
part_name="$file_name.$i"
current_size=$(stat "$part_name" -c%s)
if (( (current_size - part_size[i]) > 0 )); then
echo "In part $i, $(( part_size[i] - current_size )) bytes remain to be downloaded."
status=$((status && 0))
fi
done
if (( loop_iterations == 10 )); then
echo "Quiting the task. Something might be wrong, as this the tenth time"
echo "I've tried downloading. Do check what's going wrong. Sorry! :("
exit
fi
done
echo "All files done."
cd "$working_dir"
if [[ -f $file_name ]]; then
current_size=$(stat "$file_name" -c%s)
if (( (current_size - file_size) > 0 )); then
echo "A file of matching size and name already exists at the site."
fi
else
printf "$temp_dir/$file_name.%d\0" ${!part_size[@]} | xargs -0 cat > "$file_name"
downloaded_size=$(stat "$file_name" -c%s)
if (( downloaded_size == file_size )); then
rm $temp_dir -r -f
echo "Done!"
else
echo "Oh, damn! Something's wrong. Better check the file size."
fi
fi