Packages

A Slack Web API client generatef from their OpenAPI specs.

Current section

Files

Jump to
box lib box.ex
Raw

lib/box.ex

defmodule Box do
@moduledoc """
Unofficial Box SDK for Elixir. See the BoxOAuth2 module to get started.
"""
alias Tesla.Multipart
@box_api_url "https://api.box.com/2.0"
@box_upload_url "https://upload.box.com/api/2.0"
@box_root_folder "0"
@doc """
Folder items returns the entries in a folder.
{:ok, folder} = Box.folder_from_path(auth.client, "/")
{:ok, entries} = Box.folder_items(auth.client, folder.id, [:id, :name])
IO.inspect(entries)
"""
def folder_items(client, folder, fields \\ []) do
with {:ok, response} <-
Tesla.get(client, @box_api_url <> "/folders/#{folder}/items",
query: [fields: Enum.join(fields, ",")]
) do
case response do
%{status: 200, body: %{entries: entries}} ->
{:ok, entries}
%{status: status, body: %{message: message}} ->
{:error, status, message}
%{status: status} ->
{:error, status, to_string(status)}
end
end
end
@doc """
Folder from path returns the folder id for a path in Box.
{:ok, folder} = Box.folder_from_path(auth.client, "/")
"""
def folder_from_path(client, path) do
if path == "/" or path == "." do
{:ok, %{id: @box_root_folder}}
else
result =
path
|> String.trim_leading("/")
|> Path.split()
|> List.foldl(%{id: @box_root_folder}, fn name, parent ->
find_folder(client, parent, name)
end)
case result do
%{id: _id} -> {:ok, result}
nil -> {:error, 404, "Not Found"}
{:error, _} -> result
end
end
end
defp find_folder(client, %{id: id} = _parent_folder, folder_name) do
with {:ok, files} <- Box.folder_items(client, id, [:id, :name]) do
Enum.find(files, fn f -> f.type == "folder" and f.name == folder_name end)
end
end
defp find_folder(_client, err, _folder_name), do: err
@doc """
File from path returns the file name and id for a path in Box.
{:ok, file} = Box.file_from_path(auth.client, "file.ext")
"""
def file_from_path(client, path) do
with {:ok, folder} <- folder_from_path(client, Path.dirname(path)),
{:ok, files} <- folder_items(client, folder.id, [:id, :name]) do
filename = Path.basename(path)
case Enum.find(files, fn f -> f.type == "file" and f.name == filename end) do
nil -> {:error, "file not found"}
f -> {:ok, f}
end
end
end
@doc """
Create shared link for a file.
{:ok, file} = Box.file_from_path(auth.client, "file.ext")
{:ok, response.shared_link} = Box.create_shared_link(auth.client, file.id)
IO.puts(response.shared_link.download_url)
"""
def create_shared_link(client, file_id) do
# https://developer.box.com/reference#shared-link-object
body = %{
shared_link: %{
access: "open",
# TODO: password, unshared_at?
permissions: %{
can_download: true
}
}
}
with {:ok, response} <- Tesla.put(client, @box_api_url <> "/files/#{file_id}", body) do
case response do
%{status: 200, body: body} ->
{:ok, body}
%{status: status, body: %{message: message}} ->
{:error, status, message}
%{status: status} ->
{:error, status, to_string(status)}
end
end
end
@doc """
File info for a file id.
{:ok, file} = Box.file_from_path(auth.client, "file.ext")
{:ok, response} = Box.file_info(auth.client, file.id)
IO.puts(response.shared_link.download_url)
"""
def file_info(client, file_id) do
fields = [
:type,
:id,
:sequence_id,
:etag,
:name,
:created_at,
:modified_at,
:description,
:size,
:path_collection,
:created_by,
:modified_by,
:trashed_at,
:purged_at,
:content_created_at,
:content_modified_at,
:owned_by,
:shared_link,
:folder_upload_email,
:parent,
:item_status,
:item_collection,
:sync_state,
:has_collaborations,
:permissions,
:tags,
:sha1,
:shared_link,
:version_number,
:comment_count,
:lock,
:extension,
:is_package,
:can_non_owners_invite
]
with {:ok, response} <-
Tesla.get(client, @box_api_url <> "/files/#{file_id}",
query: [fields: Enum.join(fields, ",")]
) do
{:ok, response.body}
end
end
@doc """
Upload a local file to a folder on Box.
{:ok, folder} = Box.folder_from_path(auth.client, "/")
{:ok, _response} = Box.upload(auth.client, "path/to/file.ext", folder.id, "file.ext")
"""
def upload(client, path, folder_id, name) do
attributes =
Jason.encode!(%{
name: name,
parent: %{id: folder_id}
})
mp =
Multipart.new()
|> Multipart.add_field("attributes", attributes)
|> Multipart.add_file(path)
with {:ok, response} <- Tesla.post(client, @box_upload_url <> "/files/content", mp) do
case response do
%{status: 201, body: body} ->
{:ok, body}
%{status: status, body: %{message: message}} ->
{:error, status, message}
%{status: status} ->
{:error, status, to_string(status)}
end
end
end
@doc """
Create folder in a parent folder.
{:ok, folder} = Box.folder_from_path(auth.client, "/")
{:ok, response} = Box.create_folder(auth.client, "folder", folder.id)
"""
def create_folder(client, name, folder_id) do
body = %{
name: name,
parent: %{id: folder_id}
}
with {:ok, response} <- Tesla.post(client, @box_api_url <> "/folders", body) do
case response do
%{status: 201, body: body} ->
{:ok, body}
%{status: status, body: %{message: message}} ->
{:error, status, message}
%{status: status} ->
{:error, status, to_string(status)}
end
end
end
end