fix images
This commit is contained in:
parent
d7559647e2
commit
3b63d75219
7 changed files with 85 additions and 76 deletions
15
deps.nix
15
deps.nix
|
|
@ -527,6 +527,21 @@ let
|
||||||
beamDeps = [ castore hpax ];
|
beamDeps = [ castore hpax ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mogrify =
|
||||||
|
let
|
||||||
|
version = "0.9.3";
|
||||||
|
in
|
||||||
|
buildMix {
|
||||||
|
inherit version;
|
||||||
|
name = "mogrify";
|
||||||
|
|
||||||
|
src = fetchHex {
|
||||||
|
inherit version;
|
||||||
|
pkg = "mogrify";
|
||||||
|
sha256 = "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
nimble_options =
|
nimble_options =
|
||||||
let
|
let
|
||||||
version = "1.1.1";
|
version = "1.1.1";
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@
|
||||||
import ./deps.nix {
|
import ./deps.nix {
|
||||||
inherit pkgs lib beamPackages;
|
inherit pkgs lib beamPackages;
|
||||||
};
|
};
|
||||||
buildInputs = with pkgs; [nodejs];
|
buildInputs = with pkgs; [nodejs imagemagick];
|
||||||
|
|
||||||
postBuild = ''
|
postBuild = ''
|
||||||
echo ${heroicons}
|
echo ${heroicons}
|
||||||
|
|
@ -314,6 +314,7 @@
|
||||||
nodejs
|
nodejs
|
||||||
mix2nix
|
mix2nix
|
||||||
node2nix
|
node2nix
|
||||||
|
imagemagick
|
||||||
# Add the language server of your choice.
|
# Add the language server of your choice.
|
||||||
inputs.lexical.packages.${system}.default
|
inputs.lexical.packages.${system}.default
|
||||||
# I once added Hex via a Nix development shell, but now I install
|
# I once added Hex via a Nix development shell, but now I install
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
defmodule ZoeyscomputerWeb.ImageController do
|
defmodule ZoeyscomputerWeb.ImageController do
|
||||||
use ZoeyscomputerWeb, :controller
|
use ZoeyscomputerWeb, :controller
|
||||||
|
|
||||||
|
import Mogrify
|
||||||
|
|
||||||
alias Zoeyscomputer.IdGenerator
|
alias Zoeyscomputer.IdGenerator
|
||||||
alias Zoeyscomputer.Images
|
alias Zoeyscomputer.Images
|
||||||
alias Zoeyscomputer.Images.Image
|
alias Zoeyscomputer.Images.Image
|
||||||
|
|
@ -59,12 +61,23 @@ defmodule ZoeyscomputerWeb.ImageController do
|
||||||
defp handle_upload(upload) do
|
defp handle_upload(upload) do
|
||||||
extension = Path.extname(upload.filename)
|
extension = Path.extname(upload.filename)
|
||||||
id = IdGenerator.generate()
|
id = IdGenerator.generate()
|
||||||
key = "uploads/#{id}#{extension}"
|
key = "uploads/#{id}.png"
|
||||||
bucket = "imgs"
|
bucket = "imgs"
|
||||||
|
|
||||||
|
local_path = "/tmp/#{id}#{extension}"
|
||||||
|
|
||||||
|
IO.puts("upload path: #{upload.path}")
|
||||||
{:ok, file_binary} = File.read(upload.path)
|
{:ok, file_binary} = File.read(upload.path)
|
||||||
|
|
||||||
case ExAws.S3.put_object(bucket, key, file_binary)
|
File.write!(local_path, file_binary)
|
||||||
|
|
||||||
|
IO.puts("wrote to #{local_path}")
|
||||||
|
image = open(local_path) |> format("png") |> save()
|
||||||
|
IO.inspect(image)
|
||||||
|
|
||||||
|
{:ok, new_file_binary} = File.read(image.path)
|
||||||
|
|
||||||
|
case ExAws.S3.put_object(bucket, key, new_file_binary, %{content_type: "image/png"})
|
||||||
|> ExAws.request() do
|
|> ExAws.request() do
|
||||||
{:ok, _response} -> {:ok, id}
|
{:ok, _response} -> {:ok, id}
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
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
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
defmodule ZoeyscomputerWeb.Router do
|
defmodule ZoeyscomputerWeb.Router do
|
||||||
|
alias ExAws.S3
|
||||||
|
alias Zoeyscomputer.Images
|
||||||
alias ZoeyscomputerWeb.DiscordPlug
|
alias ZoeyscomputerWeb.DiscordPlug
|
||||||
use ZoeyscomputerWeb, :router
|
use ZoeyscomputerWeb, :router
|
||||||
|
|
||||||
|
|
@ -11,6 +13,7 @@ defmodule ZoeyscomputerWeb.Router do
|
||||||
plug :put_root_layout, html: {ZoeyscomputerWeb.Layouts, :root}
|
plug :put_root_layout, html: {ZoeyscomputerWeb.Layouts, :root}
|
||||||
plug :protect_from_forgery
|
plug :protect_from_forgery
|
||||||
plug :put_secure_browser_headers
|
plug :put_secure_browser_headers
|
||||||
|
plug :handle_discord
|
||||||
plug :fetch_current_user
|
plug :fetch_current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -18,10 +21,6 @@ defmodule ZoeyscomputerWeb.Router do
|
||||||
plug ZoeyscomputerWeb.Plugs.ApiAuthentication
|
plug ZoeyscomputerWeb.Plugs.ApiAuthentication
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :discord do
|
|
||||||
plug DiscordPlug
|
|
||||||
end
|
|
||||||
|
|
||||||
pipeline :api do
|
pipeline :api do
|
||||||
plug :accepts, ["json"]
|
plug :accepts, ["json"]
|
||||||
end
|
end
|
||||||
|
|
@ -108,28 +107,62 @@ defmodule ZoeyscomputerWeb.Router do
|
||||||
live "/users/confirm/:token", UserConfirmationLive, :edit
|
live "/users/confirm/:token", UserConfirmationLive, :edit
|
||||||
live "/users/confirm", UserConfirmationInstructionsLive, :new
|
live "/users/confirm", UserConfirmationInstructionsLive, :new
|
||||||
live "/", HomeLive, :index
|
live "/", HomeLive, :index
|
||||||
|
|
||||||
|
live "/images/:id", ImageLive.Show, :show
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", ZoeyscomputerWeb do
|
scope "/", ZoeyscomputerWeb do
|
||||||
pipe_through :check_discord
|
pipe_through [:browser, :require_authenticated_user]
|
||||||
live "/images/:id", ImageController, :show
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_discord(conn, _opts) do
|
defp download_from_s3(bucket, key) do
|
||||||
case get_req_header(conn, "user-agent") do
|
case S3.get_object(bucket, key) |> ExAws.request() do
|
||||||
["Discord" <> _rest | _] ->
|
{:ok, %{body: image_binary, headers: headers}} ->
|
||||||
conn
|
content_type =
|
||||||
|> put_private(:phoenix_pipeline, {:doscord, []})
|
Enum.find_value(headers, fn
|
||||||
|> DiscordPlug.call([])
|
{"Content-Type", value} -> value
|
||||||
|
{"content-type", value} -> value
|
||||||
|
_ -> nil
|
||||||
|
end)
|
||||||
|
|
||||||
["Discord-Bot/" <> _rest | _] ->
|
{:ok, image_binary, content_type || "application/octet-stream"}
|
||||||
conn
|
|
||||||
|> put_private(:phoenix_pipeline, {:discord, []})
|
|
||||||
|> DiscordPlug.call([])
|
|
||||||
|
|
||||||
_ ->
|
error ->
|
||||||
conn |> put_private(:phoenix_pipeline, {:browser, []})
|
error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Updated plug to return ID as string for Discord requests
|
||||||
|
def handle_discord(conn, _opts) do
|
||||||
|
is_discord =
|
||||||
|
case get_req_header(conn, "user-agent") do
|
||||||
|
["Discord" <> _rest | _] -> true
|
||||||
|
["Discord-Bot/" <> _rest | _] -> true
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
|
||||||
|
if true do
|
||||||
|
# Extract the ID from the path
|
||||||
|
id = List.last(conn.path_info)
|
||||||
|
|
||||||
|
case download_from_s3("imgs", "uploads/#{id}.png") do
|
||||||
|
{:ok, image_binary, content_type} ->
|
||||||
|
conn
|
||||||
|
|> put_resp_content_type(content_type)
|
||||||
|
|> send_resp(200, image_binary)
|
||||||
|
|> halt()
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
IO.puts(reason)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_resp_content_type("text/plain")
|
||||||
|
|> send_resp(500, "failed to retrieve image")
|
||||||
|
|> halt()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
conn
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
1
mix.exs
1
mix.exs
|
|
@ -46,6 +46,7 @@ defmodule Zoeyscomputer.MixProject do
|
||||||
{:phoenix_live_dashboard, "~> 0.8.3"},
|
{:phoenix_live_dashboard, "~> 0.8.3"},
|
||||||
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
|
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
|
||||||
{:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
|
{:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
|
||||||
|
{:mogrify, "~> 0.9.3"},
|
||||||
{:heroicons,
|
{:heroicons,
|
||||||
github: "tailwindlabs/heroicons",
|
github: "tailwindlabs/heroicons",
|
||||||
tag: "v2.1.1",
|
tag: "v2.1.1",
|
||||||
|
|
|
||||||
1
mix.lock
1
mix.lock
|
|
@ -29,6 +29,7 @@
|
||||||
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
|
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
|
||||||
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
|
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
|
||||||
"mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"},
|
"mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"},
|
||||||
|
"mogrify": {:hex, :mogrify, "0.9.3", "238c782f00271dace01369ad35ae2e9dd020feee3443b9299ea5ea6bed559841", [:mix], [], "hexpm", "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6"},
|
||||||
"nanoid": {:hex, :nanoid, "2.1.0", "d192a5bf1d774258bc49762b480fca0e3128178fa6d35a464af2a738526607fd", [:mix], [], "hexpm", "ebc7a342d02d213534a7f93a091d569b9fea7f26fcd3a638dc655060fc1f76ac"},
|
"nanoid": {:hex, :nanoid, "2.1.0", "d192a5bf1d774258bc49762b480fca0e3128178fa6d35a464af2a738526607fd", [:mix], [], "hexpm", "ebc7a342d02d213534a7f93a091d569b9fea7f26fcd3a638dc655060fc1f76ac"},
|
||||||
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
||||||
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue