From f86bf164300b7311160660970469efad5cfed3df Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Mon, 2 Jan 2023 02:15:38 +0000 Subject: [PATCH 1/6] Add language support on /api/v1/statuses --- lib/pleroma/iso639.ex | 11 +++++++++++ .../article_note_page_validator.ex | 16 ++++++++++++++++ lib/pleroma/web/common_api/activity_draft.ex | 15 +++++++++++++++ .../web/mastodon_api/views/status_view.ex | 14 ++++++++++++-- priv/language-codes.json | 1 + .../controllers/status_controller_test.exs | 12 +++++++++--- 6 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 lib/pleroma/iso639.ex create mode 100644 priv/language-codes.json diff --git a/lib/pleroma/iso639.ex b/lib/pleroma/iso639.ex new file mode 100644 index 000000000..a80fab7e9 --- /dev/null +++ b/lib/pleroma/iso639.ex @@ -0,0 +1,11 @@ +defmodule Pleroma.ISO639 do + @file "priv/language-codes.json" + @data File.read!(@file) + |> Jason.decode!() + + for %{"alpha2" => alpha2} <- @data do + def valid_alpha2?(unquote(alpha2)), do: true + end + + def valid_alpha2?(_alpha2), do: false +end 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 0d45421e2..1bdf2a950 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 @@ -30,6 +30,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do field(:replies, {:array, ObjectValidators.ObjectID}, default: []) field(:source, :map) + field(:content_map, :map) end def cast_and_apply(data) do @@ -146,6 +147,20 @@ defp fix_source(%{"source" => source} = object) when is_binary(source) do defp fix_source(object), do: object + defp fix_content_map_languages(%{"contentMap" => content_map} = object) + when is_map(content_map) do + # Only allow valid languages + content_map = + content_map + |> Enum.reject(fn {lang, content} -> + !Pleroma.ISO639.valid_alpha2?(lang) + end) + + Map.put(object, "contentMap", content_map) + end + + defp fix_content_map_languages(object), do: object + defp fix(data) do data |> CommonFixes.fix_actor() @@ -158,6 +173,7 @@ defp fix(data) do |> Transmogrifier.fix_attachments() |> Transmogrifier.fix_emoji() |> Transmogrifier.fix_content_map() + |> fix_content_map_languages() end def changeset(struct, data) do diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex index 8b0eaaadf..adddea669 100644 --- a/lib/pleroma/web/common_api/activity_draft.ex +++ b/lib/pleroma/web/common_api/activity_draft.ex @@ -22,6 +22,8 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do attachments: [], in_reply_to: nil, in_reply_to_conversation: nil, + language: nil, + content_map: %{}, quote_id: nil, quote: nil, visibility: nil, @@ -58,6 +60,7 @@ def create(user, params) do |> with_valid(&visibility/1) |> with_valid("e_id/1) |> content() + |> with_valid(&language/1) |> with_valid(&to_and_cc/1) |> with_valid(&context/1) |> sensitive() @@ -133,6 +136,17 @@ defp quote_id(%{params: %{quote_id: %Activity{} = quote}} = draft) do defp quote_id(draft), do: draft + defp language(%{params: %{language: language}, content_html: content} = draft) + when is_binary(language) do + if Pleroma.ISO639.valid_alpha2?(language) do + %__MODULE__{draft | content_map: %{language => content}} + else + add_error(draft, dgettext("errors", "Invalid language")) + end + end + + defp language(draft), do: draft + defp visibility(%{params: params} = draft) do case CommonAPI.get_visibility(params, draft.in_reply_to, draft.in_reply_to_conversation) do {visibility, "direct"} when visibility != "direct" -> @@ -224,6 +238,7 @@ defp object(draft) do "mediaType" => Utils.get_content_type(draft.params[:content_type]) }) |> Map.put("generator", draft.params[:generator]) + |> Map.put("contentMap", draft.content_map) %__MODULE__{draft | object: object} end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index b9a7e57f5..48756e78b 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -169,6 +169,7 @@ def render( |> Enum.map(fn user -> AccountView.render("mention.json", %{user: user}) end) {pinned?, pinned_at} = pin_data(object, user) + lang = language(object) %{ id: to_string(activity.id), @@ -199,7 +200,7 @@ def render( mentions: mentions, tags: reblogged[:tags] || [], application: build_application(object.data["generator"]), - language: nil, + language: lang, emojis: [], pleroma: %{ local: activity.local, @@ -357,6 +358,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} {pinned?, pinned_at} = pin_data(object, user) quote = Activity.get_quoted_activity_from_object(object) + lang = language(object) %{ id: to_string(activity.id), @@ -391,7 +393,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} mentions: mentions, tags: build_tags(tags), application: build_application(object.data["generator"]), - language: nil, + language: lang, emojis: build_emojis(object.data["emoji"]), quote_id: if(quote, do: quote.id, else: nil), quote: maybe_render_quote(quote, opts), @@ -784,4 +786,12 @@ defp get_source_content_type(%{"mediaType" => type} = _source) do defp get_source_content_type(_source) do Utils.get_content_type(nil) end + + defp language(%Object{data: %{"contentMap" => contentMap}}) when is_map(contentMap) do + contentMap + |> Map.keys() + |> Enum.at(0) + end + + defp language(_), do: nil end diff --git a/priv/language-codes.json b/priv/language-codes.json new file mode 100644 index 000000000..dda9a2b75 --- /dev/null +++ b/priv/language-codes.json @@ -0,0 +1 @@ +[{"English": "Afar", "alpha2": "aa"},{"English": "Abkhazian", "alpha2": "ab"},{"English": "Avestan", "alpha2": "ae"},{"English": "Afrikaans", "alpha2": "af"},{"English": "Akan", "alpha2": "ak"},{"English": "Amharic", "alpha2": "am"},{"English": "Aragonese", "alpha2": "an"},{"English": "Arabic", "alpha2": "ar"},{"English": "Assamese", "alpha2": "as"},{"English": "Avaric", "alpha2": "av"},{"English": "Aymara", "alpha2": "ay"},{"English": "Azerbaijani", "alpha2": "az"},{"English": "Bashkir", "alpha2": "ba"},{"English": "Belarusian", "alpha2": "be"},{"English": "Bulgarian", "alpha2": "bg"},{"English": "Bihari languages", "alpha2": "bh"},{"English": "Bislama", "alpha2": "bi"},{"English": "Bambara", "alpha2": "bm"},{"English": "Bengali", "alpha2": "bn"},{"English": "Tibetan", "alpha2": "bo"},{"English": "Breton", "alpha2": "br"},{"English": "Bosnian", "alpha2": "bs"},{"English": "Catalan; Valencian", "alpha2": "ca"},{"English": "Chechen", "alpha2": "ce"},{"English": "Chamorro", "alpha2": "ch"},{"English": "Corsican", "alpha2": "co"},{"English": "Cree", "alpha2": "cr"},{"English": "Czech", "alpha2": "cs"},{"English": "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic", "alpha2": "cu"},{"English": "Chuvash", "alpha2": "cv"},{"English": "Welsh", "alpha2": "cy"},{"English": "Danish", "alpha2": "da"},{"English": "German", "alpha2": "de"},{"English": "Divehi; Dhivehi; Maldivian", "alpha2": "dv"},{"English": "Dzongkha", "alpha2": "dz"},{"English": "Ewe", "alpha2": "ee"},{"English": "Greek, Modern (1453-)", "alpha2": "el"},{"English": "English", "alpha2": "en"},{"English": "Esperanto", "alpha2": "eo"},{"English": "Spanish; Castilian", "alpha2": "es"},{"English": "Estonian", "alpha2": "et"},{"English": "Basque", "alpha2": "eu"},{"English": "Persian", "alpha2": "fa"},{"English": "Fulah", "alpha2": "ff"},{"English": "Finnish", "alpha2": "fi"},{"English": "Fijian", "alpha2": "fj"},{"English": "Faroese", "alpha2": "fo"},{"English": "French", "alpha2": "fr"},{"English": "Western Frisian", "alpha2": "fy"},{"English": "Irish", "alpha2": "ga"},{"English": "Gaelic; Scottish Gaelic", "alpha2": "gd"},{"English": "Galician", "alpha2": "gl"},{"English": "Guarani", "alpha2": "gn"},{"English": "Gujarati", "alpha2": "gu"},{"English": "Manx", "alpha2": "gv"},{"English": "Hausa", "alpha2": "ha"},{"English": "Hebrew", "alpha2": "he"},{"English": "Hindi", "alpha2": "hi"},{"English": "Hiri Motu", "alpha2": "ho"},{"English": "Croatian", "alpha2": "hr"},{"English": "Haitian; Haitian Creole", "alpha2": "ht"},{"English": "Hungarian", "alpha2": "hu"},{"English": "Armenian", "alpha2": "hy"},{"English": "Herero", "alpha2": "hz"},{"English": "Interlingua (International Auxiliary Language Association)", "alpha2": "ia"},{"English": "Indonesian", "alpha2": "id"},{"English": "Interlingue; Occidental", "alpha2": "ie"},{"English": "Igbo", "alpha2": "ig"},{"English": "Sichuan Yi; Nuosu", "alpha2": "ii"},{"English": "Inupiaq", "alpha2": "ik"},{"English": "Ido", "alpha2": "io"},{"English": "Icelandic", "alpha2": "is"},{"English": "Italian", "alpha2": "it"},{"English": "Inuktitut", "alpha2": "iu"},{"English": "Japanese", "alpha2": "ja"},{"English": "Javanese", "alpha2": "jv"},{"English": "Georgian", "alpha2": "ka"},{"English": "Kongo", "alpha2": "kg"},{"English": "Kikuyu; Gikuyu", "alpha2": "ki"},{"English": "Kuanyama; Kwanyama", "alpha2": "kj"},{"English": "Kazakh", "alpha2": "kk"},{"English": "Kalaallisut; Greenlandic", "alpha2": "kl"},{"English": "Central Khmer", "alpha2": "km"},{"English": "Kannada", "alpha2": "kn"},{"English": "Korean", "alpha2": "ko"},{"English": "Kanuri", "alpha2": "kr"},{"English": "Kashmiri", "alpha2": "ks"},{"English": "Kurdish", "alpha2": "ku"},{"English": "Komi", "alpha2": "kv"},{"English": "Cornish", "alpha2": "kw"},{"English": "Kirghiz; Kyrgyz", "alpha2": "ky"},{"English": "Latin", "alpha2": "la"},{"English": "Luxembourgish; Letzeburgesch", "alpha2": "lb"},{"English": "Ganda", "alpha2": "lg"},{"English": "Limburgan; Limburger; Limburgish", "alpha2": "li"},{"English": "Lingala", "alpha2": "ln"},{"English": "Lao", "alpha2": "lo"},{"English": "Lithuanian", "alpha2": "lt"},{"English": "Luba-Katanga", "alpha2": "lu"},{"English": "Latvian", "alpha2": "lv"},{"English": "Malagasy", "alpha2": "mg"},{"English": "Marshallese", "alpha2": "mh"},{"English": "Maori", "alpha2": "mi"},{"English": "Macedonian", "alpha2": "mk"},{"English": "Malayalam", "alpha2": "ml"},{"English": "Mongolian", "alpha2": "mn"},{"English": "Marathi", "alpha2": "mr"},{"English": "Malay", "alpha2": "ms"},{"English": "Maltese", "alpha2": "mt"},{"English": "Burmese", "alpha2": "my"},{"English": "Nauru", "alpha2": "na"},{"English": "Bokm\u00e5l, Norwegian; Norwegian Bokm\u00e5l", "alpha2": "nb"},{"English": "Ndebele, North; North Ndebele", "alpha2": "nd"},{"English": "Nepali", "alpha2": "ne"},{"English": "Ndonga", "alpha2": "ng"},{"English": "Dutch; Flemish", "alpha2": "nl"},{"English": "Norwegian Nynorsk; Nynorsk, Norwegian", "alpha2": "nn"},{"English": "Norwegian", "alpha2": "no"},{"English": "Ndebele, South; South Ndebele", "alpha2": "nr"},{"English": "Navajo; Navaho", "alpha2": "nv"},{"English": "Chichewa; Chewa; Nyanja", "alpha2": "ny"},{"English": "Occitan (post 1500)", "alpha2": "oc"},{"English": "Ojibwa", "alpha2": "oj"},{"English": "Oromo", "alpha2": "om"},{"English": "Oriya", "alpha2": "or"},{"English": "Ossetian; Ossetic", "alpha2": "os"},{"English": "Panjabi; Punjabi", "alpha2": "pa"},{"English": "Pali", "alpha2": "pi"},{"English": "Polish", "alpha2": "pl"},{"English": "Pushto; Pashto", "alpha2": "ps"},{"English": "Portuguese", "alpha2": "pt"},{"English": "Quechua", "alpha2": "qu"},{"English": "Romansh", "alpha2": "rm"},{"English": "Rundi", "alpha2": "rn"},{"English": "Romanian; Moldavian; Moldovan", "alpha2": "ro"},{"English": "Russian", "alpha2": "ru"},{"English": "Kinyarwanda", "alpha2": "rw"},{"English": "Sanskrit", "alpha2": "sa"},{"English": "Sardinian", "alpha2": "sc"},{"English": "Sindhi", "alpha2": "sd"},{"English": "Northern Sami", "alpha2": "se"},{"English": "Sango", "alpha2": "sg"},{"English": "Sinhala; Sinhalese", "alpha2": "si"},{"English": "Slovak", "alpha2": "sk"},{"English": "Slovenian", "alpha2": "sl"},{"English": "Samoan", "alpha2": "sm"},{"English": "Shona", "alpha2": "sn"},{"English": "Somali", "alpha2": "so"},{"English": "Albanian", "alpha2": "sq"},{"English": "Serbian", "alpha2": "sr"},{"English": "Swati", "alpha2": "ss"},{"English": "Sotho, Southern", "alpha2": "st"},{"English": "Sundanese", "alpha2": "su"},{"English": "Swedish", "alpha2": "sv"},{"English": "Swahili", "alpha2": "sw"},{"English": "Tamil", "alpha2": "ta"},{"English": "Telugu", "alpha2": "te"},{"English": "Tajik", "alpha2": "tg"},{"English": "Thai", "alpha2": "th"},{"English": "Tigrinya", "alpha2": "ti"},{"English": "Turkmen", "alpha2": "tk"},{"English": "Tagalog", "alpha2": "tl"},{"English": "Tswana", "alpha2": "tn"},{"English": "Tonga (Tonga Islands)", "alpha2": "to"},{"English": "Turkish", "alpha2": "tr"},{"English": "Tsonga", "alpha2": "ts"},{"English": "Tatar", "alpha2": "tt"},{"English": "Twi", "alpha2": "tw"},{"English": "Tahitian", "alpha2": "ty"},{"English": "Uighur; Uyghur", "alpha2": "ug"},{"English": "Ukrainian", "alpha2": "uk"},{"English": "Urdu", "alpha2": "ur"},{"English": "Uzbek", "alpha2": "uz"},{"English": "Venda", "alpha2": "ve"},{"English": "Vietnamese", "alpha2": "vi"},{"English": "Volap\u00fck", "alpha2": "vo"},{"English": "Walloon", "alpha2": "wa"},{"English": "Wolof", "alpha2": "wo"},{"English": "Xhosa", "alpha2": "xh"},{"English": "Yiddish", "alpha2": "yi"},{"English": "Yoruba", "alpha2": "yo"},{"English": "Zhuang; Chuang", "alpha2": "za"},{"English": "Chinese", "alpha2": "zh"},{"English": "Zulu", "alpha2": "zu"}] \ No newline at end of file diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index 45da22d91..d964340cb 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -67,11 +67,17 @@ test "posting a status", %{conn: conn} do |> post("/api/v1/statuses", %{ "status" => "cofe", "spoiler_text" => "2hu", - "sensitive" => "0" + "sensitive" => "0", + "language" => "ja" }) - assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} = - json_response_and_validate_schema(conn_one, 200) + assert %{ + "content" => "cofe", + "id" => id, + "spoiler_text" => "2hu", + "sensitive" => false, + "language" => "ja" + } = json_response_and_validate_schema(conn_one, 200) assert Activity.get_by_id(id) From cc63a89b5d81f11f3c0dc1cc4130ac6f20cbe260 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Mon, 2 Jan 2023 02:41:56 +0000 Subject: [PATCH 2/6] Fix tests --- lib/pleroma/web/activity_pub/transmogrifier.ex | 11 ++++++++--- .../controllers/status_controller_test.exs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 77015241b..2ff0e8a74 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -346,11 +346,16 @@ def fix_tag(%{"tag" => %{} = tag} = object) do def fix_tag(object), do: object # content map usually only has one language so this will do for now. - def fix_content_map(%{"contentMap" => content_map} = object) do + def fix_content_map(%{"contentMap" => content_map} = object) when is_map(content_map) do content_groups = Map.to_list(content_map) - {_, content} = Enum.at(content_groups, 0) - Map.put(object, "content", content) + if Enum.empty?(content_groups) do + object + else + {_, content} = Enum.at(content_groups, 0) + + Map.put(object, "content", content) + end end def fix_content_map(object), do: object diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index d964340cb..6f04975b8 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -219,6 +219,18 @@ test "posting an undefined status with an attachment", %{user: user, conn: conn} assert json_response_and_validate_schema(conn, 200) end + test "posting a status with an invalid language", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ + "status" => "cofe", + "language" => "invalid" + }) + + assert %{"error" => "Invalid language"} = json_response_and_validate_schema(conn, 422) + end + test "replying to a status", %{user: user, conn: conn} do {:ok, replied_to} = CommonAPI.post(user, %{status: "cofe"}) From 7eebaa7a18f576476d56dd7415bc0fcbd19120c3 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 10 Jan 2023 10:48:14 +0000 Subject: [PATCH 3/6] bump mock --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 2a62dedee..93184a0f9 100644 --- a/mix.exs +++ b/mix.exs @@ -200,7 +200,7 @@ defp deps do ref: "1c1b99ea41a457761383d81aaf6a606913996fe7", only: [:dev, :test], runtime: false}, - {:mock, "~> 0.3.5", only: :test}, + {:mock, "~> 0.3.7", only: :test}, {:excoveralls, "0.15.1", only: :test}, {:mox, "~> 1.0", only: :test}, {:websockex, "~> 0.4.3", only: :test}, From 22068f08539b20d69056899c817485a2136a93c3 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 10 Jan 2023 10:58:17 +0000 Subject: [PATCH 4/6] fix unused variable warnings --- .../article_note_page_validator.ex | 2 +- lib/pleroma/web/rel_me.ex | 2 +- mix.lock | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) 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 1bdf2a950..056c48f86 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 @@ -152,7 +152,7 @@ defp fix_content_map_languages(%{"contentMap" => content_map} = object) # Only allow valid languages content_map = content_map - |> Enum.reject(fn {lang, content} -> + |> Enum.reject(fn {lang, _content} -> !Pleroma.ISO639.valid_alpha2?(lang) end) diff --git a/lib/pleroma/web/rel_me.ex b/lib/pleroma/web/rel_me.ex index 3a1812f7a..98a3ae8ee 100644 --- a/lib/pleroma/web/rel_me.ex +++ b/lib/pleroma/web/rel_me.ex @@ -42,7 +42,7 @@ def maybe_put_rel_me("http" <> _ = target_page, profile_urls) when is_list(profi "me" rescue - e -> nil + _ -> nil end def maybe_put_rel_me(_, _) do diff --git a/mix.lock b/mix.lock index dbe0ea5e3..ae78425d8 100644 --- a/mix.lock +++ b/mix.lock @@ -5,7 +5,7 @@ "bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.1", "5114d780459a04f2b4aeef52307de23de961b69e13a5cd98a911e39fda13f420", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "42182d5f46764def15bf9af83739e3bf4ad22661b1c34fc3e88558efced07279"}, "benchee": {:hex, :benchee, "1.1.0", "f3a43817209a92a1fade36ef36b86e1052627fd8934a8b937ac9ab3a76c43062", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}], "hexpm", "7da57d545003165a012b587077f6ba90b89210fd88074ce3c60ce239eb5e6d93"}, "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, - "cachex": {:hex, :cachex, "3.4.0", "868b2959ea4aeb328c6b60ff66c8d5123c083466ad3c33d3d8b5f142e13101fb", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "370123b1ab4fba4d2965fb18f87fd758325709787c8c5fce35b3fe80645ccbe5"}, + "cachex": {:hex, :cachex, "3.5.0", "f715390a9e93125980187dcd7c4036ece92d273fbd9ec009a8ffa480abdc51f8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "fac2ebfa200dd9ffba08cdcef404426ccadfcb92281ca34f810535712d02b049"}, "calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.1.201603 or ~> 0.5.20 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"}, "captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]}, "castore": {:hex, :castore, "0.1.20", "62a0126cbb7cb3e259257827b9190f88316eb7aa3fdac01fd6f2dfd64e7f46e9", [:mix], [], "hexpm", "a020b7650529c986c454a4035b6b13a328e288466986307bea3aadb4c95ac98a"}, @@ -27,16 +27,16 @@ "earmark": {:hex, :earmark, "1.4.34", "d7f89d3bbd7567a0bffc465e0a949f8f8dcbe43909c3acf96f4761a302cea10c", [:mix], [{:earmark_parser, "~> 1.4.29", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "90b106f3dad85b133b10d7d628167c88246123fd1cecb4557d83d21ec9e65504"}, "earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"}, "eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"}, - "ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"}, + "ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"}, "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.10", "e14d400930f401ca9f541b3349212634e44027d7f919bbb71224d7ac0d0e8acd", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.15.7 or ~> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "505e8cd81e4f17c090be0f99e92b1b3f0fd915f98e76965130b8ccfb891e7088"}, - "ecto_sql": {:hex, :ecto_sql, "3.9.1", "9bd5894eecc53d5b39d0c95180d4466aff00e10679e13a5cfa725f6f85c03c22", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5fd470a4fff2e829bbf9dcceb7f3f9f6d1e49b4241e802f614de6b8b67c51118"}, + "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, "elasticsearch": {:git, "https://akkoma.dev/AkkomaGang/elasticsearch-elixir.git", "6cd946f75f6ab9042521a009d1d32d29a90113ca", [ref: "main"]}, "elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"}, "ex_aws": {:hex, :ex_aws, "2.1.9", "dc4865ecc20a05190a34a0ac5213e3e5e2b0a75a0c2835e923ae7bfeac5e3c31", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "3e6c776703c9076001fbe1f7c049535f042cb2afa0d2cbd3b47cbc4e92ac0d10"}, - "ex_aws_s3": {:hex, :ex_aws_s3, "2.3.3", "61412e524616ea31d3f31675d8bc4c73f277e367dee0ae8245610446f9b778aa", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "0044f0b6f9ce925666021eafd630de64c2b3404d79c85245cc7c8a9a32d7f104"}, + "ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"}, "ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"}, "ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"}, "ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"}, @@ -59,7 +59,7 @@ "inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"}, "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, "joken": {:hex, :joken, "2.5.0", "09be497d804b8115eb6f07615cef2e60c2a1008fb89dc0aef0d4c4b4609b99aa", [:mix], [{:jose, "~> 1.11.2", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "22b25c89617c5ed8ca7b31026340a25ea0f9ca7160f9706b79be9ed81fdf74e7"}, - "jose": {:hex, :jose, "1.11.2", "f4c018ccf4fdce22c71e44d471f15f723cb3efab5d909ab2ba202b5bf35557b3", [:mix, :rebar3], [], "hexpm", "98143fbc48d55f3a18daba82d34fe48959d44538e9697c08f34200fa5f0947d2"}, + "jose": {:hex, :jose, "1.11.5", "3bc2d75ffa5e2c941ca93e5696b54978323191988eb8d225c2e663ddfefd515e", [:mix, :rebar3], [], "hexpm", "dcd3b215bafe02ea7c5b23dafd3eb8062a5cd8f2d904fd9caa323d37034ab384"}, "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, "linkify": {:git, "https://akkoma.dev/AkkomaGang/linkify.git", "2567e2c1073fa371fd26fd66dfa5bc77b6919c16", [branch: "bugfix/line-ending-buffer"]}, "mail": {:hex, :mail, "0.2.3", "2c6bb5f8a5f74845fa50ecd0fb45ea16b164026f285f45104f1c4c078cd616d4", [:mix], [], "hexpm", "932b398fa9c69fdf290d7ff63175826e0f1e24414d5b0763bb00a2acfc6c6bf5"}, @@ -76,7 +76,7 @@ "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, "mogrify": {:hex, :mogrify, "0.9.2", "b360984adea7dd6a55f18028e6327973c58de7f548fdb86c9859848aa904d5b0", [:mix], [], "hexpm", "c18d10fd70ca20e2585301616c89f6e4f7159d92efc9cc8ee579e00c886f699d"}, "mox": {:hex, :mox, "1.0.2", "dc2057289ac478b35760ba74165b4b3f402f68803dd5aecd3bfd19c183815d64", [:mix], [], "hexpm", "f9864921b3aaf763c8741b5b8e6f908f44566f1e427b2630e89e9a73b981fef2"}, - "nimble_options": {:hex, :nimble_options, "0.5.1", "5c166f7669e40333191bea38e3bd3811cc13f459f1e4be49e89128a21b5d8c4d", [:mix], [], "hexpm", "d176cf7baa4fef0ceb301ca3eb8b55bd7de3e45f489c4f8b4f2849f1f114ef3e"}, + "nimble_options": {:hex, :nimble_options, "0.5.2", "42703307b924880f8c08d97719da7472673391905f528259915782bb346e0a1b", [:mix], [], "hexpm", "4da7f904b915fd71db549bcdc25f8d56f378ef7ae07dc1d372cbe72ba950dce0"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"}, "oban": {:hex, :oban, "2.12.1", "f604d7e6a8be9fda4a9b0f6cebbd633deba569f85dbff70c4d25d99a6f023177", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b1844c2b74e0d788b73e5144b0c9d5674cb775eae29d88a36f3c3b48d42d058"}, @@ -86,7 +86,7 @@ "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, "phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.3", "2e3d009422addf8b15c3dccc65ce53baccbe26f7cfd21d264680b5867789a9c1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c8845177a866e017dcb7083365393c8f00ab061b8b6b2bda575891079dce81b2"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.6", "460c36977643d76fc8e0b6b3c4bba703c0ef21abc74233cf7dc15d1c1696832f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ce2768fb44c3c370df13fc4f0dc70623b662a93a201d8d7d87c4ba6542bc6b73"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.4", "615f8f393135de7e0cbb4bd00ba238b1e0cd324b0d90efbaee613c2f02ca5e5c", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "3971221846232021ab5e3c7489fd62ec5bfd6a2e01cae10a317ccf6fb350571c"}, "phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"}, @@ -100,14 +100,14 @@ "postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"}, "pot": {:hex, :pot, "1.0.2", "13abb849139fdc04ab8154986abbcb63bdee5de6ed2ba7e1713527e33df923dd", [:rebar3], [], "hexpm", "78fe127f5a4f5f919d6ea5a2a671827bd53eb9d37e5b4128c0ad3df99856c2e0"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, - "recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"}, + "recon": {:hex, :recon, "2.5.3", "739107b9050ea683c30e96de050bc59248fd27ec147696f79a8797ff9fa17153", [:mix, :rebar3], [], "hexpm", "6c6683f46fd4a1dfd98404b9f78dcabc7fcd8826613a89dcb984727a8c3099d7"}, "remote_ip": {:hex, :remote_ip, "1.1.0", "cb308841595d15df3f9073b7c39243a1dd6ca56e5020295cb012c76fbec50f2d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "616ffdf66aaad6a72fc546dabf42eed87e2a99e97b09cbd92b10cc180d02ed74"}, "search_parser": {:git, "https://github.com/FloatingGhost/pleroma-contrib-search-parser.git", "08971a81e68686f9ac465cfb6661d51c5e4e1e7f", [ref: "08971a81e68686f9ac465cfb6661d51c5e4e1e7f"]}, "sleeplocks": {:hex, :sleeplocks, "1.1.2", "d45aa1c5513da48c888715e3381211c859af34bee9b8290490e10c90bb6ff0ca", [:rebar3], [], "hexpm", "9fe5d048c5b781d6305c1a3a0f40bb3dfc06f49bf40571f3d2d0c57eaa7f59a5"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "sweet_xml": {:hex, :sweet_xml, "0.7.3", "debb256781c75ff6a8c5cbf7981146312b66f044a2898f453709a53e5031b45b", [:mix], [], "hexpm", "e110c867a1b3fe74bfc7dd9893aa851f0eed5518d0d7cad76d7baafd30e4f5ba"}, - "swoosh": {:hex, :swoosh, "1.8.3", "733357d9a65da19c162171f08d1e42a6259236cf44d02a64711b776afbbbaa78", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c699abbac7a296c205055a7501c5d5261320ea1f08bde2392699a9e899815bc7"}, + "swoosh": {:hex, :swoosh, "1.9.1", "0a5d7bf9954eb41d7e55525bc0940379982b090abbaef67cd8e1fd2ed7f8ca1a", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "76dffff3ffcab80f249d5937a592eaef7cc49ac6f4cdd27e622868326ed6371e"}, "syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"}, "table_rex": {:hex, :table_rex, "3.1.1", "0c67164d1714b5e806d5067c1e96ff098ba7ae79413cc075973e17c38a587caa", [:mix], [], "hexpm", "678a23aba4d670419c23c17790f9dcd635a4a89022040df7d5d772cb21012490"}, "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"}, From 78c44f31ca10c296dffc22e0b01a2a0cd9e25cfa Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Wed, 11 Jan 2023 15:25:34 +0000 Subject: [PATCH 5/6] fix no-language-specified federation --- lib/pleroma/web/common_api/activity_draft.ex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex index adddea669..ced6371d6 100644 --- a/lib/pleroma/web/common_api/activity_draft.ex +++ b/lib/pleroma/web/common_api/activity_draft.ex @@ -145,7 +145,10 @@ defp language(%{params: %{language: language}, content_html: content} = draft) end end - defp language(draft), do: draft + defp language(%{content_html: content} = draft) do + # Use a default language if no language is specified + %__MODULE__{draft | content_map: %{"en" => content}} + end defp visibility(%{params: params} = draft) do case CommonAPI.get_visibility(params, draft.in_reply_to, draft.in_reply_to_conversation) do From ff5793198ff9068c49de12e4dfb229b9de8d38f8 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Wed, 11 Jan 2023 15:42:13 +0000 Subject: [PATCH 6/6] add inbound language test --- .../article_note_page_validator.ex | 3 +- .../fixtures/mastodon/note_with_language.json | 38 +++++++++++++++++++ test/pleroma/iso639_test.exs | 11 ++++++ .../article_note_page_validator_test.exs | 8 ++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/mastodon/note_with_language.json create mode 100644 test/pleroma/iso639_test.exs 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 056c48f86..09b68c977 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 @@ -30,7 +30,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do field(:replies, {:array, ObjectValidators.ObjectID}, default: []) field(:source, :map) - field(:content_map, :map) + field(:contentMap, :map) end def cast_and_apply(data) do @@ -155,6 +155,7 @@ defp fix_content_map_languages(%{"contentMap" => content_map} = object) |> Enum.reject(fn {lang, _content} -> !Pleroma.ISO639.valid_alpha2?(lang) end) + |> Enum.into(%{}) Map.put(object, "contentMap", content_map) end diff --git a/test/fixtures/mastodon/note_with_language.json b/test/fixtures/mastodon/note_with_language.json new file mode 100644 index 000000000..04266708f --- /dev/null +++ b/test/fixtures/mastodon/note_with_language.json @@ -0,0 +1,38 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "ostatus": "http://ostatus.org#", + "atomUri": "ostatus:atomUri", + "inReplyToAtomUri": "ostatus:inReplyToAtomUri", + "conversation": "ostatus:conversation", + "sensitive": "as:sensitive", + "toot": "http://joinmastodon.org/ns#", + "votersCount": "toot:votersCount" + } + ], + "id": "https://mastodon.social/users/akkoma_ap_integration_tester/statuses/109671288784583764", + "type": "Note", + "summary": null, + "inReplyTo": null, + "published": "2023-01-11T15:31:01Z", + "url": "https://mastodon.social/@akkoma_ap_integration_tester/109671288784583764", + "attributedTo": "https://mastodon.social/users/akkoma_ap_integration_tester", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://mastodon.social/users/akkoma_ap_integration_tester/followers" + ], + "sensitive": false, + "atomUri": "https://mastodon.social/users/akkoma_ap_integration_tester/statuses/109671288784583764", + "inReplyToAtomUri": null, + "conversation": "tag:mastodon.social,2023-01-11:objectId=376794415:objectType=Conversation", + "content": "

