Update majic & call plug before OpenApiSpex
[akkoma] / lib / pleroma / upload.ex
index c47d6524111b3c40014b71b49a2a4d8d090f842d..a0ba2f4c0b1c7f9cb3ba34c693124811346b3cb0 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Upload do
@@ -37,6 +37,7 @@ defmodule Pleroma.Upload do
           Plug.Upload.t()
           | (data_uri_string :: String.t())
           | {:from_local, name :: String.t(), id :: String.t(), path :: String.t()}
+          | map()
 
   @type option ::
           {:type, :avatar | :banner | :background}
@@ -56,6 +57,7 @@ defmodule Pleroma.Upload do
   defstruct [:id, :name, :tempfile, :content_type, :path]
 
   @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
     opts = get_opts(opts)
 
@@ -66,6 +68,7 @@ defmodule Pleroma.Upload do
       {:ok,
        %{
          "type" => opts.activity_type,
+         "mediaType" => upload.content_type,
          "url" => [
            %{
              "type" => "Link",
@@ -105,7 +108,7 @@ defmodule Pleroma.Upload do
           {Pleroma.Config.get!([:instance, :upload_limit]), "Document"}
       end
 
-    opts = %{
+    %{
       activity_type: Keyword.get(opts, :activity_type, activity_type),
       size_limit: Keyword.get(opts, :size_limit, size_limit),
       uploader: Keyword.get(opts, :uploader, Pleroma.Config.get([__MODULE__, :uploader])),
@@ -118,65 +121,34 @@ defmodule Pleroma.Upload do
           Pleroma.Config.get([__MODULE__, :base_url], Pleroma.Web.base_url())
         )
     }
-
-    # TODO: 1.0+ : remove old config compatibility
-    opts =
-      if Pleroma.Config.get([__MODULE__, :strip_exif]) == true &&
-           !Enum.member?(opts.filters, Pleroma.Upload.Filter.Mogrify) do
-        Logger.warn("""
-        Pleroma: configuration `:instance, :strip_exif` is deprecated, please instead set:
-
-          :pleroma, Pleroma.Upload, [filters: [Pleroma.Upload.Filter.Mogrify]]
-
-          :pleroma, Pleroma.Upload.Filter.Mogrify, args: ["strip", "auto-orient"]
-        """)
-
-        Pleroma.Config.put([Pleroma.Upload.Filter.Mogrify], args: ["strip", "auto-orient"])
-        Map.put(opts, :filters, opts.filters ++ [Pleroma.Upload.Filter.Mogrify])
-      else
-        opts
-      end
-
-    if Pleroma.Config.get([:instance, :dedupe_media]) == true &&
-         !Enum.member?(opts.filters, Pleroma.Upload.Filter.Dedupe) do
-      Logger.warn("""
-      Pleroma: configuration `:instance, :dedupe_media` is deprecated, please instead set:
-
-      :pleroma, Pleroma.Upload, [filters: [Pleroma.Upload.Filter.Dedupe]]
-      """)
-
-      Map.put(opts, :filters, opts.filters ++ [Pleroma.Upload.Filter.Dedupe])
-    else
-      opts
-    end
   end
 
   defp prepare_upload(%Plug.Upload{} = file, opts) do
-    with :ok <- check_file_size(file.path, opts.size_limit),
-         {:ok, content_type, name} <- Pleroma.MIME.file_mime_type(file.path, file.filename) do
+    with :ok <- check_file_size(file.path, opts.size_limit) do
       {:ok,
        %__MODULE__{
          id: UUID.generate(),
-         name: name,
+         name: file.filename,
          tempfile: file.path,
-         content_type: content_type
+         content_type: file.content_type
        }}
     end
   end
 
-  defp prepare_upload(%{"img" => "data:image/" <> image_data}, opts) do
+  defp prepare_upload(%{img: "data:image/" <> image_data}, opts) do
     parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
     data = Base.decode64!(parsed["data"], ignore: :whitespace)
-    hash = String.downcase(Base.encode16(:crypto.hash(:sha256, data)))
+    hash = Base.encode16(:crypto.hash(:sha256, data), lower: true)
 
     with :ok <- check_binary_size(data, opts.size_limit),
          tmp_path <- tempfile_for_image(data),
-         {:ok, content_type, name} <-
-           Pleroma.MIME.bin_mime_type(data, hash <> "." <> parsed["filetype"]) do
+         {:ok, %{mime_type: content_type}} <-
+           Majic.perform({:bytes, data}, pool: Pleroma.MajicPool),
+         [ext | _] <- MIME.extensions(content_type) do
       {:ok,
        %__MODULE__{
          id: UUID.generate(),
-         name: name,
+         name: hash <> "." <> ext,
          tempfile: tmp_path,
          content_type: content_type
        }}
@@ -185,7 +157,7 @@ defmodule Pleroma.Upload do
 
   # For Mix.Tasks.MigrateLocalUploads
   defp prepare_upload(%__MODULE__{tempfile: path} = upload, _opts) do
-    with {:ok, content_type} <- Pleroma.MIME.file_mime_type(path) do
+    with {:ok, %{mime_type: content_type}} <- Majic.perform(path, pool: Pleroma.MajicPool) do
       {:ok, %__MODULE__{upload | content_type: content_type}}
     end
   end
@@ -228,7 +200,14 @@ defmodule Pleroma.Upload do
           ""
         end
 
-    [base_url, "media", path]
+    prefix =
+      if is_nil(Pleroma.Config.get([__MODULE__, :base_url])) do
+        "media"
+      else
+        ""
+      end
+
+    [base_url, prefix, path]
     |> Path.join()
   end