Move construction of S3 base URL with optional namespace and bucket to Upload.base_url/0
[akkoma] / lib / pleroma / upload.ex
index a0ba2f4c0b1c7f9cb3ba34c693124811346b3cb0..a52b698bf65a21f98bcb3466ffa43a35e91dcae4 100644 (file)
@@ -31,6 +31,7 @@ defmodule Pleroma.Upload do
 
   """
   alias Ecto.UUID
+  alias Pleroma.Config
   require Logger
 
   @type source ::
@@ -56,6 +57,15 @@ defmodule Pleroma.Upload do
         }
   defstruct [:id, :name, :tempfile, :content_type, :path]
 
+  defp get_description(opts, upload) do
+    case {opts[:description], Pleroma.Config.get([Pleroma.Upload, :default_description])} do
+      {description, _} when is_binary(description) -> description
+      {_, :filename} -> upload.name
+      {_, str} when is_binary(str) -> str
+      _ -> ""
+    end
+  end
+
   @spec store(source, options :: [option()]) :: {:ok, Map.t()} | {:error, any()}
   @doc "Store a file. If using a `Plug.Upload{}` as the source, be sure to use `Majic.Plug` to ensure its content_type and filename is correct."
   def store(upload, opts \\ []) do
@@ -64,6 +74,10 @@ defmodule Pleroma.Upload do
     with {:ok, upload} <- prepare_upload(upload, opts),
          upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"},
          {:ok, upload} <- Pleroma.Upload.Filter.filter(opts.filters, upload),
+         description = get_description(opts, upload),
+         {_, true} <-
+           {:description_limit,
+            String.length(description) <= Pleroma.Config.get([:instance, :description_limit])},
          {:ok, url_spec} <- Pleroma.Uploaders.Uploader.put_file(opts.uploader, upload) do
       {:ok,
        %{
@@ -76,9 +90,12 @@ defmodule Pleroma.Upload do
              "href" => url_from_spec(upload, opts.base_url, url_spec)
            }
          ],
-         "name" => Map.get(opts, :description) || upload.name
+         "name" => description
        }}
     else
+      {:description_limit, _} ->
+        {:error, :description_too_long}
+
       {:error, error} ->
         Logger.error(
           "#{__MODULE__} store (using #{inspect(opts.uploader)}) failed: #{inspect(error)}"
@@ -212,4 +229,53 @@ defmodule Pleroma.Upload do
   end
 
   defp url_from_spec(_upload, _base_url, {:url, url}), do: url
+
+  def base_url do
+    uploader = Config.get([Pleroma.Upload, :uploader])
+    upload_base_url = Config.get([Pleroma.Upload, :base_url])
+    public_endpoint = Config.get([uploader, :public_endpoint])
+
+    case uploader do
+      Pleroma.Uploaders.Local ->
+        cond do
+          !is_nil(upload_base_url) ->
+            upload_base_url
+
+          true ->
+            Pleroma.Web.base_url() <> "/media/"
+        end
+
+      Pleroma.Uploaders.S3 ->
+        bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
+
+        bucket_with_namespace =
+          cond do
+            truncated_namespace = Config.get([Pleroma.Uploaders.S3, :truncated_namespace]) ->
+              truncated_namespace
+
+            namespace = Config.get([Pleroma.Uploaders.S3, :bucket_namespace]) ->
+              namespace <> ":" <> bucket
+
+            true ->
+              bucket
+          end
+
+        cond do
+          !is_nil(public_endpoint) ->
+            Path.join([public_endpoint, bucket_with_namespace])
+
+          true ->
+            Path.join([upload_base_url, bucket_with_namespace])
+        end
+
+      _ ->
+        cond do
+          !is_nil(public_endpoint) ->
+            public_endpoint
+
+          true ->
+            upload_base_url
+        end
+    end
+  end
 end