Skip to content

Instantly share code, notes, and snippets.

@avdi
Created December 16, 2013 17:20
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save avdi/7990684 to your computer and use it in GitHub Desktop.
Save avdi/7990684 to your computer and use it in GitHub Desktop.
Streaming a URL to a file in Elixir
def download_video(Episode[filename: filename] = episode) do
Stream.resource(fn -> begin_download(episode) end,
&continue_download/1,
&finish_download/1)
|> File.stream_to!(filename)
|> Stream.run
end
def begin_download(Episode[video_url: video_url,
account: Account[login: login,
password: password]]) do
IO.puts "Downloading #{video_url}"
{:ok, _status, headers, client} =
:hackney.get(video_url, [], "", basic_auth: {login, password})
total_size = headers["Content-Length"] |> binary_to_integer
{client, total_size, 0}
end
def continue_download({client, total_size, size}) do
case :hackney.stream_body(client) do
{:ok, data, client} ->
new_size = size + size(data)
IO.puts "Downloaded #{new_size} of #{total_size}"
{data, {client, total_size, new_size}}
{:done, client} ->
IO.puts "No more data"
nil
{:error, reason} ->
raise reason
end
end
def finish_download({client, total_size, size}) do
IO.puts "Finished downloading #{size} bytes"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment