Working s3 compatible file uplaods!
This commit is contained in:
47
lib/mixer_web/controllers/upload_controller.ex
Normal file
47
lib/mixer_web/controllers/upload_controller.ex
Normal file
@@ -0,0 +1,47 @@
|
||||
defmodule MixerWeb.UploadController do
|
||||
use MixerWeb, :controller
|
||||
|
||||
alias Mixer.Posts.MediaUploader
|
||||
|
||||
def create(conn, %{"file" => %Plug.Upload{} = upload}) do
|
||||
actor = conn.assigns[:current_user]
|
||||
|
||||
unless actor do
|
||||
conn
|
||||
|> put_status(:unauthorized)
|
||||
|> json(%{error: "authentication required"})
|
||||
else
|
||||
scope = %{id: Ash.UUID.generate()}
|
||||
|
||||
case MediaUploader.store({upload, scope}) do
|
||||
{:ok, file_name} ->
|
||||
s3_key = "uploads/media/#{scope.id}/#{file_name}"
|
||||
url = MediaUploader.url({file_name, scope})
|
||||
|
||||
Mixer.Posts.Media
|
||||
|> Ash.Changeset.for_create(:upload, %{s3_key: s3_key}, actor: actor)
|
||||
|> Ash.create()
|
||||
|> case do
|
||||
{:ok, media} ->
|
||||
json(conn, %{success: true, mediaId: media.id, url: url})
|
||||
|
||||
{:error, error} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> json(%{success: false, error: inspect(error)})
|
||||
end
|
||||
|
||||
{:error, reason} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> json(%{success: false, error: reason})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create(conn, _params) do
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json(%{error: "no file provided"})
|
||||
end
|
||||
end
|
||||
@@ -56,7 +56,8 @@ defmodule MixerWeb.Endpoint do
|
||||
plug Plug.Parsers,
|
||||
parsers: [:urlencoded, :multipart, :json, Absinthe.Plug.Parser, AshJsonApi.Plug.Parser],
|
||||
pass: ["*/*"],
|
||||
json_decoder: Phoenix.json_library()
|
||||
json_decoder: Phoenix.json_library(),
|
||||
length: 10_000_000
|
||||
|
||||
plug Plug.MethodOverride
|
||||
plug Plug.Head
|
||||
|
||||
@@ -41,6 +41,7 @@ defmodule MixerWeb.Router do
|
||||
get "/feed", PageController, :index
|
||||
post "/rpc/run", AshTypescriptRpcController, :run
|
||||
post "/rpc/validate", AshTypescriptRpcController, :validate
|
||||
post "/upload", UploadController, :create
|
||||
auth_routes AuthController, Mixer.Accounts.User, path: "/auth"
|
||||
sign_out_route AuthController
|
||||
|
||||
|
||||
59
lib/mixer_web/uploaders/media.ex
Normal file
59
lib/mixer_web/uploaders/media.ex
Normal file
@@ -0,0 +1,59 @@
|
||||
defmodule Mixer.Media do
|
||||
use Waffle.Definition
|
||||
|
||||
# Include ecto support (requires package waffle_ecto installed):
|
||||
# use Waffle.Ecto.Definition
|
||||
|
||||
@versions [:original]
|
||||
|
||||
# To add a thumbnail version:
|
||||
# @versions [:original, :thumb]
|
||||
|
||||
# Override the bucket on a per definition basis:
|
||||
# def bucket do
|
||||
# :custom_bucket_name
|
||||
# end
|
||||
|
||||
# def bucket({_file, scope}) do
|
||||
# scope.bucket || bucket()
|
||||
# end
|
||||
|
||||
# Whitelist file extensions:
|
||||
# def validate({file, _}) do
|
||||
# file_extension = file.file_name |> Path.extname() |> String.downcase()
|
||||
#
|
||||
# case Enum.member?(~w(.jpg .jpeg .gif .png), file_extension) do
|
||||
# true -> :ok
|
||||
# false -> {:error, "invalid file type"}
|
||||
# end
|
||||
# end
|
||||
|
||||
# Define a thumbnail transformation:
|
||||
# def transform(:thumb, _) do
|
||||
# {:convert, "-strip -thumbnail 250x250^ -gravity center -extent 250x250 -format png", :png}
|
||||
# end
|
||||
|
||||
# Override the persisted filenames:
|
||||
# def filename(version, _) do
|
||||
# version
|
||||
# end
|
||||
|
||||
# Override the storage directory:
|
||||
# def storage_dir(version, {file, scope}) do
|
||||
# "uploads/user/avatars/#{scope.id}"
|
||||
# end
|
||||
|
||||
# Provide a default URL if there hasn't been a file uploaded
|
||||
# def default_url(version, scope) do
|
||||
# "/images/avatars/default_#{version}.png"
|
||||
# end
|
||||
|
||||
# Specify custom headers for s3 objects
|
||||
# Available options are [:cache_control, :content_disposition,
|
||||
# :content_encoding, :content_length, :content_type,
|
||||
# :expect, :expires, :storage_class, :website_redirect_location]
|
||||
#
|
||||
# def s3_object_headers(version, {file, scope}) do
|
||||
# [content_type: MIME.from_path(file.file_name)]
|
||||
# end
|
||||
end
|
||||
Reference in New Issue
Block a user