56 lines
1.3 KiB
Elixir
56 lines
1.3 KiB
Elixir
|
|
defmodule ZoeyscomputerWeb.DiscordPlug do
|
||
|
|
alias ExAws.S3
|
||
|
|
alias Zoeyscomputer.Images
|
||
|
|
import Plug.Conn
|
||
|
|
|
||
|
|
def init(opts), do: opts
|
||
|
|
|
||
|
|
def call(%Plug.Conn{path_info: ["images", id]} = conn, _opts) do
|
||
|
|
case Images.get_image_by!(id) do
|
||
|
|
nil ->
|
||
|
|
conn
|
||
|
|
|> send_resp(404, "Image not found")
|
||
|
|
|> halt()
|
||
|
|
|
||
|
|
image ->
|
||
|
|
serve_s3_image(conn, image)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
def call(conn, _opts), do: conn
|
||
|
|
|
||
|
|
defp serve_s3_image(conn, image) do
|
||
|
|
key = image.key
|
||
|
|
bucket = "imgs"
|
||
|
|
|
||
|
|
case download_from_s3(bucket, key) do
|
||
|
|
{:ok, image_binary, content_type} ->
|
||
|
|
conn
|
||
|
|
|> put_resp_header("content-type", content_type)
|
||
|
|
|> send_resp(200, image_binary)
|
||
|
|
|> halt()
|
||
|
|
|
||
|
|
{:error, _reason} ->
|
||
|
|
conn
|
||
|
|
|> send_resp(500, "Failed to retrieve image")
|
||
|
|
|> halt()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
defp download_from_s3(bucket, key) do
|
||
|
|
case S3.get_object(bucket, key) |> ExAws.request() do
|
||
|
|
{:ok, %{body: image_binary, headers: headers}} ->
|
||
|
|
content_type =
|
||
|
|
Enum.find_value(headers, fn
|
||
|
|
{"Content-Type", value} -> value
|
||
|
|
{"content-type", value} -> value
|
||
|
|
end)
|
||
|
|
|
||
|
|
{:ok, image_binary, content_type || "application/octet-stream"}
|
||
|
|
|
||
|
|
error ->
|
||
|
|
error
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|