Packages

Elixir package to interact via REST API with Azure Storage and Google Cloud Storage.

Current section

Files

Jump to
cloud_storage lib cloud_storage cloud_storage_azure.ex
Raw

lib/cloud_storage/cloud_storage_azure.ex

defmodule CloudStorage.Azure do
@moduledoc """
CloudStorage Azure Documentation.
"""
@azure_api_version Application.get_env(:cloud_storage, :azure_api_version)
@base_login Application.get_env(:cloud_storage, :azure_default_base_login)
@base_resource Application.get_env(:cloud_storage, :azure_default_base_resource)
@base_scheme Application.get_env(:cloud_storage, :azure_default_scheme)
@base_url Application.get_env(:cloud_storage, :azure_default_base_url)
@client_id Application.get_env(:cloud_storage, :azure_default_client)
@client_secret Application.get_env(:cloud_storage, :azure_default_client_secret)
@container Application.get_env(:cloud_storage, :azure_default_container)
@endpoint Application.get_env(:cloud_storage, :azure_default_endpoint)
@profile Application.get_env(:cloud_storage, :azure_default_profile)
@provider Application.get_env(:cloud_storage, :azure_default_provider)
@resourcegroup Application.get_env(:cloud_storage, :azure_default_resourcegroup)
@sas_token Application.get_env(:cloud_storage, :azure_default_sas_token)
@storage_account Application.get_env(:cloud_storage, :azure_default_account)
@subscription_id Application.get_env(:cloud_storage, :azure_default_subscription)
@tenant_id Application.get_env(:cloud_storage, :azure_default_tenant)
@doc """
Upload a File from an URL.
## Examples
iex> CloudStorage.Azure.url("https://www.google.com.br/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", "logo.png")
{:ok, "logo.png"}
"""
def url(url, remote_path) do
options =
[
hackney: [:insecure]
]
{:ok, response} =
HTTPoison.get(url, [], options)
case response.status_code do
200 ->
content =
response.body
type =
response.headers
|> List.keyfind("Content-Type", 0)
|> elem(1)
put(remote_path, content, type)
_ ->
{:error, response.status_code}
end
end
@doc """
Send a File.
## Examples
iex> CloudStorage.Azure.put("temp_file.txt")
{:ok, "temp_file.txt"}
"""
def put(full_path, content \\ "", type \\ "application/octet-stream") do
header =
[
"Content-Type": type,
"Content-Length": 0,
"x-ms-blob-type": "BlockBlob"
]
url =
full_path
|> blob_url()
{:ok, response} =
HTTPoison.put(url, content, header)
case response.status_code do
201 ->
{:ok, full_path}
_ ->
{:error, response.status_code}
end
end
@doc """
List Files.
## Examples
iex> CloudStorage.Azure.list("temp_file.txt") |> elem(1) |> List.first() |> Map.get("name")
"temp_file.txt"
"""
def list(full_path \\ "", _folders \\ false) do
base_url =
@base_scheme
|> Kernel.<>(@storage_account)
|> Kernel.<>(@base_url)
|> Kernel.<>(@container)
|> Kernel.<>("?")
|> Kernel.<>(@sas_token)
url =
base_url
|> Kernel.<>("&restype=container&comp=list&prefix=")
|> Kernel.<>(full_path)
items =
url
|> HTTPoison.get()
|> elem(1)
|> Map.get(:body)
|> XmlToMap.naive_map()
|> Map.get("EnumerationResults")
|> Map.get("Blobs")
|> Map.get("Blob")
final_items =
items
|> is_map()
|> case do
true ->
[items]
false ->
items
end
|> Enum.map(fn x ->
%{
"content-type" => x["Properties"]["Content-Type"],
"name" => x["Name"],
"updated" => x["Properties"]["Last-Modified"] |> time_to_local()
}
end)
{:ok, final_items}
end
defp time_to_local(datetime) do
{:ok, timestamp} =
datetime
|> Timex.parse("{WDshort}, {D} {Mshort} {YYYY} {h24}:{m}:{s} {Zname}")
timestamp
|> Timex.format!("{ISO:Extended:Z}")
end
@doc """
Get a File.
## Examples
iex> CloudStorage.Azure.get("temp_file.txt")
{:ok, ""}
"""
def get(full_path) do
url =
full_path
|> blob_url()
content =
url
|> HTTPoison.get()
|> elem(1)
|> Map.get(:body)
{:ok, content}
end
defp blob_url(full_path) do
@base_scheme
|> Kernel.<>(@storage_account)
|> Kernel.<>(@base_url)
|> Kernel.<>(@container)
|> Kernel.<>("/")
|> Kernel.<>(full_path)
|> Kernel.<>("?")
|> Kernel.<>(@sas_token)
end
@doc """
Download a File.
## Examples
iex> CloudStorage.Azure.download("temp_file.txt", "test")
{:ok, "test/temp_file.txt"}
"""
def download(remote_path, local_path) do
{_status, file_content} =
get(remote_path)
local_file =
remote_path
|> String.split("/")
|> List.last
full_local_path =
local_path
|> Kernel.<>("/")
|> Kernel.<>(local_file)
local_status =
File.write(full_local_path, file_content)
{local_status, full_local_path}
end
@doc """
Upload a File.
## Examples
iex> CloudStorage.Azure.upload("test/temp_file.txt", "temp_file.txt")
{:ok, "temp_file.txt"}
"""
def upload(local_path, remote_path) do
{:ok, file_content} =
File.read(local_path)
file_type =
MIME.from_path(remote_path)
put(remote_path, file_content, file_type)
end
@doc """
Delete a File.
## Examples
iex> CloudStorage.Azure.delete("temp_file.txt")
{:ok, "temp_file.txt"}
iex> CloudStorage.Azure.put("temp_file.txt")
{:ok, "temp_file.txt"}
"""
def delete(full_path) do
url =
full_path
|> blob_url()
{:ok, response} =
HTTPoison.delete(url)
case response.status_code do
202 ->
{:ok, full_path}
_ ->
{:error, response.status_code}
end
end
@doc """
Get a Rest Token.
## Examples
iex> CloudStorage.Azure.get_token() |> is_nil()
false
"""
def get_token() do
header =
[
"Content-Type": "application/x-www-form-urlencoded"
]
post_url =
"/oauth2/token"
url =
@base_login
|> Kernel.<>(@tenant_id)
|> Kernel.<>(post_url)
body =
"grant_type=client_credentials&client_id="
|> Kernel.<>(@client_id)
|> Kernel.<>("&client_secret=")
|> Kernel.<>(@client_secret)
|> Kernel.<>("&resource=")
|> Kernel.<>(@base_resource)
{:ok, response} =
HTTPoison.post(url, body, header)
response.body
|> Poison.decode!()
|> Map.get("access_token")
end
@doc """
Purge a CDN path content.
## Examples
iex> CloudStorage.Azure.purge("/temp_file.txt")
{:ok, "/temp_file.txt"}
"""
def purge(full_path) do
token =
get_token()
header =
[
"Content-Type": "application/json",
"Authorization": "Bearer #{token}"
]
params =
"?api-version=#{@azure_api_version}"
post_url =
"/resourceGroups/"
|> Kernel.<>(@resourcegroup)
|> Kernel.<>("/providers/")
|> Kernel.<>(@provider)
|> Kernel.<>("/profiles/")
|> Kernel.<>(@profile)
|> Kernel.<>("/endpoints/")
|> Kernel.<>(@endpoint)
|> Kernel.<>("/purge")
|> Kernel.<>(params)
url =
@base_resource
|> Kernel.<>("subscriptions/")
|> Kernel.<>(@subscription_id)
|> Kernel.<>(post_url)
body =
"{ \"contentPaths\": [\"#{full_path}\"] }"
{:ok, response} =
HTTPoison.post(url, body, header)
case response.status_code do
202 ->
{:ok, full_path}
_ ->
{:error, response.status_code}
end
end
end