diff --git a/changelog.d/mogrify.skip b/changelog.d/mogrify.skip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/changelog.d/publisher-reachability.fix b/changelog.d/publisher-reachability.fix new file mode 100644 index 0000000000..3f50be581b --- /dev/null +++ b/changelog.d/publisher-reachability.fix @@ -0,0 +1 @@ +Address case where instance reachability status couldn't be updated diff --git a/changelog.d/remote-object-fetcher.fix b/changelog.d/remote-object-fetcher.fix new file mode 100644 index 0000000000..dcf2b1b315 --- /dev/null +++ b/changelog.d/remote-object-fetcher.fix @@ -0,0 +1 @@ +Remote Fetcher Worker recognizes more permanent failure errors diff --git a/changelog.d/update-oban.change b/changelog.d/update-oban.change new file mode 100644 index 0000000000..a67b3e3cf4 --- /dev/null +++ b/changelog.d/update-oban.change @@ -0,0 +1 @@ +Update Oban to 2.18 diff --git a/changelog.d/user-imports.fix b/changelog.d/user-imports.fix new file mode 100644 index 0000000000..0076c73d77 --- /dev/null +++ b/changelog.d/user-imports.fix @@ -0,0 +1 @@ +Imports of blocks, mutes, and follows would retry repeatedly due to incorrect error handling and all work executed in a single job diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index c0f671dd43..9d9a201caf 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -73,50 +73,22 @@ def fetch_object_from_id(id, options \\ []) do {:object, data, Object.normalize(activity, fetch: false)} do {:ok, object} else - {:allowed_depth, false} = e -> - log_fetch_error(id, e) - {:error, :allowed_depth} - - {:containment, reason} = e -> - log_fetch_error(id, e) - {:error, reason} - - {:transmogrifier, {:error, {:reject, reason}}} = e -> - log_fetch_error(id, e) - {:reject, reason} - - {:transmogrifier, {:reject, reason}} = e -> - log_fetch_error(id, e) - {:reject, reason} - - {:transmogrifier, reason} = e -> - log_fetch_error(id, e) - {:error, reason} - - {:object, data, nil} -> - reinject_object(%Object{}, data) - {:normalize, object = %Object{}} -> {:ok, object} {:fetch_object, %Object{} = object} -> {:ok, object} - {:fetch, {:error, reason}} = e -> - log_fetch_error(id, e) - {:error, reason} + {:object, data, nil} -> + reinject_object(%Object{}, data) e -> - log_fetch_error(id, e) - {:error, e} + Logger.metadata(object: id) + Logger.error("Object rejected while fetching #{id} #{inspect(e)}") + e end end - defp log_fetch_error(id, error) do - Logger.metadata(object: id) - Logger.error("Object rejected while fetching #{id} #{inspect(error)}") - end - defp prepare_activity_params(data) do %{ "type" => "Create", diff --git a/lib/pleroma/user/import.ex b/lib/pleroma/user/import.ex index 11905237c3..b79fa88eb2 100644 --- a/lib/pleroma/user/import.ex +++ b/lib/pleroma/user/import.ex @@ -5,6 +5,7 @@ defmodule Pleroma.User.Import do use Ecto.Schema + alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.CommonAPI alias Pleroma.Workers.BackgroundWorker @@ -12,80 +13,99 @@ defmodule Pleroma.User.Import do require Logger @spec perform(atom(), User.t(), list()) :: :ok | list() | {:error, any()} - def perform(:mutes_import, %User{} = user, [_ | _] = identifiers) do - Enum.map( - identifiers, - fn identifier -> - with {:ok, %User{} = muted_user} <- User.get_or_fetch(identifier), - {:ok, _} <- User.mute(user, muted_user) do - muted_user - else - error -> handle_error(:mutes_import, identifier, error) - end - end - ) + def perform(:mute_import, %User{} = user, actor) do + with {:ok, %User{} = muted_user} <- User.get_or_fetch(actor), + {_, false} <- {:existing_mute, User.mutes_user?(user, muted_user)}, + {:ok, _} <- User.mute(user, muted_user) do + {:ok, muted_user} + else + {:existing_mute, true} -> :ok + error -> handle_error(:mutes_import, actor, error) + end end - def perform(:blocks_import, %User{} = blocker, [_ | _] = identifiers) do - Enum.map( - identifiers, - fn identifier -> - with {:ok, %User{} = blocked} <- User.get_or_fetch(identifier), - {:ok, _block} <- CommonAPI.block(blocked, blocker) do - blocked - else - error -> handle_error(:blocks_import, identifier, error) - end - end - ) + def perform(:block_import, %User{} = user, actor) do + with {:ok, %User{} = blocked} <- User.get_or_fetch(actor), + {_, false} <- {:existing_block, User.blocks_user?(user, blocked)}, + {:ok, _block} <- CommonAPI.block(blocked, user) do + {:ok, blocked} + else + {:existing_block, true} -> :ok + error -> handle_error(:blocks_import, actor, error) + end end - def perform(:follow_import, %User{} = follower, [_ | _] = identifiers) do - Enum.map( - identifiers, - fn identifier -> - with {:ok, %User{} = followed} <- User.get_or_fetch(identifier), - {:ok, follower, followed} <- User.maybe_direct_follow(follower, followed), - {:ok, _, _, _} <- CommonAPI.follow(followed, follower) do - followed - else - error -> handle_error(:follow_import, identifier, error) - end - end - ) + def perform(:follow_import, %User{} = user, actor) do + with {:ok, %User{} = followed} <- User.get_or_fetch(actor), + {_, false} <- {:existing_follow, User.following?(user, followed)}, + {:ok, user, followed} <- User.maybe_direct_follow(user, followed), + {:ok, _, _, _} <- CommonAPI.follow(followed, user) do + {:ok, followed} + else + {:existing_follow, true} -> :ok + error -> handle_error(:follow_import, actor, error) + end end - def perform(_, _, _), do: :ok - defp handle_error(op, user_id, error) do Logger.debug("#{op} failed for #{user_id} with: #{inspect(error)}") error end - def blocks_import(%User{} = blocker, [_ | _] = identifiers) do - BackgroundWorker.new(%{ - "op" => "blocks_import", - "user_id" => blocker.id, - "identifiers" => identifiers - }) - |> Oban.insert() + def blocks_import(%User{} = user, [_ | _] = actors) do + jobs = + Repo.checkout(fn -> + Enum.reduce(actors, [], fn actor, acc -> + {:ok, job} = + BackgroundWorker.new(%{ + "op" => "block_import", + "user_id" => user.id, + "actor" => actor + }) + |> Oban.insert() + + acc ++ [job] + end) + end) + + {:ok, jobs} end - def follow_import(%User{} = follower, [_ | _] = identifiers) do - BackgroundWorker.new(%{ - "op" => "follow_import", - "user_id" => follower.id, - "identifiers" => identifiers - }) - |> Oban.insert() + def follows_import(%User{} = user, [_ | _] = actors) do + jobs = + Repo.checkout(fn -> + Enum.reduce(actors, [], fn actor, acc -> + {:ok, job} = + BackgroundWorker.new(%{ + "op" => "follow_import", + "user_id" => user.id, + "actor" => actor + }) + |> Oban.insert() + + acc ++ [job] + end) + end) + + {:ok, jobs} end - def mutes_import(%User{} = user, [_ | _] = identifiers) do - BackgroundWorker.new(%{ - "op" => "mutes_import", - "user_id" => user.id, - "identifiers" => identifiers - }) - |> Oban.insert() + def mutes_import(%User{} = user, [_ | _] = actors) do + jobs = + Repo.checkout(fn -> + Enum.reduce(actors, [], fn actor, acc -> + {:ok, job} = + BackgroundWorker.new(%{ + "op" => "mute_import", + "user_id" => user.id, + "actor" => actor + }) + |> Oban.insert() + + acc ++ [job] + end) + end) + + {:ok, jobs} end end diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index 5cd982c6a2..0de3a0d434 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -148,12 +148,17 @@ def publish_one(%Prepared{} = p) do {"digest", p.digest} ] ) do - maybe_set_reachable(p.unreachable_since, p.inbox) + if not is_nil(p.unreachable_since) do + Instances.set_reachable(p.inbox) + end result else {_post_result, %{status: code} = response} = e -> - maybe_set_unreachable(p.unreachable_since, p.inbox) + if is_nil(p.unreachable_since) do + Instances.set_unreachable(p.inbox) + end + Logger.metadata(activity: p.activity_id, inbox: p.inbox, status: code) Logger.error("Publisher failed to inbox #{p.inbox} with status #{code}") @@ -174,7 +179,10 @@ def publish_one(%Prepared{} = p) do connection_pool_snooze() e -> - maybe_set_unreachable(p.unreachable_since, p.inbox) + if is_nil(p.unreachable_since) do + Instances.set_unreachable(p.inbox) + end + Logger.metadata(activity: p.activity_id, inbox: p.inbox) Logger.error("Publisher failed to inbox #{p.inbox} #{inspect(e)}") {:error, e} @@ -183,12 +191,6 @@ def publish_one(%Prepared{} = p) do defp connection_pool_snooze, do: {:snooze, 3} - defp maybe_set_reachable(%NaiveDateTime{}, inbox), do: Instances.set_reachable(inbox) - defp maybe_set_reachable(_, _), do: :ok - - defp maybe_set_unreachable(nil, inbox), do: Instances.set_unreachable(inbox) - defp maybe_set_unreachable(%NaiveDateTime{}, _), do: :ok - defp signature_host(%URI{port: port, scheme: scheme, host: host}) do if port == URI.default_port(scheme) do host diff --git a/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex b/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex index 96466f1921..d65c30dab5 100644 --- a/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex @@ -38,8 +38,8 @@ def do_follow(%{assigns: %{user: follower}} = conn, list) do |> Enum.map(&(&1 |> String.trim() |> String.trim_leading("@"))) |> Enum.reject(&(&1 == "")) - User.Import.follow_import(follower, identifiers) - json(conn, "job started") + User.Import.follows_import(follower, identifiers) + json(conn, "jobs started") end def blocks( @@ -55,7 +55,7 @@ def blocks(%{private: %{open_api_spex: %{body_params: %{list: list}}}} = conn, _ defp do_block(%{assigns: %{user: blocker}} = conn, list) do User.Import.blocks_import(blocker, prepare_user_identifiers(list)) - json(conn, "job started") + json(conn, "jobs started") end def mutes( @@ -71,7 +71,7 @@ def mutes(%{private: %{open_api_spex: %{body_params: %{list: list}}}} = conn, _) defp do_mute(%{assigns: %{user: user}} = conn, list) do User.Import.mutes_import(user, prepare_user_identifiers(list)) - json(conn, "job started") + json(conn, "jobs started") end defp prepare_user_identifiers(list) do diff --git a/lib/pleroma/workers/background_worker.ex b/lib/pleroma/workers/background_worker.ex index 60da2d5ca7..4737c6ea24 100644 --- a/lib/pleroma/workers/background_worker.ex +++ b/lib/pleroma/workers/background_worker.ex @@ -19,10 +19,10 @@ def perform(%Job{args: %{"op" => "force_password_reset", "user_id" => user_id}}) User.perform(:force_password_reset, user) end - def perform(%Job{args: %{"op" => op, "user_id" => user_id, "identifiers" => identifiers}}) - when op in ["blocks_import", "follow_import", "mutes_import"] do + def perform(%Job{args: %{"op" => op, "user_id" => user_id, "actor" => actor}}) + when op in ["block_import", "follow_import", "mute_import"] do user = User.get_cached_by_id(user_id) - {:ok, User.Import.perform(String.to_existing_atom(op), user, identifiers)} + User.Import.perform(String.to_existing_atom(op), user, actor) end def perform(%Job{ diff --git a/lib/pleroma/workers/remote_fetcher_worker.ex b/lib/pleroma/workers/remote_fetcher_worker.ex index e43765733e..9d3f1ec539 100644 --- a/lib/pleroma/workers/remote_fetcher_worker.ex +++ b/lib/pleroma/workers/remote_fetcher_worker.ex @@ -13,17 +13,26 @@ def perform(%Job{args: %{"op" => "fetch_remote", "id" => id} = args}) do {:ok, _object} -> :ok - {:reject, reason} -> + {:allowed_depth, false} -> + {:cancel, :allowed_depth} + + {:containment, reason} -> {:cancel, reason} - {:error, :forbidden} -> - {:cancel, :forbidden} + {:transmogrifier, reason} -> + {:cancel, reason} - {:error, :not_found} -> - {:cancel, :not_found} + {:fetch, {:error, :forbidden = reason}} -> + {:cancel, reason} - {:error, :allowed_depth} -> - {:cancel, :allowed_depth} + {:fetch, {:error, :not_found = reason}} -> + {:cancel, reason} + + {:fetch, {:error, {:content_type, _}} = reason} -> + {:cancel, reason} + + {:fetch, {:error, reason}} -> + {:error, reason} {:error, _} = e -> e diff --git a/mix.exs b/mix.exs index 251243bb43..b2705cfbc8 100644 --- a/mix.exs +++ b/mix.exs @@ -147,7 +147,7 @@ defp deps do {:telemetry_poller, "~> 1.0"}, {:tzdata, "~> 1.0.3"}, {:plug_cowboy, "~> 2.5"}, - {:oban, "~> 2.17.9"}, + {:oban, "~> 2.18.0"}, {:gettext, "~> 0.20"}, {:bcrypt_elixir, "~> 2.2"}, {:fast_sanitize, "~> 0.2.0"}, @@ -161,7 +161,7 @@ defp deps do {:gun, "~> 2.0.0-rc.1", override: true}, {:finch, "~> 0.15"}, {:jason, "~> 1.2"}, - {:mogrify, "~> 0.8.0"}, + {:mogrify, "~> 0.9.0", override: "true"}, {:ex_aws, "~> 2.1.6"}, {:ex_aws_s3, "~> 2.0"}, {:sweet_xml, "~> 0.7.2"}, diff --git a/mix.lock b/mix.lock index 8446bd6eac..cfa75cac80 100644 --- a/mix.lock +++ b/mix.lock @@ -73,7 +73,7 @@ "icalendar": {:hex, :icalendar, "1.1.2", "5d0afff5d0143c5bd43f18ae32a777bf0fb9a724543ab05229a460d368f0a5e7", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2060f8e353fdf3047e95a3f012583dc3c0bbd7ca1010e32ed9e9fc5760ad4292"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inet_cidr": {:hex, :inet_cidr, "1.0.8", "d26bb7bdbdf21ae401ead2092bf2bb4bf57fe44a62f5eaa5025280720ace8a40", [:mix], [], "hexpm", "d5b26da66603bb56c933c65214c72152f0de9a6ea53618b56d63302a68f6a90e"}, - "jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "joken": {:hex, :joken, "2.6.0", "b9dd9b6d52e3e6fcb6c65e151ad38bf4bc286382b5b6f97079c47ade6b1bcc6a", [:mix], [{:jose, "~> 1.11.5", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "5a95b05a71cd0b54abd35378aeb1d487a23a52c324fa7efdffc512b655b5aaa7"}, "jose": {:hex, :jose, "1.11.6", "613fda82552128aa6fb804682e3a616f4bc15565a048dabd05b1ebd5827ed965", [:mix, :rebar3], [], "hexpm", "6275cb75504f9c1e60eeacb771adfeee4905a9e182103aa59b53fed651ff9738"}, "jumper": {:hex, :jumper, "1.0.2", "68cdcd84472a00ac596b4e6459a41b3062d4427cbd4f1e8c8793c5b54f1406a7", [:mix], [], "hexpm", "9b7782409021e01ab3c08270e26f36eb62976a38c1aa64b2eaf6348422f165e1"}, @@ -90,7 +90,7 @@ "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"}, "mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"}, - "mogrify": {:hex, :mogrify, "0.8.0", "3506f3ca3f7b95a155f3b4ef803b5db176f5a0633723e3fe85e0d6399e3b11c8", [:mix], [], "hexpm", "2278d245f07056ea3b586e98801e933695147066fa4cf563f552c1b4f0ff8ad9"}, + "mogrify": {:hex, :mogrify, "0.9.3", "238c782f00271dace01369ad35ae2e9dd020feee3443b9299ea5ea6bed559841", [:mix], [], "hexpm", "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6"}, "mox": {:hex, :mox, "1.1.0", "0f5e399649ce9ab7602f72e718305c0f9cdc351190f72844599545e4996af73c", [:mix], [], "hexpm", "d44474c50be02d5b72131070281a5d3895c0e7a95c780e90bc0cfe712f633a13"}, "multipart": {:hex, :multipart, "0.4.0", "634880a2148d4555d050963373d0e3bbb44a55b2badd87fa8623166172e9cda0", [:mix], [{:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "3c5604bc2fb17b3137e5d2abdf5dacc2647e60c5cc6634b102cf1aef75a06f0a"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, @@ -99,7 +99,7 @@ "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, "oauth2": {:hex, :oauth2, "0.9.4", "632e8e8826a45e33ac2ea5ac66dcc019ba6bb5a0d2ba77e342d33e3b7b252c6e", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "407c6b9f60aa0d01b915e2347dc6be78adca706a37f0c530808942da3b62e7af"}, "oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"}, - "oban": {:hex, :oban, "2.17.12", "33fb0cbfb92b910d48dd91a908590fe3698bb85eacec8cd0d9bc6aa13dddd6d6", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7a647d6cd6bb300073db17faabce22d80ae135da3baf3180a064fa7c4fa046e3"}, + "oban": {:hex, :oban, "2.18.2", "583e78965ee15263ac968e38c983bad169ae55eadaa8e1e39912562badff93ba", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9dd25fd35883a91ed995e9fe516e479344d3a8623dfe2b8c3fc8e5be0228ec3a"}, "oban_live_dashboard": {:hex, :oban_live_dashboard, "0.1.1", "8aa4ceaf381c818f7d5c8185cc59942b8ac82ef0cf559881aacf8d3f8ac7bdd3", [:mix], [{:oban, "~> 2.15", [hex: :oban, repo: "hexpm", optional: false]}, {:phoenix_live_dashboard, "~> 0.7", [hex: :phoenix_live_dashboard, repo: "hexpm", optional: false]}], "hexpm", "16dc4ce9c9a95aa2e655e35ed4e675652994a8def61731a18af85e230e1caa63"}, "octo_fetch": {:hex, :octo_fetch, "0.4.0", "074b5ecbc08be10b05b27e9db08bc20a3060142769436242702931c418695b19", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "cf8be6f40cd519d7000bb4e84adcf661c32e59369ca2827c4e20042eda7a7fc6"}, "open_api_spex": {:hex, :open_api_spex, "3.18.2", "8c855e83bfe8bf81603d919d6e892541eafece3720f34d1700b58024dadde247", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0 or ~> 4.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "aa3e6dcfc0ad6a02596b2172662da21c9dd848dac145ea9e603f54e3d81b8d2b"}, diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po b/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po index ff9ad52452..a56c907247 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po @@ -3,9 +3,9 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-07-21 04:21+0300\n" -"PO-Revision-Date: 2022-07-24 10:04+0000\n" -"Last-Translator: Yating Zhan \n" -"Language-Team: Chinese (Simplified) \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" @@ -49,6 +49,8 @@ msgstr "Mime 类型设置" msgctxt "config description at :pleroma" msgid "Allows setting a token that can be used to authenticate requests with admin privileges without a normal user account token. Append the `admin_token` parameter to requests to utilize it. (Please reconsider using HTTP Basic Auth or OAuth-based authentication if possible)" msgstr "" +"允许设置令牌以不使用普通用户令牌来授权管理员权限。在参数后加上 `admin_token` " +"来启用该功能。(可用时可以考虑使用 HTTP Basic Auth 或 基于 OAuth 的鉴定方式)" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -126,7 +128,7 @@ msgstr "ActivityPub 相关设置" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:assets" msgid "This section configures assets to be used with various frontends. Currently the only option relates to mascots on the mastodon frontend" -msgstr "" +msgstr "该部分配置不同前端使用的资源。目前该选项只对 Mastodon 前端的吉祥物有效" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -138,7 +140,7 @@ msgstr "鉴权/授权设置" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:connections_pool" msgid "Advanced settings for `Gun` connections pool" -msgstr "「Gun」连接池的高级设置" +msgstr "`Gun` 连接池的高级设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -183,7 +185,7 @@ msgstr "Gopher 设置" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:hackney_pools" msgid "Advanced settings for `Hackney` connections pools" -msgstr "「Hackney」连接池的高级设置" +msgstr "`Hackney` 连接池的高级设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -226,7 +228,7 @@ msgid "Majic/libmagic configuration" msgstr "Majic/libmagic 配置" #: lib/pleroma/docs/translator.ex:5 -#, elixir-autogen, elixir-format, fuzzy +#, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:manifest" msgid "This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE." msgstr "此处提供针对特定实例的 PWA manifest 数值。目前相关设定尚只支持 MastoFE。" @@ -244,10 +246,10 @@ msgid "Media proxy" msgstr "媒体代理" #: lib/pleroma/docs/translator.ex:5 -#, elixir-autogen, elixir-format, fuzzy +#, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:modules" msgid "Custom Runtime Modules" -msgstr "自定义 Runtime 模块" +msgstr "自定义运行库模块" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -299,7 +301,7 @@ msgstr "拒绝提及特定用户的讯息" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:mrf_normalize_markup" msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup." -msgstr "" +msgstr "MRF NomalizeMarkup 设置。清楚超文本标记。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -317,7 +319,7 @@ msgstr "RejectNonPublic 丢弃有非公开的可见性设置的文章。" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:mrf_simple" msgid "Simple ingress policies" -msgstr "" +msgstr "简单入口流量控制" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -326,10 +328,11 @@ msgid "Steals emojis from selected instances when it sees them." msgstr "从选择的实例偷取看到的 emoji。" #: lib/pleroma/docs/translator.ex:5 -#, elixir-autogen, elixir-format +#, elixir-autogen, elixir-format, fuzzy msgctxt "config description at :pleroma-:mrf_subchain" msgid "This policy processes messages through an alternate pipeline when a given message matches certain criteria. All criteria are configured as a map of regular expressions to lists of policy modules." -msgstr "" +msgstr "此策略将会把满足特定条件的信息通过另一管线处理。所有条件都以正则表达式来对应" +"列出的策略模块配置。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -347,13 +350,13 @@ msgstr "配置 OAuth 2 提供者的能力" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:pools" msgid "Advanced settings for `Gun` workers pools" -msgstr "「Gun」工人池的高级设置" +msgstr "`Gun` worker 池的高级设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:populate_hashtags_table" msgid "`populate_hashtags_table` background migration settings" -msgstr "「populate_hashtags_table」后台迁移设置" +msgstr "`populate_hashtags_table` 后台迁移设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -395,13 +398,13 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:uri_schemes" msgid "URI schemes related settings" -msgstr "" +msgstr "URI scheme 相关设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:web_cache_ttl" msgid "The expiration time for the web responses cache. Values should be in milliseconds or `nil` to disable expiration." -msgstr "web 回应缓存的过期时间。值应该以毫秒为单位,或者用「nil」来禁用过期。" +msgstr "网页回应缓存的过期时间。以毫秒为单位,或者用 `nil` 来禁用过期。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -413,7 +416,7 @@ msgstr "欢迎讯息设置" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:workers" msgid "Includes custom worker options not interpretable directly by `Oban`" -msgstr "包含不能直接被「Oban」解读的自定工人选项" +msgstr "包含不能直接被 `Oban` 解读的自定 worker 选项" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -488,7 +491,7 @@ msgstr "过滤器将会匿名化上传文件的文件名" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify" msgid "Uploads mogrify filter settings" -msgstr "" +msgstr "morgify 上传过滤器设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -531,6 +534,9 @@ msgstr "元数据相关设定" msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp" msgid "`Pleroma.Web.Plugs.RemoteIp` is a shim to call [`RemoteIp`](https://git.pleroma.social/pleroma/remote_ip) but with runtime configuration.\n**If your instance is not behind at least one reverse proxy, you should not enable this plug.**\n" msgstr "" +"`Pleroma.Web.Plugs.RemoteIp` 是一个呼叫 [`RemoteIp`](https://git.pleroma." +"social/pleroma/remote_ip) 的 shim 但是包含运行库配置。\n" +"**如果您的实例不在至少一个反向代理后面,您不应该启用这个插件。**\n" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -548,13 +554,13 @@ msgstr "失效活动设定" #, elixir-autogen, elixir-format msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" msgid "Prometheus app metrics endpoint configuration" -msgstr "" +msgstr "Prometheus 服务监控端点配置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :web_push_encryption-:vapid_details" msgid "Web Push Notifications configuration. You can use the mix task mix web_push.gen.keypair to generate it." -msgstr "" +msgstr "网页推送通知配置。您可以使用 mix task mix web_push.gen.keypair 来生成它。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -584,7 +590,7 @@ msgstr "ActivityPub" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:assets" msgid "Assets" -msgstr "" +msgstr "资源" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -608,13 +614,13 @@ msgstr "邮件通知" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:emoji" msgid "Emoji" -msgstr "Emoji" +msgstr "表情符号" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:features" msgid "Features" -msgstr "特性" +msgstr "功能" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -644,7 +650,7 @@ msgstr "Gopher" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:hackney_pools" msgid "Hackney pools" -msgstr "" +msgstr "Hackney 池" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -674,25 +680,25 @@ msgstr "实例图标" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:ldap" msgid "LDAP" -msgstr "" +msgstr "LDAP" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:majic_pool" msgid "Majic pool" -msgstr "" +msgstr "Majic 池" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:manifest" msgid "Manifest" -msgstr "" +msgstr "Manifest" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:markup" msgid "Markup Settings" -msgstr "" +msgstr "标记设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -710,25 +716,25 @@ msgstr "媒体文件代理" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:modules" msgid "Modules" -msgstr "" +msgstr "模块" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf" msgid "MRF" -msgstr "" +msgstr "MRF" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_activity_expiration" msgid "MRF Activity Expiration Policy" -msgstr "" +msgstr "MRF 活动过期策略" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_follow_bot" msgid "MRF FollowBot Policy" -msgstr "" +msgstr "MRF FollowBot 策略" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -740,49 +746,49 @@ msgstr "MRF 标签" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_hellthread" msgid "MRF Hellthread" -msgstr "" +msgstr "MRF Hellthread" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_keyword" msgid "MRF Keyword" -msgstr "" +msgstr "MRF 关键词" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_mention" msgid "MRF Mention" -msgstr "" +msgstr "MRF 提及" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_normalize_markup" msgid "MRF Normalize Markup" -msgstr "" +msgstr "MRF 标记标准化" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_object_age" msgid "MRF Object Age" -msgstr "" +msgstr "MRF 对象年龄" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_rejectnonpublic" msgid "MRF Reject Non Public" -msgstr "" +msgstr "MRF 拒绝非公开帖子" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_simple" msgid "MRF Simple" -msgstr "" +msgstr "MRF 简单" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:mrf_steal_emoji" msgid "MRF Emojis" -msgstr "" +msgstr "MRF 表情符号" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -800,13 +806,13 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:oauth2" msgid "OAuth2" -msgstr "" +msgstr "OAuth2" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:pools" msgid "Pools" -msgstr "" +msgstr "池" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -818,13 +824,13 @@ msgstr "本站话题标签列表" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:rate_limit" msgid "Rate limit" -msgstr "" +msgstr "限流" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:restrict_unauthenticated" msgid "Restrict Unauthenticated" -msgstr "" +msgstr "限制未授权用户" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -842,7 +848,7 @@ msgstr "留言板" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:static_fe" msgid "Static FE" -msgstr "" +msgstr "静态 FE" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -854,7 +860,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:uri_schemes" msgid "URI Schemes" -msgstr "" +msgstr "URI Schemes" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -866,7 +872,7 @@ msgstr "用户" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:web_cache_ttl" msgid "Web cache TTL" -msgstr "" +msgstr "网页缓存 TTL" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -878,13 +884,13 @@ msgstr "欢迎" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:workers" msgid "Workers" -msgstr "工人" +msgstr "Workers" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-ConcurrentLimiter" msgid "ConcurrentLimiter" -msgstr "" +msgstr "ConcurrentLimiter" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -896,133 +902,133 @@ msgstr "Oban" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Captcha" msgid "Pleroma.Captcha" -msgstr "" +msgstr "Pleroma.Captcha" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha" msgid "Pleroma.Captcha.Kocaptcha" -msgstr "" +msgstr "Pleroma.Captcha.Kocaptcha" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Emails.Mailer" msgid "Pleroma.Emails.Mailer" -msgstr "" +msgstr "Pleroma.Emails.Mailer" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail" msgid "Pleroma.Emails.NewUsersDigestEmail" -msgstr "" +msgstr "Pleroma.Emails.NewUsersDigestEmail" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail" msgid "Pleroma.Emails.UserEmail" -msgstr "" +msgstr "Pleroma.Emails.UserEmail" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Formatter" msgid "Linkify" -msgstr "" +msgstr "Linkify" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.ScheduledActivity" msgid "Pleroma.ScheduledActivity" -msgstr "" +msgstr "Pleroma.ScheduledActivity" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Upload" msgid "Pleroma.Upload" -msgstr "" +msgstr "Pleroma.Upload" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename" msgid "Pleroma.Upload.Filter.AnonymizeFilename" -msgstr "" +msgstr "Pleroma.Upload.Filter.AnonymizeFilename" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Upload.Filter.Mogrify" msgid "Pleroma.Upload.Filter.Mogrify" -msgstr "" +msgstr "Pleroma.Upload.Filter.Mogrify" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Uploaders.Local" msgid "Pleroma.Uploaders.Local" -msgstr "" +msgstr "Pleroma.Uploaders.Local" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Uploaders.S3" msgid "Pleroma.Uploaders.S3" -msgstr "" +msgstr "Pleroma.Uploaders.S3" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.User" msgid "Pleroma.User" -msgstr "" +msgstr "Pleroma.User" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.User.Backup" msgid "Pleroma.User.Backup" -msgstr "" +msgstr "Pleroma.User.Backup" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate" msgid "Pleroma.Web.ApiSpec.CastAndValidate" -msgstr "" +msgstr "Pleroma.Web.ApiSpec.CastAndValidate" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http" msgid "Pleroma.Web.MediaProxy.Invalidation.Http" -msgstr "" +msgstr "Pleroma.Web.MediaProxy.Invalidation.Http" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script" msgid "Pleroma.Web.MediaProxy.Invalidation.Script" -msgstr "" +msgstr "Pleroma.Web.MediaProxy.Invalidation.Script" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Web.Metadata" msgid "Pleroma.Web.Metadata" -msgstr "" +msgstr "Pleroma.Web.Metadata" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp" msgid "Pleroma.Web.Plugs.RemoteIp" -msgstr "" +msgstr "Pleroma.Web.Plugs.RemoteIp" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Web.Preload" msgid "Pleroma.Web.Preload" -msgstr "" +msgstr "Pleroma.Web.Preload" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity" msgid "Pleroma.Workers.PurgeExpiredActivity" -msgstr "" +msgstr "Pleroma.Workers.PurgeExpiredActivity" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" msgid "Pleroma.Web.Endpoint.MetricsExporter" -msgstr "" +msgstr "Pleroma.Web.Endpoint.MetricsExporter" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1064,37 +1070,39 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :ex_aws-:s3 > :access_key_id" msgid "S3 access key ID" -msgstr "" +msgstr "S3 访问密钥 ID" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :ex_aws-:s3 > :host" msgid "S3 host" -msgstr "" +msgstr "S3 主机" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :ex_aws-:s3 > :region" msgid "S3 region (for AWS)" -msgstr "" +msgstr "S3 区域(AWS)" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :ex_aws-:s3 > :secret_access_key" msgid "Secret access key" -msgstr "" +msgstr "访问密钥" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :logger > :backends" msgid "Where logs will be sent, :console - send logs to stdout, { ExSyslogger, :ex_syslogger } - to syslog, Quack.Logger - to Slack." msgstr "" +"日志发送的地点,:console - 将日志发送到 stdout, { ExSyslogger, :ex_syslogger " +"} - 发送到 syslog, Quack.Logger - 发送到 Slack." #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :logger-:console > :format" msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" -msgstr "" +msgstr "默认:\"$date $time [$level] $levelpad$node $metadata $message\"" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1106,13 +1114,13 @@ msgstr "日志等级" #, elixir-autogen, elixir-format msgctxt "config description at :logger-:ex_syslogger > :format" msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" -msgstr "" +msgstr "默认:\"$date $time [$level] $levelpad$node $metadata $message\"" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :logger-:ex_syslogger > :ident" msgid "A string that's prepended to every message, and is typically set to the app name" -msgstr "" +msgstr "注入在每一个消息前面的字符串,通常设为应用程序的名称" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1148,13 +1156,13 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:activitypub > :outgoing_blocks" msgid "Whether to federate blocks to other instances" -msgstr "" +msgstr "是否与其他实例同步屏蔽列表" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:activitypub > :sign_object_fetches" msgid "Sign object fetches with HTTP signatures" -msgstr "" +msgstr "为对象获取进行 HTTP 签名" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1166,7 +1174,7 @@ msgstr "屏蔽对象时是否同时取消对其的关注" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:assets > :default_mascot" msgid "This will be used as the default mascot on MastoFE. Default: `:pleroma_fox_tan`" -msgstr "" +msgstr "这将是 MastoFE 的默认吉祥物。默认:`:pleroma_fox_tan`" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1178,13 +1186,15 @@ msgstr "默认用户头像的网址" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:assets > :mascots" msgid "Keyword of mascots, each element must contain both an URL and a mime_type key" -msgstr "" +msgstr "吉祥物关键词,每一个元素必须包含一个 URL 和 mine_type 值" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:auth > :auth_template" msgid "Authentication form template. By default it's `show.html` which corresponds to `lib/pleroma/web/templates/o_auth/o_auth/show.html.ee`." msgstr "" +"授权表达模板。默认是 `show.html`,对应于 `lib/pleroma/web/templates/o_auth/" +"o_auth/show.html.ee`。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1208,7 +1218,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:connections_pool > :connect_timeout" msgid "Timeout while `gun` will wait until connection is up. Default: 5000ms." -msgstr "「Gun」等待连接时触发超时的上限。默认为5000ms。" +msgstr "`gun` 等待连接时触发超时的上限。默认:5000ms。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1226,7 +1236,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:connections_pool > :max_connections" msgid "Maximum number of connections in the pool. Default: 250 connections." -msgstr "" +msgstr "池的最大连接数量。默认:250 连接。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1262,13 +1272,15 @@ msgstr "单个用户每次收到摘要邮件的间隔" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:email_notifications > :digest > :schedule" msgid "When to send digest email, in crontab format. \"0 0 0\" is the default, meaning \"once a week at midnight on Sunday morning\"." -msgstr "" +msgstr "发送摘要邮件的时间,以 crontab 格式。默认为“0 0 " +"0”,意味着“每周在周日的午夜时分”。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:emoji > :default_manifest" msgid "Location of the JSON-manifest. This manifest contains information about the emoji-packs you can download. Currently only one manifest can be added (no arrays)." -msgstr "" +msgstr "JSON-manifest 的位置。manifest 包含您可以下载的表情包信息。目前只能添加一个 " +"manifest(无数列)。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1286,7 +1298,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:emoji > :shortcode_globs" msgid "Location of custom emoji files. * can be used as a wildcard." -msgstr "" +msgstr "自定义表情符号位置。* 可以当作通配符使用。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1298,7 +1310,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:feed > :post_title" msgid "Configure title rendering" -msgstr "" +msgstr "配置标题渲染" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1468,7 +1480,7 @@ msgstr "管理员前端" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:frontends > :admin > name" msgid "Name of the installed frontend. Valid config must include both `Name` and `Reference` values." -msgstr "已安装的前端名称。只有包含了「名称」与「引用」数值才能被算作有效配置。" +msgstr "已安装的前端名称。有效配置必须包含 `Name` 和 `Reference` 数值。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1498,13 +1510,13 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:frontends > :available > custom-http-headers" msgid "The custom HTTP headers for the frontend" -msgstr "" +msgstr "前端的自定义 HTTP 响应头" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:frontends > :available > git" msgid "URL of the git repository of the frontend" -msgstr "" +msgstr "前端 git 仓库的 URL" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1522,13 +1534,13 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:frontends > :primary" msgid "Primary frontend, the one that is served for all pages by default" -msgstr "" +msgstr "主要前端,这是默认服务所有页面的前端" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:frontends > :primary > name" msgid "Name of the installed frontend. Valid config must include both `Name` and `Reference` values." -msgstr "已安装的前端名称。只有包含了「名称」与「引用」数值才能被算作有效配置。" +msgstr "已安装的前端名称。有效配置必须包含 `Name` 和 `Reference` 数值。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1540,7 +1552,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:gopher > :dstport" msgid "Port advertised in URLs (optional, defaults to port)" -msgstr "" +msgstr "URL 中宣传的端口(可选,默认为端口)" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1570,7 +1582,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:hackney_pools > :federation > :max_connections" msgid "Number workers in the pool." -msgstr "池内的工人数量。" +msgstr "池内的 worker 数量。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1588,7 +1600,7 @@ msgstr "媒体池设定。" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:hackney_pools > :media > :max_connections" msgid "Number workers in the pool." -msgstr "池内的工人数量。" +msgstr "池内的 worker 数量。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1600,7 +1612,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:hackney_pools > :upload" msgid "Settings for upload pool." -msgstr "" +msgstr "上传池设置。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1780,7 +1792,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :email" msgid "Email used to reach an Administrator/Moderator of the instance" -msgstr "" +msgstr "用于联系实例管理员/监管员的电子邮箱" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1813,10 +1825,10 @@ msgid "Timeout (in days) of each external federation target being unreachable pr msgstr "" #: lib/pleroma/docs/translator.ex:5 -#, elixir-autogen, elixir-format, fuzzy +#, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :healthcheck" msgid "If enabled, system data will be shown on `/api/pleroma/healthcheck`" -msgstr "若启用,「/api/pleroma/healthcheck」下将显示系统数据" +msgstr "若启用,`/api/pleroma/healthcheck` 下将显示系统数据" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1828,7 +1840,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :invites_enabled" msgid "Enable user invitations for admins (depends on `registrations_open` being disabled)" -msgstr "只有管理员邀请的用户方能注册(需要关闭「registrations_open」选项)" +msgstr "只有管理员邀请的用户才能注册(需要关闭 `registrations_open` 选项)" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1900,13 +1912,13 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" msgid "Number of backup codes to generate." -msgstr "" +msgstr "生成的备份密钥数目。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp" msgid "TOTP settings" -msgstr "" +msgstr "TOTP 设置" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -1973,7 +1985,7 @@ msgstr "允许管理员访问敏感信息(例,更新用户凭据、取得密 #, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :profile_directory" msgid "Enable profile directory." -msgstr "" +msgstr "启用用户主页配置。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -2020,10 +2032,10 @@ msgstr "" "用户(例,“@admin 请留意 @bad_actor”)。默认下为关闭状态" #: lib/pleroma/docs/translator.ex:5 -#, elixir-autogen, elixir-format, fuzzy +#, elixir-autogen, elixir-format msgctxt "config description at :pleroma-:instance > :show_reactions" msgid "Let favourites and emoji reactions be viewed through the API." -msgstr "允许通过此API来看见喜欢数量与表情反应。" +msgstr "允许通过此 API 来看见喜欢数量与表情回应。" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format @@ -3607,7 +3619,7 @@ msgstr "" #, elixir-autogen, elixir-format msgctxt "config label at :pleroma-:assets > :mascots" msgid "Mascots" -msgstr "" +msgstr "吉祥物" #: lib/pleroma/docs/translator.ex:5 #, elixir-autogen, elixir-format diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/default.po b/priv/gettext/zh_Hans/LC_MESSAGES/default.po index ed0d1576b6..7d5828fae4 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/default.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/default.po @@ -8,9 +8,9 @@ ## to merge POT files into PO files. msgid "" msgstr "" -"PO-Revision-Date: 2022-07-22 19:00+0000\n" -"Last-Translator: Yating Zhan \n" -"Language-Team: Chinese (Simplified) \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -106,7 +106,7 @@ msgstr "转换到 %{polymorphic_type} 中的任一 schema 失败" #: lib/pleroma/web/api_spec/render_error.ex:71 #, elixir-format msgid "Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed." -msgstr "把值转换成 %{invalid_schema} 失败。值必须可以被转换成在列的「所有」schema。" +msgstr "把值转换成 %{invalid_schema} 失败。值必须可以被转换成在列的 `allOf` schema。" #: lib/pleroma/web/api_spec/render_error.ex:84 #, elixir-format @@ -136,17 +136,17 @@ msgstr "缺少头:%{name}。" #: lib/pleroma/web/api_spec/render_error.ex:196 #, elixir-format msgid "No value provided for required discriminator `%{field}`." -msgstr "" +msgstr "没有提供给鉴别器 `%{field}` 提供所需要的值。" #: lib/pleroma/web/api_spec/render_error.ex:216 #, elixir-format msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." -msgstr "" +msgstr "对象属性数 %{property_count} 大于 maxProperties: %{max_properties}。" #: lib/pleroma/web/api_spec/render_error.ex:224 #, elixir-format msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" -msgstr "" +msgstr "对象属性数 %{property_count} 小于 minProperties: %{min_properties}" #: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 #, elixir-format @@ -166,7 +166,7 @@ msgstr "未知的 schema:%{name}。" #: lib/pleroma/web/api_spec/render_error.ex:192 #, elixir-format msgid "Value used as discriminator for `%{field}` matches no schemas." -msgstr "" +msgstr "用于 `%{field}` 鉴别器的值无法匹配到任何 schema。" #: lib/pleroma/web/templates/embed/show.html.eex:43 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/errors.po b/priv/gettext/zh_Hans/LC_MESSAGES/errors.po index 4431445e34..6684729392 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/errors.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/errors.po @@ -3,9 +3,9 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-20 13:18+0000\n" -"PO-Revision-Date: 2022-07-22 19:00+0000\n" -"Last-Translator: Yating Zhan \n" -"Language-Team: Chinese (Simplified) \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" @@ -392,7 +392,7 @@ msgid "Invalid answer data" msgstr "无效的回答数据" #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33 -#, elixir-format, fuzzy +#, elixir-format msgid "Nodeinfo schema version not handled" msgstr "Nodeinfo schema 版本没被处理" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/oauth_scopes.po b/priv/gettext/zh_Hans/LC_MESSAGES/oauth_scopes.po new file mode 100644 index 0000000000..2044148367 --- /dev/null +++ b/priv/gettext/zh_Hans/LC_MESSAGES/oauth_scopes.po @@ -0,0 +1,274 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-01 10:12+0300\n" +"PO-Revision-Date: 2024-08-01 08:19+0000\n" +"Last-Translator: Eric Zhang \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_Hans\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.13.1\n" + +## This file is a PO Template file. +## +## "msgid"s here are often extracted from source code. +## Add new translations manually only if they're dynamic +## translations that can't be statically extracted. +## +## Run "mix gettext.extract" to bring this file up to +## date. Leave "msgstr"s empty as changing them here has no +## effect: edit them in PO (.po) files instead. +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin" +msgstr "全部管理员权限" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read" +msgstr "使用管理员 API 读取" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write" +msgstr "使用管理员 API 写入" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "follow" +msgstr "读取并写入用户关系" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read" +msgstr "读取任何信息" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:accounts" +msgstr "读取所有账号的信息" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:blocks" +msgstr "读取块关系" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:bookmarks" +msgstr "读取您的书签" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:favourites" +msgstr "读取您喜欢的帖子" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:filters" +msgstr "读取您的过滤器设置" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:follows" +msgstr "读取关注关系" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:lists" +msgstr "读取您的列表" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:notifications" +msgstr "读取您的通知" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:search" +msgstr "执行搜索" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:statuses" +msgstr "读取您可以看到的动态" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write" +msgstr "写入任何信息" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:accounts" +msgstr "更改您的账号信息" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:blocks" +msgstr "屏蔽或取消屏蔽任何人" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:bookmarks" +msgstr "从您的书签中添加或移除" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:conversations" +msgstr "更改收件人,标记为已阅,或删除聊天" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:favourites" +msgstr "喜欢或取消喜欢动态" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:filters" +msgstr "更改您的过滤器设置" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:follows" +msgstr "关注或取消关注任何人" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:lists" +msgstr "创建,更改或删除您的列表" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:media" +msgstr "上传媒体文件或更改您上传的媒体文件" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:mutes" +msgstr "隐藏或取消隐藏任何人" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:notifications" +msgstr "标记通知为已读" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:statuses" +msgstr "发表,编辑,转发帖子或对帖子做出回应" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read:accounts" +msgstr "使用管理员 API 读取所有账号" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read:chats" +msgstr "使用管理员 API 读取所有聊天" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read:invites" +msgstr "使用管理员 API 读取所有邀请码" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read:media_proxy_caches" +msgstr "使用管理员 API 读取媒体代理缓存" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read:reports" +msgstr "使用管理员 API 读取所有举报" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:read:statuses" +msgstr "使用管理员 API 读取所有动态" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:accounts" +msgstr "使用管理员 API 更改所有账号" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:chats" +msgstr "使用管理员 API 更改所有聊天" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:follows" +msgstr "使用管理员 API 更改关注关系" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:invites" +msgstr "使用管理员 API 创建或吊销邀请码" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:media_proxy_caches" +msgstr "使用管理员 API 更改媒体代理缓存" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:reports" +msgstr "使用管理员 API 处理举报" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "admin:write:statuses" +msgstr "使用管理员 API 删除动态,更改动态的范围,或标记为敏感动态" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:mutes" +msgstr "读取隐藏关系" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "push" +msgstr "推送通知" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:backups" +msgstr "读取您的备份" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:chats" +msgstr "读取您的聊天" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:media" +msgstr "读取媒体附件" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "read:reports" +msgstr "读取您的举报" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:chats" +msgstr "添加或移除聊天信息,或者标记它们为已阅" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:follow" +msgstr "关注或取消关注任何人" + +#: lib/pleroma/web/api_spec/scopes/translator.ex:5 +#, elixir-autogen, elixir-format +msgid "write:reports" +msgstr "提交举报" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po b/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po index c486a54864..930f5db1e5 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po @@ -8,9 +8,9 @@ ## to merge POT files into PO files. msgid "" msgstr "" -"PO-Revision-Date: 2022-07-22 19:00+0000\n" -"Last-Translator: Yating Zhan \n" -"Language-Team: Chinese (Simplified) \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,19 +22,19 @@ msgid "eperm" msgstr "不允许的操作" msgid "eacces" -msgstr "权限不够" +msgstr "拒绝访问" msgid "eagain" msgstr "资源暂时不可用" msgid "ebadf" -msgstr "坏的文件描述符" +msgstr "非法的文件描述符" msgid "ebadmsg" -msgstr "坏讯息" +msgstr "非法消息" msgid "ebusy" -msgstr "设备或资源忙" +msgstr "设备或资源繁忙" msgid "edeadlk" msgstr "避免了资源死锁" @@ -46,10 +46,10 @@ msgid "edquot" msgstr "超出了磁盘配额" msgid "eexist" -msgstr "文件存在" +msgstr "文件已存在" msgid "efault" -msgstr "坏地址" +msgstr "非法地址" msgid "efbig" msgstr "文件太大" @@ -61,7 +61,7 @@ msgid "eintr" msgstr "系统调用被中断" msgid "einval" -msgstr "不合法的参数" +msgstr "非法参数" msgid "eio" msgstr "输入/输出错误" @@ -79,7 +79,7 @@ msgid "emlink" msgstr "太多链接" msgid "emultihop" -msgstr "" +msgstr "已尝试多跳" msgid "enametoolong" msgstr "文件名太长" @@ -97,7 +97,7 @@ msgid "enolck" msgstr "没有可用的锁" msgid "enolink" -msgstr "链接被切断了" +msgstr "链接被切断" msgid "enoent" msgstr "没这文件或目录" @@ -109,19 +109,19 @@ msgid "enospc" msgstr "设备上没剩余空间" msgid "enosr" -msgstr "" +msgstr "流资源不足" msgid "enostr" msgstr "设备不是流" msgid "enosys" -msgstr "功能没实现" +msgstr "功能未实现" msgid "enotblk" -msgstr "" +msgstr "需要块设备" msgid "enotdir" -msgstr "" +msgstr "不是目录" msgid "enotsup" msgstr "不受支持的操作" @@ -136,25 +136,25 @@ msgid "eoverflow" msgstr "请为给定类型的数据指定较小的数值" msgid "epipe" -msgstr "" +msgstr "管道中断" msgid "erange" -msgstr "" +msgstr "数值超过范围" msgid "erofs" -msgstr "只读权限文件系统" +msgstr "只读文件系统" msgid "espipe" -msgstr "" +msgstr "非法搜寻" msgid "esrch" -msgstr "具体进程不存在" +msgstr "进程不存在" msgid "estale" -msgstr "" +msgstr "过时的文件句柄" msgid "etxtbsy" -msgstr "文本文件忙碌" +msgstr "文本文件繁忙" msgid "exdev" -msgstr "该多设备链接不可用" +msgstr "非法多设备链接" diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs index 6704c18db9..215fca5706 100644 --- a/test/pleroma/object/fetcher_test.exs +++ b/test/pleroma/object/fetcher_test.exs @@ -100,7 +100,7 @@ test "it works when fetching the OP actor errors out" do test "it returns thread depth exceeded error if thread depth is exceeded" do clear_config([:instance, :federation_incoming_replies_max_depth], 0) - assert {:error, :allowed_depth} = Fetcher.fetch_object_from_id(@ap_id, depth: 1) + assert {:allowed_depth, false} = Fetcher.fetch_object_from_id(@ap_id, depth: 1) end test "it fetches object if max thread depth is restricted to 0 and depth is not specified" do @@ -118,15 +118,18 @@ test "it fetches object if requested depth does not exceed max thread depth" do describe "actor origin containment" do test "it rejects objects with a bogus origin" do - {:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity.json") + {:containment, :error} = + Fetcher.fetch_object_from_id("https://info.pleroma.site/activity.json") end test "it rejects objects when attributedTo is wrong (variant 1)" do - {:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity2.json") + {:containment, :error} = + Fetcher.fetch_object_from_id("https://info.pleroma.site/activity2.json") end test "it rejects objects when attributedTo is wrong (variant 2)" do - {:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity3.json") + {:containment, :error} = + Fetcher.fetch_object_from_id("https://info.pleroma.site/activity3.json") end end @@ -150,14 +153,14 @@ test "Return MRF reason when fetched status is rejected by one" do clear_config([:mrf_keyword, :reject], ["yeah"]) clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy]) - assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} == + assert {:transmogrifier, {:reject, "[KeywordPolicy] Matches with rejected keyword"}} == Fetcher.fetch_object_from_id( "http://mastodon.example.org/@admin/99541947525187367" ) end test "it does not fetch a spoofed object uploaded on an instance as an attachment" do - assert {:error, _} = + assert {:fetch, {:error, {:content_type, "application/json"}}} = Fetcher.fetch_object_from_id( "https://patch.cx/media/03ca3c8b4ac3ddd08bf0f84be7885f2f88de0f709112131a22d83650819e36c2.json" ) diff --git a/test/pleroma/user/import_test.exs b/test/pleroma/user/import_test.exs index f75305e0e5..1d6469a4f6 100644 --- a/test/pleroma/user/import_test.exs +++ b/test/pleroma/user/import_test.exs @@ -25,11 +25,12 @@ test "it imports user followings from list" do user3.nickname ] - {:ok, job} = User.Import.follow_import(user1, identifiers) + {:ok, jobs} = User.Import.follows_import(user1, identifiers) + + for job <- jobs do + assert {:ok, %User{}} = ObanHelpers.perform(job) + end - assert {:ok, result} = ObanHelpers.perform(job) - assert is_list(result) - assert result == [refresh_record(user2), refresh_record(user3)] assert User.following?(user1, user2) assert User.following?(user1, user3) end @@ -44,11 +45,12 @@ test "it imports user blocks from list" do user3.nickname ] - {:ok, job} = User.Import.blocks_import(user1, identifiers) + {:ok, jobs} = User.Import.blocks_import(user1, identifiers) + + for job <- jobs do + assert {:ok, %User{}} = ObanHelpers.perform(job) + end - assert {:ok, result} = ObanHelpers.perform(job) - assert is_list(result) - assert result == [user2, user3] assert User.blocks?(user1, user2) assert User.blocks?(user1, user3) end @@ -63,11 +65,12 @@ test "it imports user mutes from list" do user3.nickname ] - {:ok, job} = User.Import.mutes_import(user1, identifiers) + {:ok, jobs} = User.Import.mutes_import(user1, identifiers) + + for job <- jobs do + assert {:ok, %User{}} = ObanHelpers.perform(job) + end - assert {:ok, result} = ObanHelpers.perform(job) - assert is_list(result) - assert result == [user2, user3] assert User.mutes?(user1, user2) assert User.mutes?(user1, user3) end diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index 3acbac3969..99ed428777 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -180,7 +180,7 @@ test "publish to url with with different ports" do Publisher.prepare_one(%{ inbox: inbox, activity_id: activity.id, - unreachable_since: NaiveDateTime.utc_now() + unreachable_since: NaiveDateTime.utc_now() |> NaiveDateTime.to_string() }) |> Publisher.publish_one() @@ -269,7 +269,7 @@ test "publish to url with with different ports" do Publisher.prepare_one(%{ inbox: inbox, activity_id: activity.id, - unreachable_since: NaiveDateTime.utc_now() + unreachable_since: NaiveDateTime.utc_now() |> NaiveDateTime.to_string() }) |> Publisher.publish_one() end) =~ "connrefused" diff --git a/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs index 52a62e4166..efdc743e3e 100644 --- a/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs @@ -22,7 +22,7 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do test "it returns HTTP 200", %{conn: conn} do user2 = insert(:user) - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"}) @@ -38,7 +38,7 @@ test "it imports follow lists from file", %{conn: conn} do "Account address,Show boosts\n#{user2.ap_id},true" end} ]) do - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/follow_import", %{ @@ -46,9 +46,9 @@ test "it imports follow lists from file", %{conn: conn} do }) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == [refresh_record(user2)] - assert [%Pleroma.User{follower_count: 1}] = job_result + assert [{:ok, updated_user}] = ObanHelpers.perform_all() + assert updated_user.id == user2.id + assert updated_user.follower_count == 1 end end @@ -63,7 +63,7 @@ test "it imports new-style mastodon follow lists", %{conn: conn} do }) |> json_response_and_validate_schema(200) - assert response == "job started" + assert response == "jobs started" end test "requires 'follow' or 'write:follows' permissions" do @@ -102,14 +102,20 @@ test "it imports follows with different nickname variations", %{conn: conn} do ] |> Enum.join("\n") - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/follow_import", %{"list" => identifiers}) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == Enum.map(users, &refresh_record/1) + results = ObanHelpers.perform_all() + + returned_users = + for {_, returned_user} <- results do + returned_user + end + + assert returned_users == Enum.map(users, &refresh_record/1) end end @@ -120,7 +126,7 @@ test "it imports follows with different nickname variations", %{conn: conn} do test "it returns HTTP 200", %{conn: conn} do user2 = insert(:user) - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"}) @@ -133,7 +139,7 @@ test "it imports blocks users from file", %{conn: conn} do with_mocks([ {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end} ]) do - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/blocks_import", %{ @@ -141,8 +147,14 @@ test "it imports blocks users from file", %{conn: conn} do }) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == users + results = ObanHelpers.perform_all() + + returned_users = + for {_, returned_user} <- results do + returned_user + end + + assert returned_users == users end end @@ -159,14 +171,25 @@ test "it imports blocks with different nickname variations", %{conn: conn} do ] |> Enum.join(" ") - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/blocks_import", %{"list" => identifiers}) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == users + results = ObanHelpers.perform_all() + + returned_user_ids = + for {_, user} <- results do + user.id + end + + original_user_ids = + for user <- users do + user.id + end + + assert match?(^original_user_ids, returned_user_ids) end end @@ -177,24 +200,25 @@ test "it imports blocks with different nickname variations", %{conn: conn} do test "it returns HTTP 200", %{user: user, conn: conn} do user2 = insert(:user) - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/mutes_import", %{"list" => "#{user2.ap_id}"}) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == [user2] + [{:ok, result_user}] = ObanHelpers.perform_all() + + assert result_user == refresh_record(user2) assert Pleroma.User.mutes?(user, user2) end test "it imports mutes users from file", %{user: user, conn: conn} do - users = [user2, user3] = insert_list(2, :user) + [user2, user3] = insert_list(2, :user) with_mocks([ {File, [], read!: fn "mutes_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end} ]) do - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/mutes_import", %{ @@ -202,14 +226,19 @@ test "it imports mutes users from file", %{user: user, conn: conn} do }) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == users - assert Enum.all?(users, &Pleroma.User.mutes?(user, &1)) + results = ObanHelpers.perform_all() + + returned_users = + for {_, returned_user} <- results do + returned_user + end + + assert Enum.all?(returned_users, &Pleroma.User.mutes?(user, &1)) end end test "it imports mutes with different nickname variations", %{user: user, conn: conn} do - users = [user2, user3, user4, user5, user6] = insert_list(5, :user) + [user2, user3, user4, user5, user6] = insert_list(5, :user) identifiers = [ @@ -221,15 +250,20 @@ test "it imports mutes with different nickname variations", %{user: user, conn: ] |> Enum.join(" ") - assert "job started" == + assert "jobs started" == conn |> put_req_header("content-type", "application/json") |> post("/api/pleroma/mutes_import", %{"list" => identifiers}) |> json_response_and_validate_schema(200) - assert [{:ok, job_result}] = ObanHelpers.perform_all() - assert job_result == users - assert Enum.all?(users, &Pleroma.User.mutes?(user, &1)) + results = ObanHelpers.perform_all() + + returned_users = + for {_, returned_user} <- results do + returned_user + end + + assert Enum.all?(returned_users, &Pleroma.User.mutes?(user, &1)) end end end diff --git a/test/pleroma/workers/remote_fetcher_worker_test.exs b/test/pleroma/workers/remote_fetcher_worker_test.exs index 2104baab2f..9caddb6008 100644 --- a/test/pleroma/workers/remote_fetcher_worker_test.exs +++ b/test/pleroma/workers/remote_fetcher_worker_test.exs @@ -12,6 +12,7 @@ defmodule Pleroma.Workers.RemoteFetcherWorkerTest do @deleted_object_two "https://deleted-410.example.com/" @unauthorized_object "https://unauthorized.example.com/" @depth_object "https://depth.example.com/" + @content_type_object "https://bad_content_type.example.com/" describe "RemoteFetcherWorker" do setup do @@ -35,34 +36,48 @@ defmodule Pleroma.Workers.RemoteFetcherWorkerTest do %Tesla.Env{ status: 200 } + + %{method: :get, url: @content_type_object} -> + %Tesla.Env{ + status: 200, + headers: [{"content-type", "application/json"}], + body: File.read!("test/fixtures/spoofed-object.json") + } end) end - test "does not requeue a deleted object" do - assert {:cancel, _} = - RemoteFetcherWorker.perform(%Oban.Job{ - args: %{"op" => "fetch_remote", "id" => @deleted_object_one} - }) + test "does not retry jobs for a deleted object" do + [ + %{"op" => "fetch_remote", "id" => @deleted_object_one}, + %{"op" => "fetch_remote", "id" => @deleted_object_two} + ] + |> Enum.each(fn job -> assert {:cancel, _} = perform_job(RemoteFetcherWorker, job) end) + end + test "does not retry jobs for an unauthorized object" do assert {:cancel, _} = - RemoteFetcherWorker.perform(%Oban.Job{ - args: %{"op" => "fetch_remote", "id" => @deleted_object_two} + perform_job(RemoteFetcherWorker, %{ + "op" => "fetch_remote", + "id" => @unauthorized_object }) end - test "does not requeue an unauthorized object" do - assert {:cancel, _} = - RemoteFetcherWorker.perform(%Oban.Job{ - args: %{"op" => "fetch_remote", "id" => @unauthorized_object} - }) - end - - test "does not requeue an object that exceeded depth" do + test "does not retry jobs for an an object that exceeded depth" do clear_config([:instance, :federation_incoming_replies_max_depth], 0) assert {:cancel, _} = - RemoteFetcherWorker.perform(%Oban.Job{ - args: %{"op" => "fetch_remote", "id" => @depth_object, "depth" => 1} + perform_job(RemoteFetcherWorker, %{ + "op" => "fetch_remote", + "id" => @depth_object, + "depth" => 1 + }) + end + + test "does not retry jobs for when object returns wrong content type" do + assert {:cancel, _} = + perform_job(RemoteFetcherWorker, %{ + "op" => "fetch_remote", + "id" => @content_type_object }) end end