tag

", + "contentMap": { + "ja": "

tag

" + }, + "attachment": [], + "tag": [], + "replies": [] +} diff --git a/test/pleroma/iso639_test.exs b/test/pleroma/iso639_test.exs new file mode 100644 index 000000000..f05635b8c --- /dev/null +++ b/test/pleroma/iso639_test.exs @@ -0,0 +1,11 @@ +defmodule Pleroma.ISO639Test do + use Pleroma.DataCase + + describe "ISO639 validation" do + test "should validate a language" do + assert Pleroma.ISO639.valid_alpha2?("en") + assert Pleroma.ISO639.valid_alpha2?("ja") + refute Pleroma.ISO639.valid_alpha2?("xx") + end + end +end 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 5b95ebc51..ade2256c3 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 @@ -39,6 +39,14 @@ test "a basic note validates", %{note: note} do %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note) end + test "a note with a language validates" do + user = insert(:user, %{ap_id: "https://mastodon.social/users/akkoma_ap_integration_tester"}) + note = File.read!("test/fixtures/mastodon/note_with_language.json") |> Jason.decode!() + %{valid?: true, changes: %{ contentMap: %{ + "ja" => "

tag

", + }}} = ArticleNotePageValidator.cast_and_validate(note) + end + test "a note from factory validates" do note = insert(:note) %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note.data)