From dad39b24a1bca0341d5cf47cc4a32ea66219c654 Mon Sep 17 00:00:00 2001 From: Thurloat Date: Tue, 28 Aug 2018 19:48:03 -0300 Subject: [PATCH] add the behaviour, work on actually making it work. --- lib/pleroma/upload.ex | 50 ++++++++++--------------------- lib/pleroma/uploaders/local.ex | 6 ++-- lib/pleroma/uploaders/uploader.ex | 26 ++++++++++++++++ 3 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 lib/pleroma/uploaders/uploader.ex diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index e786693ad..16149d4dd 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -1,11 +1,13 @@ defmodule Pleroma.Upload do alias Ecto.UUID + import Logger @storage_backend Application.get_env(:pleroma, Pleroma.Upload) |> Keyword.fetch!(:uploader) def store(%Plug.Upload{} = file, should_dedupe) do content_type = get_content_type(file.path) + uuid = get_uuid(file, should_dedupe) name = get_name(file, uuid, content_type, should_dedupe) @@ -26,23 +28,21 @@ def store(%Plug.Upload{} = file, should_dedupe) do } end - """ # XXX: does this code actually work? i am skeptical. --kaniini def store(%{"img" => "data:image/" <> image_data}, should_dedupe) do - settings = Application.get_env(:pleroma, Pleroma.Upload) - use_s3 = Keyword.fetch!(settings, :use_s3) - parsed = Regex.named_captures(~r/(?jpeg|png|gif);base64,(?.*)/, image_data) data = Base.decode64!(parsed["data"], ignore: :whitespace) - uuid = UUID.generate() - uuidpath = Path.join(upload_path(), uuid) + + tmp_path = mkupload_for_image(data) + uuid = UUID.generate() - File.mkdir_p!(upload_path()) + # create temp local storage, like plug upload provides for us. - File.write!(uuidpath, data) + Logger.info(tmp_path) - content_type = get_content_type(uuidpath) + content_type = get_content_type(tmp_path) + strip_exif_data(content_type, tmp_path) name = create_name( @@ -51,30 +51,7 @@ def store(%{"img" => "data:image/" <> image_data}, should_dedupe) do content_type ) - upload_folder = get_upload_path(uuid, should_dedupe) - url_path = get_url(name, uuid, should_dedupe) - - File.mkdir_p!(upload_folder) - result_file = Path.join(upload_folder, name) - - if should_dedupe do - if !File.exists?(result_file) do - File.rename(uuidpath, result_file) - else - File.rm!(uuidpath) - end - else - File.rename(uuidpath, result_file) - end - - strip_exif_data(content_type, result_file) - - url_path = - if use_s3 do - put_s3_file(name, uuid, result_file, content_type) - else - url_path - end + url_path = @storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe) %{ "type" => "Image", @@ -88,7 +65,12 @@ def store(%{"img" => "data:image/" <> image_data}, should_dedupe) do "name" => name } end - """ + + def mkupload_for_image(data) do + {:ok, tmp_path} = Plug.Upload.random_file("profile_pics") + :file.write_file(tmp_path, data, [:write, :raw, :exclusive, :binary]) + tmp_path + end def strip_exif_data(content_type, file) do settings = Application.get_env(:pleroma, Pleroma.Upload) diff --git a/lib/pleroma/uploaders/local.ex b/lib/pleroma/uploaders/local.ex index b089c8f14..39dca49c9 100644 --- a/lib/pleroma/uploaders/local.ex +++ b/lib/pleroma/uploaders/local.ex @@ -3,7 +3,7 @@ defmodule Pleroma.Uploaders.Local do alias Pleroma.Web - def put_file(name, uuid, file, _content_type, should_dedupe) do + def put_file(name, uuid, tmpfile, _content_type, should_dedupe) do upload_folder = get_upload_path(uuid, should_dedupe) url_path = get_url(name, uuid, should_dedupe) @@ -12,9 +12,9 @@ def put_file(name, uuid, file, _content_type, should_dedupe) do result_file = Path.join(upload_folder, name) if File.exists?(result_file) do - File.rm!(file.path) + File.rm!(tmpfile) else - File.cp!(file.path, result_file) + File.cp!(tmpfile, result_file) end url_path diff --git a/lib/pleroma/uploaders/uploader.ex b/lib/pleroma/uploaders/uploader.ex new file mode 100644 index 000000000..7380320af --- /dev/null +++ b/lib/pleroma/uploaders/uploader.ex @@ -0,0 +1,26 @@ +defmodule Pleroma.Uploaders.Uploader do + @moduledoc """ + Defines the contract to put an uploaded file to any backend. + """ + + @doc """ + Put a file to the backend. + + Returns a `String.t` containing the path of the uploaded file. + """ + @callback put_file( + name :: String.t(), + uuid :: String.t(), + file :: File.t(), + content_type :: String.t(), + should_dedupe :: Boolean.t() + ) :: String.t() + + @callback put_file( + name :: String.t(), + uuid :: String.t(), + image_data :: String.t(), + content_type :: String.t(), + should_dedupe :: String.t() + ) :: String.t() +end