Accept multilang descriptions when uploading attachments

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
tusooa 2023-01-03 02:31:23 -05:00 committed by marcin mikołajczak
parent 7222cebdb6
commit 4d2813ae41
5 changed files with 90 additions and 11 deletions

View file

@ -62,6 +62,7 @@ defmodule Pleroma.Upload do
height: integer(),
blurhash: String.t(),
description: String.t(),
description_map: map(),
path: String.t()
}
defstruct [
@ -73,21 +74,44 @@ defmodule Pleroma.Upload do
:height,
:blurhash,
:description,
:description_map,
:path
]
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
defp get_description(upload) do
case {upload.description, Pleroma.Config.get([Pleroma.Upload, :default_description])} do
{description, _} when is_binary(description) -> description
case {upload, Pleroma.Config.get([Pleroma.Upload, :default_description])} do
{%{description_map: %{} = description_map}, _} -> description_map
{%{description: description}, _} when is_binary(description) -> description
{_, :filename} -> upload.name
{_, str} when is_binary(str) -> str
_ -> ""
end
end
@spec store(source, options :: [option()]) :: {:ok, map()} | {:error, any()}
defp validate_description_limit(%{} = description) do
len = Enum.reduce(description, 0, fn {_, content}, acc -> String.length(content) + acc end)
len <= Pleroma.Config.get([:instance, :description_limit])
end
defp validate_description_limit(description) when is_binary(description) do
String.length(description) <= Pleroma.Config.get([:instance, :description_limit])
end
defp description_fields(%{} = description) do
%{
"name" => Pleroma.MultiLanguage.map_to_str(description, multiline: false),
"nameMap" => description
}
end
defp description_fields(description) when is_binary(description) do
%{"name" => description}
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
opts = get_opts(opts)
@ -96,9 +120,7 @@ def store(upload, opts \\ []) do
upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"},
{:ok, upload} <- Pleroma.Upload.Filter.filter(opts.filters, upload),
description = get_description(upload),
{_, true} <-
{:description_limit,
String.length(description) <= Pleroma.Config.get([:instance, :description_limit])},
{_, true} <- {:description_limit, validate_description_limit(description)},
{:ok, url_spec} <- Pleroma.Uploaders.Uploader.put_file(opts.uploader, upload) do
{:ok,
%{
@ -113,9 +135,9 @@ def store(upload, opts \\ []) do
}
|> Maps.put_if_present("width", upload.width)
|> Maps.put_if_present("height", upload.height)
],
"name" => description
]
}
|> Map.merge(description_fields(description))
|> Maps.put_if_present("blurhash", upload.blurhash)}
else
{:description_limit, _} ->
@ -156,6 +178,7 @@ defp get_opts(opts) do
uploader: Keyword.get(opts, :uploader, Pleroma.Config.get([__MODULE__, :uploader])),
filters: Keyword.get(opts, :filters, Pleroma.Config.get([__MODULE__, :filters])),
description: Keyword.get(opts, :description),
description_map: Keyword.get(opts, :description_map),
base_url: base_url()
}
end
@ -168,7 +191,8 @@ defp prepare_upload(%Plug.Upload{} = file, opts) do
name: file.filename,
tempfile: file.path,
content_type: file.content_type,
description: opts.description
description: opts.description,
description_map: opts.description_map
}}
end
end

View file

@ -47,6 +47,11 @@ defp create_request do
type: :string,
description: "A plain-text description of the media, for accessibility purposes."
},
description_map:
Helpers.multilang_map_of(%Schema{
type: :string,
description: "A plain-text description of the media, for accessibility purposes."
}),
focus: %Schema{
type: :string,
description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0."
@ -88,6 +93,11 @@ defp update_request do
type: :string,
description: "A plain-text description of the media, for accessibility purposes."
},
description_map:
Helpers.multilang_map_of(%Schema{
type: :string,
description: "A plain-text description of the media, for accessibility purposes."
}),
focus: %Schema{
type: :string,
description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0."

View file

@ -28,7 +28,8 @@ def create(
ActivityPub.upload(
file,
actor: user.ap_id,
description: Map.get(data, :description)
description: Map.get(data, :description),
description_map: Map.get(data, :description_map)
) do
attachment_data = Map.put(object.data, "id", object.id)
@ -48,7 +49,8 @@ def create2(
ActivityPub.upload(
file,
actor: user.ap_id,
description: Map.get(data, :description)
description: Map.get(data, :description),
description_map: Map.get(data, :description_map)
) do
attachment_data = Map.put(object.data, "id", object.id)

View file

@ -1410,6 +1410,13 @@ test "sets a description if given", %{test_file: file} do
assert object.data["name"] == "a cool file"
end
test "sets a multilang description if given", %{test_file: file} do
{:ok, %Object{} = object} =
ActivityPub.upload(file, description_map: %{"a" => "mew", "b" => "lol"})
assert object.data["nameMap"] == %{"a" => "mew", "b" => "lol"}
end
test "it sets the default description depending on the configuration", %{test_file: file} do
clear_config([Pleroma.Upload, :default_description])

View file

@ -49,6 +49,24 @@ test "/api/v1/media", %{conn: conn, image: image} do
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
end
test "/api/v1/media, multilang", %{conn: conn, image: image} do
media =
conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/v1/media", %{
"file" => image,
"description_map" => %{"a" => "mew", "b" => "lol"}
})
|> json_response_and_validate_schema(:ok)
assert media["type"] == "image"
assert media["description_map"] == %{"a" => "mew", "b" => "lol"}
assert media["id"]
object = Object.get_by_id(media["id"])
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
end
test "/api/v2/media", %{conn: conn, user: user, image: image} do
desc = "Description of the image"
@ -75,6 +93,24 @@ test "/api/v2/media", %{conn: conn, user: user, image: image} do
assert object.data["actor"] == user.ap_id
end
test "/api/v2/media, multilang", %{conn: conn, image: image} do
media =
conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/v2/media", %{
"file" => image,
"description_map" => %{"a" => "mew", "b" => "lol"}
})
|> json_response_and_validate_schema(202)
assert media["type"] == "image"
assert media["description_map"] == %{"a" => "mew", "b" => "lol"}
assert media["id"]
object = Object.get_by_id(media["id"])
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
end
test "/api/v2/media, upload_limit", %{conn: conn, user: user} do
desc = "Description of the binary"