Skip to content

Instantly share code, notes, and snippets.

@oxinabox
Created July 6, 2018 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oxinabox/3fe139924887c9339de714ce701ba2bc to your computer and use it in GitHub Desktop.
Save oxinabox/3fe139924887c9339de714ce701ba2bc to your computer and use it in GitHub Desktop.
Pure julia download function for julia 0.7 using HTTP.jl
module Download
using HTTP
using Random
using Dates
function try_get_filename_from_headers(headers)
content_disp = HTTP.getkv(headers, "Content-Disposition")
if content_disp != nothing
# extract out of Content-Disposition line
# rough version of what is needed in https://github.com/JuliaWeb/HTTP.jl/issues/179
filename_part = match(r"filename\s*=\s*(.*)", content_disp)
if filename_part != nothing
filename = filename_part[1]
quoted_filename = match(r"\"(.*)\"", ret)
if quoted_filename != nothing
# It was in quotes, so it will be double escaped
filename = unescape_string(quoted_filename[1])
end
return filename
end
end
return nothing
end
function try_get_filename_from_remote_path(target)
target == "" && return nothing
filename = basename(target)
if filename == ""
try_get_filename_from_remote_path(dirname(target))
else
filename
end
end
determine_file(::Nothing, resp) = determine_file(tempdir(), resp)
# ^ We want to the filename if possible because extension is useful for FileIO.jl
function determine_file(path, resp)
if isdir(path)
# got to to workout what file to put there
filename = something(
try_get_filename_from_headers(resp.headers),
try_get_filename_from_remote_path(resp.request.target),
randstring()
)
return joinpath(path, filename)
else
# It is a file, we are done.
return path
end
end
function download(url::AbstractString, local_file=nothing)
local file
HTTP.open("GET", url) do stream
resp = startread(stream)
file = determine_file(local_file, resp)
total_bytes = parse(Float64, HTTP.getkv(resp.headers, "Content-Length", "NaN"))
downloaded_bytes = 0
start_time = now()
prev_time = now()
function report_callback()
prev_time = now()
taken_time = (prev_time - start_time).value / 1000 # in seconds
average_speed = downloaded_bytes / taken_time
remaining_bytes = total_bytes - downloaded_bytes
remaining_time = remaining_bytes/average_speed
completion_progress = downloaded_bytes/total_bytes
@info("Downloading",
source=url,
dest = file,
progress = completion_progress,
taken_time,
remaining_time,
average_speed,
downloaded_bytes,
remaining_bytes,
total_bytes,
)
end
open(file, "w") do fh
while(!eof(stream))
downloaded_bytes += write(fh, readavailable(stream))
if now() - prev_time > Millisecond(500)
report_callback()
end
end
end
report_callback()
end
file
end
end # module
@Redeem-Grimm-Satoshi
Copy link

Thanks For Sharing. Helped Me A lot.

@oxinabox
Copy link
Author

oxinabox commented Sep 7, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment