104 lines
2.8 KiB
Elixir
104 lines
2.8 KiB
Elixir
defmodule ZoeyscomputerWeb.ImageController do
|
|
use ZoeyscomputerWeb, :controller
|
|
|
|
alias Zoeyscomputer.IdGenerator
|
|
alias Zoeyscomputer.Images
|
|
alias Zoeyscomputer.Images.Image
|
|
|
|
action_fallback ZoeyscomputerWeb.FallbackController
|
|
|
|
def index(conn, _params) do
|
|
images = Images.list_images()
|
|
render(conn, :index, images: images)
|
|
end
|
|
|
|
def create(conn, %{"file" => upload}) do
|
|
user = conn.assigns.current_user
|
|
|
|
case handle_upload(upload) do
|
|
{:ok, s3_key} ->
|
|
# Fixed: create_image takes one argument (the params map)
|
|
case Images.create_image(%{file: s3_key, user_id: user.id}) do
|
|
{:ok, image} ->
|
|
conn
|
|
|> put_status(:created)
|
|
|> put_resp_header("location", ~p"/api/images/#{image}")
|
|
|> json(%{
|
|
message: "File uploaded successfully",
|
|
url: get_public_url(s3_key),
|
|
image: image
|
|
})
|
|
|
|
{:error, changeset} ->
|
|
conn
|
|
|> put_status(:unprocessable_entity)
|
|
|> json(%{
|
|
error: "Database save failed",
|
|
details: changeset_error_to_string(changeset)
|
|
})
|
|
end
|
|
|
|
{:error, reason} ->
|
|
conn
|
|
|> put_status(:unprocessable_entity)
|
|
|> json(%{
|
|
error: "Upload failed",
|
|
reason: inspect(reason)
|
|
})
|
|
end
|
|
end
|
|
|
|
defp changeset_error_to_string(changeset) do
|
|
Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} ->
|
|
Enum.reduce(opts, msg, fn {key, value}, acc ->
|
|
String.replace(acc, "%{#{key}}", to_string(value))
|
|
end)
|
|
end)
|
|
end
|
|
|
|
defp handle_upload(upload) do
|
|
extension = Path.extname(upload.filename)
|
|
id = IdGenerator.generate()
|
|
key = "uploads/#{id}#{extension}"
|
|
bucket = "imgs"
|
|
|
|
{:ok, file_binary} = File.read(upload.path)
|
|
|
|
case ExAws.S3.put_object(bucket, key, file_binary)
|
|
|> ExAws.request() do
|
|
{:ok, _response} -> {:ok, id}
|
|
{:error, reason} -> {:error, reason}
|
|
end
|
|
end
|
|
|
|
defp get_public_url(key) do
|
|
"https://zoeys.computer/images/#{key}"
|
|
end
|
|
|
|
def show(conn, %{"id" => id}) do
|
|
image = Images.get_image!(id)
|
|
render(conn, :show, image: image)
|
|
end
|
|
|
|
def update(conn, %{"id" => id, "image" => image_params}) do
|
|
image = Images.get_image!(id)
|
|
|
|
with {:ok, %Image{} = image} <- Images.update_image(image, image_params) do
|
|
render(conn, :show, image: image)
|
|
end
|
|
end
|
|
|
|
def delete(conn, %{"id" => id}) do
|
|
image = Images.get_image!(id)
|
|
|
|
case ExAws.S3.delete_object("imgs", image.file)
|
|
|> ExAws.request() do
|
|
{:ok, _response} -> {:ok, image.file}
|
|
{:error, reason} -> {:error, reason}
|
|
end
|
|
|
|
with {:ok, %Image{}} <- Images.delete_image(image) do
|
|
send_resp(conn, :no_content, "")
|
|
end
|
|
end
|
|
end
|