diff --git a/config/config.exs b/config/config.exs index 8b5c224ecf..683805fe34 100644 --- a/config/config.exs +++ b/config/config.exs @@ -931,12 +931,6 @@ config :pleroma, ConcurrentLimiter, [ config :pleroma, Pleroma.Web.WebFinger, domain: nil, update_nickname_on_user_fetch: true -config :pleroma, Pleroma.MultiLanguage, - template: "
{content}
", - separator: "


", - single_line_template: "[{code}] {content}", - single_line_separator: " | " - config :pleroma, Pleroma.Search, module: Pleroma.Search.DatabaseSearch config :pleroma, Pleroma.Search.Meilisearch, diff --git a/lib/pleroma/multi_language.ex b/lib/pleroma/multi_language.ex index 15c34832b5..ec0df0a44b 100644 --- a/lib/pleroma/multi_language.ex +++ b/lib/pleroma/multi_language.ex @@ -6,12 +6,6 @@ defmodule Pleroma.MultiLanguage do import Pleroma.EctoType.ActivityPub.ObjectValidators.LanguageCode, only: [good_locale_code?: 1] - defp template(:multi), do: Pleroma.Config.get([__MODULE__, :template]) - defp template(:single), do: Pleroma.Config.get([__MODULE__, :single_line_template]) - - defp sep(:multi), do: Pleroma.Config.get([__MODULE__, :separator]) - defp sep(:single), do: Pleroma.Config.get([__MODULE__, :single_line_separator]) - def validate_map(%{} = object) do {status, data} = object @@ -36,27 +30,6 @@ defmodule Pleroma.MultiLanguage do def validate_map(_), do: {:error, nil} - def map_to_str(data, opts \\ []) do - map_to_str_impl(data, if(opts[:multiline], do: :multi, else: :single)) - end - - defp map_to_str_impl(data, mode) do - with ks <- Map.keys(data), - [_, _ | _] <- ks, - ks <- Enum.sort(ks) do - template = template(mode) - - ks - |> Enum.map(fn lang -> - format_template(template, %{code: lang, content: data[lang]}) - end) - |> Enum.join(sep(mode)) - else - [lang] -> data[lang] - _ -> nil - end - end - def str_to_map(data, opts \\ []) do with lang when is_binary(lang) <- opts[:lang], true <- good_locale_code?(lang) do @@ -66,16 +39,4 @@ defmodule Pleroma.MultiLanguage do %{"und" => data} end end - - def format_template(template, %{code: code, content: content}) do - template - |> String.replace( - ["{code}", "{content}"], - fn - "{code}" -> code - "{content}" -> content - end, - global: true - ) - end end diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index c27c2b6470..2b419eea26 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -92,23 +92,23 @@ defmodule Pleroma.Upload do end 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]) + Enum.each(description, fn content -> + String.length(content) <= Pleroma.Config.get([:instance, :description_limit]) + end) 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 + defp description_fields(%{} = description, language) do %{ - "name" => Pleroma.MultiLanguage.map_to_str(description, multiline: false), + "name" => Map.get(description, language), "nameMap" => description } end - defp description_fields(description) when is_binary(description) do + defp description_fields(description, _language) when is_binary(description) do %{"name" => description} end @@ -122,6 +122,9 @@ defmodule Pleroma.Upload do {:ok, upload} <- Pleroma.Upload.Filter.filter(opts.filters, upload), description = get_description(upload), {_, true} <- {:description_limit, validate_description_limit(description)}, + {_, true} <- + {:valid_locale, + opts[:language] == nil or Pleroma.MultiLanguage.good_locale_code?(opts[:language])}, {:ok, url_spec} <- Pleroma.Uploaders.Uploader.put_file(opts.uploader, upload) do {:ok, %{ @@ -138,8 +141,9 @@ defmodule Pleroma.Upload do |> Maps.put_if_present("height", upload.height) ] } - |> Map.merge(description_fields(description)) - |> Maps.put_if_present("blurhash", upload.blurhash)} + |> Map.merge(description_fields(description, opts[:language])) + |> Maps.put_if_present("blurhash", upload.blurhash) + |> Maps.put_if_present("language", opts[:language])} else {:description_limit, _} -> {:error, :description_too_long} diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 784bd19069..26d6722a3c 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1562,27 +1562,36 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> Enum.reverse() end - defp validate_media_description_map(%{} = map) do - with {:ok, %{}} <- Pleroma.MultiLanguage.validate_map(map) do + defp validate_media_description_map(%{} = map, language) do + with {:ok, %{}} <- Pleroma.MultiLanguage.validate_map(map), + true <- Pleroma.MultiLanguage.good_locale_code?(language) do :ok else _ -> :error end end - defp validate_media_description_map(nil), do: :ok - defp validate_media_description_map(_), do: :error + defp validate_media_description_map(nil, _), do: :ok + defp validate_media_description_map(_, _), do: :error @spec upload(Upload.source(), keyword()) :: {:ok, Object.t()} | {:error, any()} def upload(file, opts \\ []) do - with {_, :ok} <- {:description_map, validate_media_description_map(opts[:description_map])}, + with {_, :ok} <- + {:description_map, + validate_media_description_map(opts[:description_map], opts[:language])}, {:ok, data} <- Upload.store(sanitize_upload_file(file), opts) do obj_data = Maps.put_if_present(data, "actor", opts[:actor]) Repo.insert(%Object{data: obj_data}) else - {:description_map, _} -> {:error, dgettext("errors", "description_map invalid")} - e -> e + {:description_map, :invalid_language} -> + {:error, dgettext("errors", "valid language must be provided with description_map")} + + {:description_map, _} -> + {:error, dgettext("errors", "description_map invalid")} + + e -> + e end end diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex index 695374104f..57029ae0ed 100644 --- a/lib/pleroma/web/activity_pub/builder.ex +++ b/lib/pleroma/web/activity_pub/builder.ex @@ -11,7 +11,6 @@ defmodule Pleroma.Web.ActivityPub.Builder do alias Pleroma.Activity alias Pleroma.Emoji - alias Pleroma.MultiLanguage alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.ActivityPub.Relay @@ -200,12 +199,12 @@ defmodule Pleroma.Web.ActivityPub.Builder do if draft.content_html_map do case Map.keys(draft.content_html_map) do ["und"] -> - %{"content" => MultiLanguage.map_to_str(draft.content_html_map, multiline: true)} + %{"content" => Map.get(draft.content_html_map, "und")} _ -> %{ "contentMap" => draft.content_html_map, - "content" => MultiLanguage.map_to_str(draft.content_html_map, multiline: true) + "content" => Map.get(draft.content_html_map, draft.language) } end else @@ -216,12 +215,12 @@ defmodule Pleroma.Web.ActivityPub.Builder do if draft.summary_map do case Map.keys(draft.summary_map) do ["und"] -> - %{"summary" => MultiLanguage.map_to_str(draft.summary_map, multiline: false)} + %{"summary" => Map.get(draft.summary_map, "und")} _ -> %{ "summaryMap" => draft.summary_map, - "summary" => MultiLanguage.map_to_str(draft.summary_map, multiline: false) + "summary" => Map.get(draft.summary_map, draft.language) } end else diff --git a/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex index 8ea61aec26..d0320ce497 100644 --- a/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex @@ -24,7 +24,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy do defp score_displayname("fedibot"), do: 1.0 defp score_displayname(_), do: 0.0 - defp determine_if_followbot(%User{nickname: nickname, name: displayname, actor_type: actor_type}) do + defp determine_if_followbot(%User{ + nickname: nickname, + name: displayname, + actor_type: actor_type + }) do # nickname will be a binary string except when following a relay nick_score = if is_binary(nickname) do diff --git a/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex b/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex index 96624a8efe..6e12873cc2 100644 --- a/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex +++ b/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex @@ -13,7 +13,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do def history_awareness, do: :auto def filter_by_summary( - %{data: %{"summaryMap" => %{} = parent_summary_map}} = _in_reply_to, + %{data: %{"summaryMap" => %{} = parent_summary_map} = parent} = _in_reply_to, %{"summaryMap" => %{} = child_summary_map} = child ) do fixed_summary_map = @@ -25,9 +25,16 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do end end) + fixed_summary = + with {:ok, fixed} <- fix_one(child["summary"], parent["summary"]) do + fixed + else + _ -> child["summary"] + end + child |> Map.put("summaryMap", fixed_summary_map) - |> Map.put("summary", Pleroma.MultiLanguage.map_to_str(fixed_summary_map, multiline: false)) + |> Map.put("summary", fixed_summary) end def filter_by_summary( diff --git a/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex b/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex index 4edc2e7b51..3d01772fe9 100644 --- a/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex +++ b/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex @@ -105,10 +105,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do object |> Map.put("contentMap", fixed_content_map) - |> Map.put( - "content", - Pleroma.MultiLanguage.map_to_str(fixed_content_map, multiline: true) - ) + |> Map.put("content", fix_content(object["content"] || "", mention_users)) else _ -> # image-only posts from pleroma apparently reach this MRF without the content field diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex index 7ede7d7027..e834bd2348 100644 --- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex @@ -88,16 +88,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do config = Pleroma.Config.get([:mrf_keyword, :replace]) replace_kw = fn object -> - [ - {"content", [multiline: true]}, - {"name", [multiline: false]}, - {"summary", [multiline: false]} - ] - |> Enum.filter(fn {field, _} -> + ["content", "name", "summary"] + |> Enum.filter(fn field -> is_map(object[field <> "Map"]) or (Map.has_key?(object, field) && object[field]) end) - |> Enum.reduce(object, fn {field, opts}, object -> + |> Enum.reduce(object, fn field, object -> field_name_map = field <> "Map" with %{} = data_map <- object[field_name_map] do @@ -108,7 +104,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do object |> Map.put(field_name_map, fixed_data_map) - |> Map.put(field, Pleroma.MultiLanguage.map_to_str(fixed_data_map, opts)) + |> Map.put(field, replace_keyword(object[field], config)) else _ -> data = replace_keyword(object[field], config) diff --git a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex index 534973bd89..93e056af76 100644 --- a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do def filter( %{ "type" => type, - "object" => %{"contentMap" => %{} = content_map, "attachment" => _} = _object + "object" => %{"contentMap" => %{} = content_map, "attachment" => _} = object } = activity ) when type in ["Create", "Update"] do @@ -28,6 +28,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do end end) + fixed_content = + if object["content"] in @placeholders do + "" + else + object["content"] + end + fixed_activity = if fixed_content_map == %{} do Map.put( @@ -40,10 +47,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do else activity |> put_in(["object", "contentMap"], fixed_content_map) - |> put_in( - ["object", "content"], - Pleroma.MultiLanguage.map_to_str(fixed_content_map, multiline: true) - ) + |> put_in(["object", "content"], fixed_content) end {:ok, fixed_activity} diff --git a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex index 2e8d83b11a..33ba3da2a1 100644 --- a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex +++ b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex @@ -25,10 +25,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do activity |> put_in(["object", "contentMap"], fixed_content_map) - |> put_in( - ["object", "content"], - Pleroma.MultiLanguage.map_to_str(fixed_content_map, multiline: true) - ) + |> put_in(["object", "content"], HTML.filter_tags(child_object["content"], scrub_policy)) else _ -> content = diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index a97e8db7b1..93f0616ec0 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -108,7 +108,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do end defp intersection(list1, list2) do - list1 -- list1 -- list2 + list1 -- (list1 -- list2) end defp check_followers_only(%{host: actor_host} = _actor_info, activity) do diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex index 3eb2a4d8fe..30844c60a9 100644 --- a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex @@ -92,9 +92,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do |> CommonFixes.fix_likes() |> Transmogrifier.fix_emoji() |> CommonFixes.maybe_add_language() - |> CommonFixes.fix_multilang_field("content", "contentMap", multiline: true) - |> CommonFixes.fix_multilang_field("summary", "summaryMap", multiline: false) - |> CommonFixes.fix_multilang_field("name", "nameMap", multiline: false) + |> CommonFixes.maybe_add_content_map() end def changeset(struct, data) do diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex index f6e1b2a9da..034c6f33fe 100644 --- a/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex @@ -103,9 +103,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioImageVideoValidator do |> CommonFixes.fix_likes() |> Transmogrifier.fix_emoji() |> fix_url() - |> CommonFixes.fix_multilang_field("content", "contentMap", multiline: true) - |> CommonFixes.fix_multilang_field("summary", "summaryMap", multiline: false) - |> CommonFixes.fix_multilang_field("name", "nameMap", multiline: false) |> fix_content() end diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex index 7da6c71f83..2e0f7a8a06 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex @@ -96,15 +96,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do Map.put(data, "to", to) end - def fix_multilang_field(data, str_field, map_field, opts \\ []) do - with %{} = map <- data[map_field], - str when is_binary(str) <- Pleroma.MultiLanguage.map_to_str(map, opts) do - Map.put(data, str_field, str) - else - _ -> data - end - end - def fix_quote_url(%{"quoteUrl" => _quote_url} = data), do: data # Fedibird diff --git a/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex index 6927cd71fc..b8e0518eed 100644 --- a/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex @@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator do import Ecto.Changeset alias Pleroma.EctoType.ActivityPub.ObjectValidators - alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes @primary_key false @@ -25,15 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator do field(:type, :string, default: "Note") end - defp fix(data) do - data - # name is used in Answers, so better not change it - |> CommonFixes.fix_multilang_field("nameRendered", "nameMap", multiline: false) - end - def changeset(struct, data) do - data = fix(data) - struct |> cast(data, [:name, :nameRendered, :nameMap, :type]) |> cast_embed(:replies, with: &replies_changeset/2) diff --git a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex index 0afa5bdf56..21940f4f16 100644 --- a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex @@ -67,9 +67,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do |> CommonFixes.fix_likes() |> Transmogrifier.fix_emoji() |> fix_closed() - |> CommonFixes.fix_multilang_field("content", "contentMap", multiline: true) - |> CommonFixes.fix_multilang_field("summary", "summaryMap", multiline: false) - |> CommonFixes.fix_multilang_field("name", "nameMap", multiline: false) end def changeset(struct, data) do diff --git a/lib/pleroma/web/api_spec/operations/media_operation.ex b/lib/pleroma/web/api_spec/operations/media_operation.ex index ceae57a372..4cc30a144b 100644 --- a/lib/pleroma/web/api_spec/operations/media_operation.ex +++ b/lib/pleroma/web/api_spec/operations/media_operation.ex @@ -52,6 +52,11 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do type: :string, description: "A plain-text description of the media, for accessibility purposes." }), + language: %Schema{ + type: :string, + nullable: true, + description: "ISO 639 language code for this status." + }, focus: %Schema{ type: :string, description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0." @@ -98,6 +103,11 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do type: :string, description: "A plain-text description of the media, for accessibility purposes." }), + language: %Schema{ + type: :string, + nullable: true, + description: "ISO 639 language code for this status." + }, focus: %Schema{ type: :string, description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0." diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex index 890321923a..e81320cee8 100644 --- a/lib/pleroma/web/common_api/activity_draft.ex +++ b/lib/pleroma/web/common_api/activity_draft.ex @@ -345,7 +345,10 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do add_error(draft, dgettext("errors", "valid language is required when using status_map")) true -> - %__MODULE__{draft | language: LanguageDetector.detect(draft.content_html <> " " <> draft.summary || "")} + %__MODULE__{ + draft + | language: LanguageDetector.detect(draft.content_html <> " " <> draft.summary || "") + } end end @@ -436,9 +439,9 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do defp differentiate_string_map(%{} = map), do: {nil, map} defp differentiate_string_map(str) when is_binary(str), do: {str, nil} - defp get_source_map(%{status_map: %{} = status_map} = _draft) do + defp get_source_map(%{status_map: %{} = status_map} = draft) do %{ - "content" => Pleroma.MultiLanguage.map_to_str(status_map, mutiline: true), + "content" => Map.get(status_map, draft.language), "contentMap" => status_map } end diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 1702388715..617826e818 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -165,7 +165,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do %{"name" => option["und"]} else %{ - "name" => MultiLanguage.map_to_str(option, multiline: false), + "name" => Map.get(option, data.language), "nameMap" => option } end diff --git a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex index 7a8d831267..88922df2e2 100644 --- a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex @@ -25,17 +25,25 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do conn, _ ) do - with {:ok, object} <- + with language <- Map.get(data, :language), + {_, true} <- + {:valid_locale, + Map.get(data, :description_map) == nil or MultiLanguage.good_locale_code?(language)}, + {:ok, object} <- ActivityPub.upload( file, actor: User.ap_id(user), description: Map.get(data, :description), - description_map: Map.get(data, :description_map) + description_map: Map.get(data, :description_map), + language: language ) do attachment_data = Map.put(object.data, "id", object.id) render(conn, "attachment.json", %{attachment: attachment_data}) else + {:valid_locale, _} -> + render_error(conn, 422, "valid language must be provided with description_map") + {:error, e} -> conn |> put_status(:unprocessable_entity) @@ -51,17 +59,25 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do conn, _ ) do - with {:ok, object} <- + with language <- Map.get(data, :language), + {_, true} <- + {:valid_locale, + Map.get(data, :description_map) == nil or MultiLanguage.good_locale_code?(language)}, + {:ok, object} <- ActivityPub.upload( file, actor: User.ap_id(user), description: Map.get(data, :description), - description_map: Map.get(data, :description_map) + description_map: Map.get(data, :description_map), + language: language ) do attachment_data = Map.put(object.data, "id", object.id) render(conn, "attachment.json", %{attachment: attachment_data}) else + {:valid_locale, _} -> + render_error(conn, 422, "valid language must be provided with description_map") + {:error, e} -> conn |> put_status(:unprocessable_entity) @@ -76,25 +92,34 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do %{ assigns: %{user: user}, private: %{ - open_api_spex: %{body_params: %{description_map: description_map}, params: %{id: id}} + open_api_spex: %{ + body_params: %{description_map: description_map} = body_params, + params: %{id: id} + } } } = conn, _ ) do with %Object{} = object <- Object.get_by_id(id), :ok <- Object.authorize_access(object, user), - {_, {:ok, %{}}} <- - {:description_map, Pleroma.MultiLanguage.validate_map(description_map)}, + language = Map.get(body_params, :language, object["language"]), + {_, true} <- + {:valid_locale, description_map == nil or MultiLanguage.good_locale_code?(language)}, + {_, {:ok, %{}}} <- {:description_map, MultiLanguage.validate_map(description_map)}, {:ok, %Object{data: data}} <- Object.update_data(object, %{ - "name" => Pleroma.MultiLanguage.map_to_str(description_map), + "name" => Map.get(description_map, language), "nameMap" => description_map }) do attachment_data = Map.put(data, "id", object.id) render(conn, "attachment.json", %{attachment: attachment_data}) else - {:description_map, _} -> render_error(conn, 422, "description_map not valid") + {:valid_locale, _} -> + render_error(conn, 422, "valid language must be provided with description_map") + + {:description_map, _} -> + render_error(conn, 422, "description_map not valid") end end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 936b518f7e..0d63625891 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -689,7 +689,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do %{ancestors: ancestors, descendants: descendants} = activities |> Enum.reverse() - |> Enum.group_by(fn %{id: id} -> if id < activity.id, do: :ancestors, else: :descendants end) + |> Enum.group_by(fn %{id: id} -> + if id < activity.id, do: :ancestors, else: :descendants + end) |> Map.put_new(:ancestors, []) |> Map.put_new(:descendants, []) diff --git a/lib/pleroma/workers/mailer_worker.ex b/lib/pleroma/workers/mailer_worker.ex index b0259b1917..9ef6a80c9d 100644 --- a/lib/pleroma/workers/mailer_worker.ex +++ b/lib/pleroma/workers/mailer_worker.ex @@ -6,7 +6,9 @@ defmodule Pleroma.Workers.MailerWorker do use Oban.Worker, queue: :background @impl true - def perform(%Job{args: %{"op" => "email", "encoded_email" => encoded_email, "config" => config}}) do + def perform(%Job{ + args: %{"op" => "email", "encoded_email" => encoded_email, "config" => config} + }) do encoded_email |> Base.decode64!() |> :erlang.binary_to_term() diff --git a/test/pleroma/multi_language_test.exs b/test/pleroma/multi_language_test.exs index aea25f1170..3db87be65f 100644 --- a/test/pleroma/multi_language_test.exs +++ b/test/pleroma/multi_language_test.exs @@ -7,42 +7,6 @@ defmodule Pleroma.MultiLanguageTest do alias Pleroma.MultiLanguage - describe "map_to_str" do - setup do - %{ - data: %{ - "en-US" => "mew", - "en-GB" => "meow" - } - } - end - - test "single line", %{data: data} do - assert MultiLanguage.map_to_str(data) == "[en-GB] meow | [en-US] mew" - end - - test "multi line", %{data: data} do - assert MultiLanguage.map_to_str(data, multiline: true) == - "
meow



mew
" - end - - test "only one language" do - data = %{"some" => "foo"} - assert MultiLanguage.map_to_str(data) == "foo" - assert MultiLanguage.map_to_str(data, multiline: true) == "foo" - end - - test "resistent to tampering" do - data = %{ - "en-US" => "mew {code} {content}", - "en-GB" => "meow {code} {content}" - } - - assert MultiLanguage.map_to_str(data) == - "[en-GB] meow {code} {content} | [en-US] mew {code} {content}" - end - end - describe "str_to_map" do test "" do assert MultiLanguage.str_to_map("foo") == %{"und" => "foo"} diff --git a/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs index 95abb188e3..f56e0faf37 100644 --- a/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs +++ b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs @@ -56,8 +56,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do "c" => "another-object-summary" } - assert res["object"]["summary"] == - Pleroma.MultiLanguage.map_to_str(res["object"]["summaryMap"], multiline: false) + assert res["object"]["summary"] == "re: object-summary" end test "it adds `re:` to summary object when child summary contains re-subject of parent summary " do diff --git a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs index 7eb8d51632..cbb0078765 100644 --- a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs +++ b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs @@ -16,7 +16,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do test "adds mentions to post content" do [lain, coolboymew, dielan, hakui, fence] = [ - insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain@lain.com", local: false), + insert(:user, + ap_id: "https://lain.com/users/lain", + nickname: "lain@lain.com", + local: false + ), insert(:user, ap_id: "https://shitposter.club/users/coolboymew", nickname: "coolboymew@shitposter.club", @@ -123,11 +127,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do %{ "object" => %{ "content" => content, - "contentMap" => - %{ - "a" => content_a, - "b" => content_b - } = content_map + "contentMap" => %{ + "a" => content_a, + "b" => content_b + } } }} = ForceMentionsInContent.filter(activity) @@ -136,7 +139,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do assert content_a == mentions_part <> "mew mew" assert content_b == mentions_part <> "lol lol" - assert content == Pleroma.MultiLanguage.map_to_str(content_map, multiline: true) + assert content == mentions_part <> "WHA-HA!" end test "don't mention self" do diff --git a/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs b/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs index a40d5374c5..65a1840328 100644 --- a/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs @@ -318,23 +318,16 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do {:ok, %{ "object" => %{ - "content" => content, - "contentMap" => - %{ - "a" => "ZFS is free software", - "b" => "mew mew is also free software" - } = content_map, - "summary" => summary, - "summaryMap" => - %{ - "a" => "ZFS is very free software", - "b" => "mew mew is also very free software" - } = summary_map + "contentMap" => %{ + "a" => "ZFS is free software", + "b" => "mew mew is also free software" + }, + "summaryMap" => %{ + "a" => "ZFS is very free software", + "b" => "mew mew is also very free software" + } } }} = KeywordPolicy.filter(message) - - assert content == Pleroma.MultiLanguage.map_to_str(content_map, multiline: true) - assert summary == Pleroma.MultiLanguage.map_to_str(summary_map, multiline: false) end test "replaces keyword if string matches in history" do diff --git a/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs index 6fb5e656da..cf7a3bce19 100644 --- a/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs @@ -32,7 +32,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do } assert {:ok, res} = NoPlaceholderTextPolicy.filter(message) - assert res["object"]["content"] == "lol" + assert res["object"]["content"] == "" assert res["object"]["contentMap"] == %{"b" => "lol"} message = %{ diff --git a/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs index c9ae343372..0331ce613d 100644 --- a/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs +++ b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs @@ -49,8 +49,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do assert {:ok, res} = NormalizeMarkup.filter(message) assert res["object"]["contentMap"] == %{"a" => @expected, "b" => @expected} - assert res["object"]["content"] == - Pleroma.MultiLanguage.map_to_str(res["object"]["contentMap"], multiline: true) + assert res["object"]["content"] == "some" end test "history-aware" do diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs index 74971e6cae..afc6cd47a1 100644 --- a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs @@ -75,14 +75,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest |> Map.put("summaryMap", summary_map) |> Map.put("contentMap", content_map) - expected_summary = Pleroma.MultiLanguage.map_to_str(summary_map, multiline: false) - expected_content = Pleroma.MultiLanguage.map_to_str(content_map, multiline: true) - assert %{ valid?: true, changes: %{ - summary: ^expected_summary, - content: ^expected_content, summaryMap: ^summary_map, contentMap: ^content_map } diff --git a/test/pleroma/web/common_api/activity_draft_test.exs b/test/pleroma/web/common_api/activity_draft_test.exs index 834f5cd173..2257afe0da 100644 --- a/test/pleroma/web/common_api/activity_draft_test.exs +++ b/test/pleroma/web/common_api/activity_draft_test.exs @@ -59,6 +59,5 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraftTest do {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quoted_status_id: local.id}) {:ok, _} = ActivityDraft.create(user, %{status: "nice", quoted_status_id: public.id}) {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quoted_status_id: public.id}) ->>>>>>> origin/develop end end