Current section
Files
Jump to
Current section
Files
lib/supplement/storages/disk.ex
defmodule Capsule.Storages.Disk do
alias Capsule.{Storage, Upload, Encapsulation}
@behaviour Storage
@impl Storage
def put(upload, opts \\ []) do
with path <- Path.join(opts[:prefix] || "/", Upload.name(upload)),
destination <- path_in_root(opts, path),
true <-
!File.exists?(destination) || opts[:force] ||
{:error, "File already exists at upload destination"},
{:ok, contents} <- Upload.contents(upload) do
create_path!(destination)
File.write!(destination, contents)
encapsulation = %Encapsulation{
id: path,
size: byte_size(contents),
storage: to_string(__MODULE__)
}
{:ok, encapsulation}
end
|> case do
{:error, error} ->
{:error, "Could not store file: #{error}"}
success_tuple ->
success_tuple
end
end
@impl Storage
def copy(%Encapsulation{id: id} = encapsulation, path, opts \\ []) do
path_in_root(opts, path)
|> create_path!
path_in_root(opts, id)
|> File.cp(path_in_root(opts, path))
|> case do
:ok -> {:ok, encapsulation |> Map.replace!(:id, path)}
error_tuple -> error_tuple
end
end
@impl Storage
def delete(%Encapsulation{id: id}, opts \\ []) when is_binary(id) do
path_in_root(opts, id)
|> File.rm()
|> case do
:ok -> :ok
{:error, error} -> {:error, "Could not remove file: #{error}"}
end
end
@impl Storage
def read(%Encapsulation{id: id}, opts \\ []), do: path_in_root(opts, id) |> File.read()
defp config(opts, key) do
Application.fetch_env!(:capsule, __MODULE__)
|> Keyword.merge(opts)
|> Keyword.fetch!(key)
end
defp path_in_root(opts, path) do
config(opts, :root_dir)
|> Path.join(path)
end
defp create_path!(path) do
path |> Path.dirname() |> File.mkdir_p!()
end
end