Current section

Files

Jump to
nldoc_s3 lib nldoc s3.ex
Raw

lib/nldoc/s3.ex

defmodule NLdoc.S3 do
@moduledoc """
Helper functions for S3.
"""
@type response() :: {:ok, term()} | {:error, term()}
@doc """
Upload a specific file as a stream.
"""
@spec stream_upload(
path :: String.t(),
bucket :: String.t(),
key :: String.t(),
opts :: ExAws.S3.upload_opts()
) :: {:ok, term()} | {:error, term()}
def stream_upload(path, bucket, key, opts) do
with stream = %File.Stream{} <- ExAws.S3.Upload.stream_file(path),
operation = %ExAws.S3.Upload{} <- ExAws.S3.upload(stream, bucket, key, opts) do
ExAws.request(operation)
end
end
@doc """
Download a specific file as a stream
"""
@spec stream_download!(bucket :: String.t(), key :: String.t()) :: Enumerable.t()
def stream_download!(bucket, key) do
with download = %ExAws.S3.Download{} <- ExAws.S3.download_file(bucket, key, :memory) do
ExAws.stream!(download)
end
end
@doc """
Head an object in a bucket.
"""
@spec head_object(bucket :: String.t(), key :: String.t()) :: response()
def head_object(bucket, key) do
with operation = %ExAws.Operation.S3{} <- ExAws.S3.head_object(bucket, key) do
ExAws.request(operation)
end
end
@doc """
Check if bucket exists. Create it if it does not.
"""
@spec upsert_bucket(bucket :: String.t(), region :: String.t()) :: response()
def upsert_bucket(bucket, region) do
case bucket |> ExAws.S3.head_bucket() |> ExAws.request() do
{:ok, _} = ok ->
ok
{:error, {:http_error, 404, _}} ->
bucket
|> ExAws.S3.put_bucket(region)
|> ExAws.request()
|> handle_put_bucket_conflicts()
{:error, other} ->
{:error, other}
end
end
defp handle_put_bucket_conflicts(ok = {:ok, _}), do: ok
# If the name is taken globally but owned by us, treat as success.
defp handle_put_bucket_conflicts({:error, {:http_error, 409, _}}),
do: {:ok, :exists}
defp handle_put_bucket_conflicts(other),
do: other
end