diff --git a/.credo.exs b/.credo.exs index b85898af3..a467f2951 100644 --- a/.credo.exs +++ b/.credo.exs @@ -83,6 +83,7 @@ # lanodan: I think PreferImplicitTry should be consistency, and the behaviour seems # inconsistent, see: https://github.com/rrrene/credo/issues/224 {Credo.Check.Readability.PreferImplicitTry, false}, + {Credo.Check.Readability.PipeIntoAnonymousFunctions, exit_status: 0}, {Credo.Check.Readability.RedundantBlankLines}, {Credo.Check.Readability.StringSigils}, {Credo.Check.Readability.TrailingBlankLine}, @@ -90,6 +91,7 @@ {Credo.Check.Readability.VariableNames}, {Credo.Check.Readability.Semicolons}, {Credo.Check.Readability.SpaceAfterCommas}, + {Credo.Check.Readability.WithSingleClause, exit_status: 0}, {Credo.Check.Refactor.DoubleBooleanNegation}, {Credo.Check.Refactor.CondStatements}, {Credo.Check.Refactor.CyclomaticComplexity}, diff --git a/.gitignore b/.gitignore index da73b6f36..4009bd844 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ docs/generated_config.md # Code test coverage /cover /Elixir.*.coverdata +/coverage.xml .idea pleroma.iml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e5664da68..8b0381d11 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ variables: &global_variables POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres DB_HOST: postgres + DB_PORT: 5432 MIX_ENV: test cache: &global_cache_policy @@ -34,7 +35,8 @@ after_script: build: stage: build only: - changes: + changes: &build_changes_policy + - ".gitlab-ci.yml" - "**/*.ex" - "**/*.exs" - "mix.lock" @@ -45,6 +47,7 @@ spec-build: stage: test only: changes: + - ".gitlab-ci.yml" - "lib/pleroma/web/api_spec/**/*.ex" - "lib/pleroma/web/api_spec.ex" artifacts: @@ -59,7 +62,7 @@ benchmark: variables: MIX_ENV: benchmark services: - - name: postgres:9.6 + - name: postgres:9.6-alpine alias: postgres command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] script: @@ -70,38 +73,38 @@ benchmark: unit-testing: stage: test only: - changes: - - "**/*.ex" - - "**/*.exs" - - "mix.lock" + changes: *build_changes_policy cache: &testing_cache_policy <<: *global_cache_policy policy: pull services: - - name: postgres:13 + - name: postgres:13-alpine alias: postgres command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] script: - mix ecto.create - mix ecto.migrate - - mix coveralls --preload-modules + - mix test --cover --preload-modules + coverage: '/^Line total: ([^ ]*%)$/' + artifacts: + reports: + coverage_report: + coverage_format: cobertura + path: coverage.xml unit-testing-erratic: stage: test retry: 2 allow_failure: true only: - changes: - - "**/*.ex" - - "**/*.exs" - - "mix.lock" + changes: *build_changes_policy cache: &testing_cache_policy <<: *global_cache_policy policy: pull services: - - name: postgres:13 + - name: postgres:13-alpine alias: postgres command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] script: @@ -128,10 +131,7 @@ unit-testing-erratic: unit-testing-rum: stage: test only: - changes: - - "**/*.ex" - - "**/*.exs" - - "mix.lock" + changes: *build_changes_policy cache: *testing_cache_policy services: - name: minibikini/postgres-with-rum:12 @@ -147,15 +147,14 @@ unit-testing-rum: - mix test --preload-modules lint: - image: elixir:1.12 + image: ¤t_elixir elixir:1.12-alpine stage: test only: - changes: - - "**/*.ex" - - "**/*.exs" - - "mix.lock" + changes: *build_changes_policy cache: *testing_cache_policy - before_script: + before_script: ¤t_bfr_script + - apk update + - apk add build-base cmake file-dev git openssl - mix local.hex --force - mix local.rebar --force - mix deps.get @@ -165,29 +164,18 @@ lint: analysis: stage: test only: - changes: - - "**/*.ex" - - "**/*.exs" - - "mix.lock" + changes: *build_changes_policy cache: *testing_cache_policy script: - mix credo --strict --only=warnings,todo,fixme,consistency,readability cycles: + image: *current_elixir stage: test - image: elixir:1.11 only: - changes: - - "**/*.ex" - - "**/*.exs" - - "mix.lock" + changes: *build_changes_policy cache: {} - before_script: - - mix local.hex --force - - mix local.rebar --force - - mix deps.get - - apt-get update - - apt-get install cmake libmagic-dev -y + before_script: *current_bfr_script script: - mix compile - mix xref graph --format cycles --label compile | awk '{print $0} END{exit ($0 != "No cycles found")}' @@ -266,12 +254,14 @@ stop_review_app: amd64: stage: release - image: elixir:1.10.4 + image: elixir:1.11.4 only: &release-only - stable@pleroma/pleroma - develop@pleroma/pleroma - /^maint/.*$/@pleroma/pleroma - /^release/.*$/@pleroma/pleroma + tags: + - amd64 artifacts: &release-artifacts name: "pleroma-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME" paths: @@ -290,7 +280,7 @@ amd64: MIX_ENV: prod before_script: &before-release - apt-get update && apt-get install -y cmake libmagic-dev - - echo "import Mix.Config" > config/prod.secret.exs + - echo "import Config" > config/prod.secret.exs - mix local.hex --force - mix local.rebar --force script: &release @@ -304,12 +294,14 @@ amd64-musl: stage: release artifacts: *release-artifacts only: *release-only - image: elixir:1.10.4-alpine + image: elixir:1.11.4-alpine + tags: + - amd64 cache: *release-cache variables: *release-variables before_script: &before-release-musl - - apk add git gcc g++ musl-dev make cmake file-dev - - echo "import Mix.Config" > config/prod.secret.exs + - apk add git build-base cmake file-dev openssl + - echo "import Config" > config/prod.secret.exs - mix local.hex --force - mix local.rebar --force script: *release @@ -320,7 +312,7 @@ arm: only: *release-only tags: - arm32-specified - image: arm32v7/elixir:1.10.4 + image: arm32v7/elixir:1.11.4 cache: *release-cache variables: *release-variables before_script: *before-release @@ -332,7 +324,7 @@ arm-musl: only: *release-only tags: - arm32-specified - image: arm32v7/elixir:1.10.4-alpine + image: arm32v7/elixir:1.11.4-alpine cache: *release-cache variables: *release-variables before_script: *before-release-musl @@ -344,7 +336,7 @@ arm64: only: *release-only tags: - arm - image: arm64v8/elixir:1.10.4 + image: arm64v8/elixir:1.11.4 cache: *release-cache variables: *release-variables before_script: *before-release @@ -356,7 +348,7 @@ arm64-musl: only: *release-only tags: - arm - image: arm64v8/elixir:1.10.4-alpine + image: arm64v8/elixir:1.11.4-alpine cache: *release-cache variables: *release-variables before_script: *before-release-musl diff --git a/.gitlab/merge_request_templates/Release.md b/.gitlab/merge_request_templates/Release.md index b2c772696..9638d6d11 100644 --- a/.gitlab/merge_request_templates/Release.md +++ b/.gitlab/merge_request_templates/Release.md @@ -1,6 +1,8 @@ ### Release checklist -* [ ] Bump version in `mix.exs` -* [ ] Compile a changelog -* [ ] Create an MR with an announcement to pleroma.social -* [ ] Tag the release +* [ ] Bump version in `mix.exs` +* [ ] Compile a changelog +* [ ] Create an MR with an announcement to pleroma.social +#### post-merge +* [ ] Tag the release on the merge commit +* [ ] Make the tag into a Gitlab Release™ * [ ] Merge `stable` into `develop` (in case the fixes are already in develop, use `git merge -s ours --no-commit` and manually merge the changelogs) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1cb0243b..13641b3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - MastoFE ### Changed +- **Breaking:** Elixir >=1.10 is now required (was >= 1.9) - Allow users to remove their emails if instance does not need email to register - Uploadfilter `Pleroma.Upload.Filter.Exiftool` has been renamed to `Pleroma.Upload.Filter.Exiftool.StripLocation` +- **Breaking**: `/api/v1/pleroma/backups` endpoints now requires `read:backups` scope instead of `read:accounts` +- Updated the recommended pleroma.vcl configuration for Varnish to target Varnish 7.0+ +- Set timeout values for Oban queues. The default is infinity and some operations may not time out on their own. +- Delete activities are federated at lowest priority +- CSP now includes wasm-unsafe-eval ### Added - `activeMonth` and `activeHalfyear` fields in NodeInfo usage.users object @@ -31,6 +37,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Make backend-rendered pages translatable. This includes emails. Pages returned as a HTTP response are translated using the language specified in the `userLanguage` cookie, or the `Accept-Language` header. Emails are translated using the `language` field when registering. This language can be changed by `PATCH /api/v1/accounts/update_credentials` with the `language` field. - Add fine grained options to provide privileges to moderators and admins (e.g. delete messages, manage reports...) - Uploadfilter `Pleroma.Upload.Filter.Exiftool.ReadDescription` returns description values to the FE so they can pre fill the image description field +- Added move account API +- Enable remote users to interact with posts +- Possibility to discover users like `user@example.org`, while Pleroma is working on `pleroma.example.org`. Additional configuration required. ### Fixed - Subscription(Bell) Notifications: Don't create from Pipeline Ingested replies @@ -46,8 +55,31 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed crash when pinned_objects is nil - Fixed slow timelines when there are a lot of deactivated users - Fixed account deletion API +- Fixed lowercase HTTP HEAD method in the Media Proxy Preview code +- Removed useless notification call on Delete activities +- Improved performance for filtering out deactivated and invisible users ### Removed +- Quack, the logging backend that pushes to Slack channels + +## 2.4.5 - 2022-08-27 + +## Fixed +- Image `class` attributes not being scrubbed, allowing to exploit frontend special classes [!3792](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3792) +- Delete report notifs when demoting from superuser [!3642](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3642) +- Validate `mediaType` only by it's format rather than using a list [!3597](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3597) +- Pagination: Make mutes and blocks lists behave the same as other lists [!3693](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3693) +- Compatibility with Elixir 1.14 [!3740](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3740) +- Frontend installer: FediFE build URL [!3736](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3736) +- Streaming: Don't stream ChatMessage into the home timeline [!3738](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3738) +- Streaming: Stream local-only posts in the local timeline [!3738](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3738) +- Signatures: Fix `keyId` lookup for GoToSocial [!3725](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3725) +- Validator: Fix `replies` handling for GoToSocial [!3725](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3725) + +## 2.4.4 - 2022-08-19 + +### Security +- Streaming API sessions will now properly disconnect if the corresponding token is revoked ## 2.4.3 - 2022-05-06 diff --git a/Dockerfile b/Dockerfile index c51ebbab0..64f955b78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,18 @@ -FROM elixir:1.9-alpine as build +FROM elixir:1.11.4-alpine as build COPY . . ENV MIX_ENV=prod RUN apk add git gcc g++ musl-dev make cmake file-dev &&\ - echo "import Mix.Config" > config/prod.secret.exs &&\ + echo "import Config" > config/prod.secret.exs &&\ mix local.hex --force &&\ mix local.rebar --force &&\ mix deps.get --only prod &&\ mkdir release &&\ mix release --path release -FROM alpine:3.14 +FROM alpine ARG BUILD_DATE ARG VCS_REF diff --git a/ci/Dockerfile b/ci/Dockerfile index e6a8b438c..ca28b7029 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,7 +1,8 @@ -FROM elixir:1.9.4 +FROM elixir:1.11.4 +# Single RUN statement, otherwise intermediate images are created +# https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run RUN apt-get update &&\ - apt-get install -y libmagic-dev cmake libimage-exiftool-perl ffmpeg &&\ + apt-get install -y libmagic-dev cmake libimage-exiftool-perl ffmpeg &&\ mix local.hex --force &&\ mix local.rebar --force - diff --git a/ci/README b/ci/README new file mode 100644 index 000000000..3785adef1 --- /dev/null +++ b/ci/README @@ -0,0 +1,12 @@ +## Dependencies + +Assuming an AMD64 Alpine system, you're going to need the following packages +- `qemu qemu-openrc qemu-arm qemu-aarch64` for binfmt +- `docker-cli-buildx` for building the images + +## Setting up + +``` +docker login git.pleroma.social:5050 +doas rc-service qemu-binfmt start +``` diff --git a/config/benchmark.exs b/config/benchmark.exs index 9a7ea5669..870ead150 100644 --- a/config/benchmark.exs +++ b/config/benchmark.exs @@ -40,6 +40,7 @@ password: "postgres", database: "pleroma_benchmark", hostname: System.get_env("DB_HOST") || "localhost", + port: System.get_env("DB_PORT") || "5432", pool_size: 10 # Reduce hash rounds for testing diff --git a/config/config.exs b/config/config.exs index 7f2927e37..e41ec2f91 100644 --- a/config/config.exs +++ b/config/config.exs @@ -37,7 +37,7 @@ # FIGURATION! EDIT YOUR SECRET FILE (either prod.secret.exs, dev.secret.exs). # # This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. +# and its dependencies with the aid of the Config module. # # This configuration file is loaded before any dependency and # is restricted to this project. @@ -160,11 +160,6 @@ format: "$metadata[$level] $message", metadata: [:request_id] -config :quack, - level: :warn, - meta: [:all], - webhook_url: "https://hooks.slack.com/services/YOUR-KEY-HERE" - config :mime, :types, %{ "application/xml" => ["xml"], "application/xrd+xml" => ["xrd+xml"], @@ -228,6 +223,7 @@ max_pinned_statuses: 1, attachment_links: false, max_report_comment_size: 1000, + report_strip_status: true, safe_dm_mentions: false, healthcheck: false, remote_post_retention_days: 90, @@ -575,8 +571,8 @@ token_expiration: 5, filter_expiration: 1, backup: 1, - federator_incoming: 50, - federator_outgoing: 50, + federator_incoming: 5, + federator_outgoing: 5, ingestion_queue: 50, web_push: 50, mailer: 10, @@ -689,6 +685,8 @@ config :pleroma, :populate_hashtags_table, fault_rate_allowance: 0.01 +config :pleroma, :delete_context_objects, fault_rate_allowance: 0.01 + config :pleroma, :env, Mix.env() config :http_signatures, @@ -757,7 +755,7 @@ "name" => "fedi-fe", "git" => "https://git.pleroma.social/pleroma/fedi-fe", "build_url" => - "https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build", + "https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build_release", "ref" => "master", "custom-http-headers" => [ {"service-worker-allowed", "/"} @@ -770,13 +768,21 @@ "https://git.pleroma.social/pleroma/admin-fe/-/jobs/artifacts/${ref}/download?job=build", "ref" => "develop" }, - "soapbox-fe" => %{ - "name" => "soapbox-fe", - "git" => "https://gitlab.com/soapbox-pub/soapbox-fe", + "soapbox" => %{ + "name" => "soapbox", + "git" => "https://gitlab.com/soapbox-pub/soapbox", "build_url" => - "https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/${ref}/download?job=build-production", - "ref" => "v1.0.0", + "https://gitlab.com/soapbox-pub/soapbox/-/jobs/artifacts/${ref}/download?job=build-production", + "ref" => "v3.0.0-beta.1", "build_dir" => "static" + }, + "glitch-lily" => %{ + "name" => "glitch-lily", + "git" => "https://lily-is.land/infra/glitch-lily", + "build_url" => + "https://lily-is.land/infra/glitch-lily/-/jobs/artifacts/${ref}/download?job=build", + "ref" => "servant", + "build_dir" => "public" } } @@ -875,6 +881,8 @@ {Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy, [max_running: 5, max_waiting: 5]} ] +config :pleroma, Pleroma.Web.WebFinger, domain: nil, update_nickname_on_user_fetch: true + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/config/description.exs b/config/description.exs index b53354a79..bf4734426 100644 --- a/config/description.exs +++ b/config/description.exs @@ -495,6 +495,27 @@ } ] }, + %{ + group: :pleroma, + key: :delete_context_objects, + type: :group, + description: "`delete_context_objects` background migration settings", + children: [ + %{ + key: :fault_rate_allowance, + type: :float, + description: + "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if context object deletion failed for all records.", + suggestions: [0.01] + }, + %{ + key: :sleep_interval_ms, + type: :integer, + description: + "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." + } + ] + }, %{ group: :pleroma, key: :instance, @@ -794,6 +815,13 @@ 1_000 ] }, + %{ + key: :report_strip_status, + label: "Report strip status", + type: :boolean, + description: + "Strip associated statuses in reports to ids when closed/resolved, otherwise keep a copy" + }, %{ key: :safe_dm_mentions, label: "Safe DM mentions", @@ -1022,7 +1050,8 @@ key: :birthday_min_age, type: :integer, description: - "Minimum required age for users to create account. Only used if birthday is required." + "Minimum required age (in days) for users to create account. Only used if birthday is required.", + suggestions: [6570] } ] }, @@ -1206,45 +1235,6 @@ } ] }, - %{ - group: :quack, - type: :group, - label: "Quack Logger", - description: "Quack-related settings", - children: [ - %{ - key: :level, - type: {:dropdown, :atom}, - description: "Log level", - suggestions: [:debug, :info, :warn, :error] - }, - %{ - key: :meta, - type: {:list, :atom}, - description: "Configure which metadata you want to report on", - suggestions: [ - :application, - :module, - :file, - :function, - :line, - :pid, - :crash_reason, - :initial_call, - :registered_name, - :all, - :none - ] - }, - %{ - key: :webhook_url, - label: "Webhook URL", - type: :string, - description: "Configure the Slack incoming webhook", - suggestions: ["https://hooks.slack.com/services/YOUR-KEY-HERE"] - } - ] - }, %{ group: :pleroma, key: :frontend_configurations, @@ -1767,6 +1757,11 @@ type: :boolean, description: "Sign object fetches with HTTP signatures" }, + %{ + key: :authorized_fetch_mode, + type: :boolean, + description: "Require HTTP signatures for AP fetches" + }, %{ key: :note_replies_output_limit, type: :integer, diff --git a/config/docker.exs b/config/docker.exs index f9f27d141..5db222485 100644 --- a/config/docker.exs +++ b/config/docker.exs @@ -18,6 +18,7 @@ password: System.fetch_env!("DB_PASS"), database: System.get_env("DB_NAME", "pleroma"), hostname: System.get_env("DB_HOST", "db"), + port: System.get_env("DB_PORT", "5432"), pool_size: 10 # Configure web push notifications diff --git a/config/test.exs b/config/test.exs index d5c25f65e..78303eb1d 100644 --- a/config/test.exs +++ b/config/test.exs @@ -47,6 +47,7 @@ password: "postgres", database: "pleroma_test", hostname: System.get_env("DB_HOST") || "localhost", + port: System.get_env("DB_PORT") || "5432", pool: Ecto.Adapters.SQL.Sandbox, pool_size: 50 @@ -81,10 +82,7 @@ "BLH1qVhJItRGCfxgTtONfsOKDc9VRAraXw-3NsmjMngWSh7NxOizN6bkuRA7iLTMPS82PjwJAr3UoK9EC1IFrz4", private_key: "_-XZ0iebPrRfZ_o0-IatTdszYa8VCH1yLN-JauK7HHA" -config :pleroma, Oban, - queues: false, - crontab: false, - plugins: false +config :pleroma, Oban, testing: :manual config :pleroma, Pleroma.ScheduledActivity, daily_user_limit: 2, @@ -129,6 +127,8 @@ config :pleroma, :cachex, provider: Pleroma.CachexMock +config :pleroma, Pleroma.Web.WebFinger, update_nickname_on_user_fetch: false + config :pleroma, :side_effects, ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock, logger: Pleroma.LoggerMock diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index f56f8c50a..4691f68bb 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -3,7 +3,7 @@ set -e echo "-- Waiting for database..." -while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:5432/${DB_NAME:-pleroma} -t 1; do +while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-pleroma} -t 1; do sleep 1s done diff --git a/docs/administration/CLI_tasks/frontend.md b/docs/administration/CLI_tasks/frontend.md index d4a48cb56..4e9d9eecb 100644 --- a/docs/administration/CLI_tasks/frontend.md +++ b/docs/administration/CLI_tasks/frontend.md @@ -22,7 +22,7 @@ Currently, known `` values are: - [kenoma](http://git.pleroma.social/lambadalambda/kenoma) - [pleroma-fe](http://git.pleroma.social/pleroma/pleroma-fe) - [fedi-fe](https://git.pleroma.social/pleroma/fedi-fe) -- [soapbox-fe](https://gitlab.com/soapbox-pub/soapbox-fe) +- [soapbox](https://gitlab.com/soapbox-pub/soapbox) You can still install frontends that are not configured, see below. diff --git a/docs/administration/updating.md b/docs/administration/updating.md index 01d3b9b0e..00eca36a0 100644 --- a/docs/administration/updating.md +++ b/docs/administration/updating.md @@ -17,7 +17,7 @@ su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate" ## For from source installations (using git) 1. Go to the working directory of Pleroma (default is `/opt/pleroma`) -2. Run `git pull` [^1]. This pulls the latest changes from upstream. +2. Run `git checkout ` [^1]. e.g. `git checkout v2.4.5` This pulls the [tagged release](https://git.pleroma.social/pleroma/pleroma/-/releases) from upstream. 3. Run `mix deps.get` [^1]. This pulls in any new dependencies. 4. Stop the Pleroma service. 5. Run `mix ecto.migrate` [^1] [^2]. This task performs database migrations, if there were any. diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index c236f53d3..bbdf30a0f 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -49,6 +49,7 @@ To add configuration to your config file, you can copy it from the base config. * `autofollowing_nicknames`: Set to nicknames of (local) users that automatically follows every newly registered user. * `attachment_links`: Set to true to enable automatically adding attachment link text to statuses. * `max_report_comment_size`: The maximum size of the report comment (Default: `1000`). +* `report_strip_status`: Strip associated statuses in reports to ids when closed/resolved, otherwise keep a copy. * `safe_dm_mentions`: If set to true, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. "@friend hey i really don't like @enemy"). Default: `false`. * `healthcheck`: If set to true, system data will be shown on ``/api/v1/pleroma/healthcheck``. * `remote_post_retention_days`: The default amount of days to retain remote posts when pruning the database. @@ -234,7 +235,7 @@ config :pleroma, :mrf_user_allowlist, %{ e.g., A value of 900 results in any post with a timestamp older than 15 minutes will be acted upon. * `actions`: A list of actions to apply to the post: * `:delist` removes the post from public timelines - * `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines + * `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines, additionally for followers-only it degrades to a direct message * `:reject` rejects the message entirely #### :mrf_steal_emoji @@ -807,7 +808,7 @@ Web Push Notifications configuration. You can use the mix task `mix web_push.gen * ``private_key``: VAPID private key ## :logger -* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog, and `Quack.Logger` to log to Slack +* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog An example to enable ONLY ExSyslogger (f/ex in ``prod.secret.exs``) with info and debug suppressed: ```elixir @@ -830,10 +831,10 @@ config :logger, :ex_syslogger, See: [logger’s documentation](https://hexdocs.pm/logger/Logger.html) and [ex_syslogger’s documentation](https://hexdocs.pm/ex_syslogger/) -An example of logging info to local syslog, but warn to a Slack channel: +An example of logging info to local syslog, but debug to console: ```elixir config :logger, - backends: [ {ExSyslogger, :ex_syslogger}, Quack.Logger ], + backends: [ {ExSyslogger, :ex_syslogger}, :console ], level: :info config :logger, :ex_syslogger, @@ -841,14 +842,12 @@ config :logger, :ex_syslogger, ident: "pleroma", format: "$metadata[$level] $message" -config :quack, - level: :warn, - meta: [:all], - webhook_url: "https://hooks.slack.com/services/YOUR-API-KEY-HERE" +config :logger, :console, + level: :debug, + format: "\n$time $metadata[$level] $message\n", + metadata: [:request_id] ``` -See the [Quack Github](https://github.com/azohra/quack) for more details - ## Database options diff --git a/docs/configuration/how_to_serve_another_domain_for_webfinger.md b/docs/configuration/how_to_serve_another_domain_for_webfinger.md new file mode 100644 index 000000000..5ae3e7943 --- /dev/null +++ b/docs/configuration/how_to_serve_another_domain_for_webfinger.md @@ -0,0 +1,62 @@ +# How to use a different domain name for Pleroma and the users it serves + +Pleroma users are primarily identified by a `user@example.org` handle, and you might want this identifier to be the same as your email or jabber account, for instance. +However, in this case, you are almost certainly serving some web content on `https://example.org` already, and you might want to use another domain (say `pleroma.example.org`) for Pleroma itself. + +Pleroma supports that, but it might be tricky to set up, and any error might prevent you from federating with other instances. + +*If you are already running Pleroma on `example.org`, it is no longer possible to move it to `pleroma.example.org`.* + +## Account identifiers + +It is important to understand that for federation purposes, a user in Pleroma has two unique identifiers associated: + +- A webfinger `acct:` URI, used for discovery and as a verifiable global name for the user across Pleroma instances. In our example, our account's acct: URI is `acct:user@example.org` +- An author/actor URI, used in every other aspect of federation. This is the way in which users are identified in ActivityPub, the underlying protocol used for federation with other Pleroma instances. +In our case, it is `https://pleroma.example.org/users/user`. + +Both account identifiers are unique and required for Pleroma. An important risk if you set up your Pleroma instance incorrectly is to create two users (with different acct: URIs) with conflicting author/actor URIs. + +## WebFinger + +As said earlier, each Pleroma user has an `acct`: URI, which is used for discovery and authentication. When you add @user@example.org, a webfinger query is performed. This is done in two steps: + +1. Querying `https://example.org/.well-known/host-meta` (where the domain of the URL matches the domain part of the `acct`: URI) to get information on how to perform the query. +This file will indeed contain a URL template of the form `https://example.org/.well-known/webfinger?resource={uri}` that will be used in the second step. +2. Fill the returned template with the `acct`: URI to be queried and perform the query: `https://example.org/.well-known/webfinger?resource=acct:user@example.org` + +## Configuring your Pleroma instance + +**_DO NOT ATTEMPT TO CONFIGURE YOUR INSTANCE THIS WAY IF YOU DID NOT UNDERSTAND THE ABOVE_** + +### Configuring Pleroma + +Pleroma has a two configuration settings to enable using different domains for your users and Pleroma itself. `host` in `Pleroma.Web.Endpoint` and `domain` in `Pleroma.Web.WebFinger`. When the latter is not set, it defaults to the value of `host`. + +*Be extra careful when configuring your Pleroma instance, as changing `host` may cause remote instances to register different accounts with the same author/actor URI, which will result in federation issues!* + +```elixir +config :pleroma, Pleroma.Web.Endpoint, + url: [host: "pleroma.example.org"] + +config :pleroma, Pleroma.Web.WebFinger, domain: "example.org" +``` + +- `domain` - is the domain for which your Pleroma instance has authority, it's the domain used in `acct:` URI. In our example, `domain` would be set to `example.org`. This is used in WebFinger account ids, which are the canonical account identifier in some other fediverse software like Mastodon. **If you change `domain`, the accounts on your server will be shown as different accounts in those software**. +- `host` - is the domain used for any URL generated for your instance, including the author/actor URL's. In our case, that would be `pleroma.example.org`. This is used in AP ids, which are the canonical account identifier in Pleroma and some other fediverse software. **You should not change this after you have set up the instance**. + +### Configuring WebFinger domain + +Now, you have Pleroma running at `https://pleroma.example.org` as well as a website at `https://example.org`. If you recall how webfinger queries work, the first step is to query `https://example.org/.well-known/host-meta`, which will contain an URL template. + +Therefore, the easiest way to configure `example.org` is to redirect `/.well-known/host-meta` to `pleroma.example.org`. + +With nginx, it would be as simple as adding: + +```nginx +location = /.well-known/host-meta { + return 301 https://pleroma.example.org$request_uri; +} +``` + +in example.org's server block. diff --git a/docs/configuration/howto_database_config.md b/docs/configuration/howto_database_config.md index ae1462f9b..e5af9097a 100644 --- a/docs/configuration/howto_database_config.md +++ b/docs/configuration/howto_database_config.md @@ -59,7 +59,7 @@ The configuration of Pleroma has traditionally been managed with a config file, Here is an example of a server config stripped down after migration: ``` - use Mix.Config + import Config config :pleroma, Pleroma.Web.Endpoint, url: [host: "cool.pleroma.site", scheme: "https", port: 443] diff --git a/docs/development/API/admin_api.md b/docs/development/API/admin_api.md index c46f83839..f6e9f7d2a 100644 --- a/docs/development/API/admin_api.md +++ b/docs/development/API/admin_api.md @@ -1064,7 +1064,6 @@ List of settings which support only full update by key: ```elixir @full_key_update [ {:pleroma, :ecto_repos}, - {:quack, :meta}, {:mime, :types}, {:cors_plug, [:max_age, :methods, :expose, :headers]}, {:auto_linker, :opts}, @@ -1084,18 +1083,18 @@ List of settings which support only full update by subkey: ] ``` -*Settings without explicit key must be sended in separate config object params.* +*Settings without explicit key must be sent in separate config object params.* ```elixir -config :quack, - level: :debug, - meta: [:all], +config :foo, + bar: :baz, + meta: [:data], ... ``` ```json { "configs": [ - {"group": ":quack", "key": ":level", "value": ":debug"}, - {"group": ":quack", "key": ":meta", "value": [":all"]}, + {"group": ":foo", "key": ":bar", "value": ":baz"}, + {"group": ":foo", "key": ":meta", "value": [":data"]}, ... ] } diff --git a/docs/development/API/differences_in_mastoapi_responses.md b/docs/development/API/differences_in_mastoapi_responses.md index 73c46fff8..4007c63c8 100644 --- a/docs/development/API/differences_in_mastoapi_responses.md +++ b/docs/development/API/differences_in_mastoapi_responses.md @@ -40,6 +40,10 @@ Has these additional fields under the `pleroma` object: - `parent_visible`: If the parent of this post is visible to the user or not. - `pinned_at`: a datetime (iso8601) when status was pinned, `null` otherwise. +The `GET /api/v1/statuses/:id/source` endpoint additionally has the following attributes: + +- `content_type`: The content type of the status source. + ## Scheduled statuses Has these additional fields in `params`: diff --git a/docs/development/API/pleroma_api.md b/docs/development/API/pleroma_api.md index 0d15384b9..47fcb7479 100644 --- a/docs/development/API/pleroma_api.md +++ b/docs/development/API/pleroma_api.md @@ -342,6 +342,36 @@ See [Admin-API](admin_api.md) * Response: JSON. Returns `{"status": "success"}` if the change was successful, `{"error": "[error message]"}` otherwise * Note: Currently, Mastodon has no API for changing email. If they add it in future it might be incompatible with Pleroma. +## `/api/pleroma/move_account` +### Move account +* Method `POST` +* Authentication: required +* Params: + * `password`: user's password + * `target_account`: the nickname of the target account (e.g. `foo@example.org`) +* Response: JSON. Returns `{"status": "success"}` if the change was successful, `{"error": "[error message]"}` otherwise +* Note: This endpoint emits a `Move` activity to all followers of the current account. Some remote servers will automatically unfollow the current account and follow the target account upon seeing this, but this depends on the remote server implementation and cannot be guaranteed. For local followers , they will automatically unfollow and follow if and only if they have set the `allow_following_move` preference ("Allow auto-follow when following account moves"). + +## `/api/pleroma/aliases` +### Get aliases of the current account +* Method `GET` +* Authentication: required +* Response: JSON. Returns `{"aliases": [alias, ...]}`, where `alias` is the nickname of an alias, e.g. `foo@example.org`. + +### Add alias to the current account +* Method `PUT` +* Authentication: required +* Params: + * `alias`: the nickname of the alias to add, e.g. `foo@example.org`. +* Response: JSON. Returns `{"status": "success"}` if the change was successful, `{"error": "[error message]"}` otherwise + +### Delete alias from the current account +* Method `DELETE` +* Authentication: required +* Params: + * `alias`: the nickname of the alias to delete, e.g. `foo@example.org`. +* Response: JSON. Returns `{"status": "success"}` if the change was successful, `{"error": "[error message]"}` otherwise + # Pleroma Conversations Pleroma Conversations have the same general structure that Mastodon Conversations have. The behavior differs in the following ways when using these endpoints: @@ -695,3 +725,42 @@ Emoji reactions work a lot like favourites do. They make it possible to react to * Authentication: required * Params: none * Response: HTTP 200 on success, 500 on error + +## `/api/v1/pleroma/settings/:app` +### Gets settings for some application +* Method `GET` +* Authentication: `read:accounts` + +* Response: JSON. The settings for that application, or empty object if there is none. +* Example response: +```json +{ + "some key": "some value" +} +``` + +### Updates settings for some application +* Method `PATCH` +* Authentication: `write:accounts` +* Request body: JSON object. The object will be merged recursively with old settings. If some field is set to null, it is removed. +* Example request: +```json +{ + "some key": "some value", + "key to remove": null, + "nested field": { + "some key": "some value", + "key to remove": null + } +} +``` +* Response: JSON. Updated (merged) settings for that application. +* Example response: +```json +{ + "some key": "some value", + "nested field": { + "some key": "some value", + } +} +``` diff --git a/docs/development/setting_up_a_gitlab_runner.md b/docs/development/setting_up_a_gitlab_runner.md new file mode 100644 index 000000000..88beb82f2 --- /dev/null +++ b/docs/development/setting_up_a_gitlab_runner.md @@ -0,0 +1,9 @@ +# Setting up a Gitlab-runner + +When you push changes, a pipeline will start some automated jobs. These are done with so called [runners](https://docs.gitlab.com/runner/), services that run somewhere on a server and run these automated jobs. These jobs typically run tests and should pass. If not, you probably need to fix something. + +Generally, Pleroma provides a runner, so you don't need to set up your own. However, if for whatever reason you want to set up your own, here's some high level instructions. + +1. We use docker to run the jobs, so you should install that. For Debian, you need to allow non-free packages in the [source list](https://wiki.debian.org/SourcesList). Then you can install docker with `apt install docker-compose`. +2. You can [install](https://docs.gitlab.com/runner/install/index.html) and [configure](https://docs.gitlab.com/runner/register/index.html) a Gitlab-runner. It's probably easiest to install from the packages, but there are other options as well. +3. When registering the runner, you'll need some values. You can find them in the project under your own name. Choose "Settings", "CI/CD", and then expand "Runners". For executor you can choose "docker". For default image, you can use the image used in (although it shouldn't matter much). diff --git a/docs/installation/generic_dependencies.include b/docs/installation/generic_dependencies.include index 2dbd93e42..dcaacfdfd 100644 --- a/docs/installation/generic_dependencies.include +++ b/docs/installation/generic_dependencies.include @@ -1,7 +1,7 @@ ## Required dependencies * PostgreSQL 9.6+ -* Elixir 1.9+ +* Elixir 1.10+ * Erlang OTP 22.2+ * git * file / libmagic diff --git a/elixir_buildpack.config b/elixir_buildpack.config index 946408c12..1102e7145 100644 --- a/elixir_buildpack.config +++ b/elixir_buildpack.config @@ -1,2 +1,2 @@ -elixir_version=1.9.4 +elixir_version=1.10.4 erlang_version=22.3.4.1 diff --git a/installation/pleroma-mongooseim.cfg b/installation/pleroma-mongooseim.cfg index 576f83541..3ecba5641 100755 --- a/installation/pleroma-mongooseim.cfg +++ b/installation/pleroma-mongooseim.cfg @@ -466,7 +466,7 @@ %% == PostgreSQL == %% {rdbms, global, default, [{workers, 10}], -%% [{server, {pgsql, "server", 5432, "database", "username", "password"}}]}, +%% [{server, {pgsql, "server", "port", "database", "username", "password"}}]}, %% == ODBC (MSSQL) == %% {rdbms, global, default, [{workers, 10}], diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index 9890cb2b1..273cfb390 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -81,6 +81,19 @@ server { proxy_pass http://phoenix; } + # Uncomment this if you want notice compatibility routes for frontends like Soapbox. + # location ~ ^/@[^/]+/([^/]+)$ { + # proxy_pass http://phoenix/notice/$1; + # } + # + # location ~ ^/@[^/]+/posts/([^/]+)$ { + # proxy_pass http://phoenix/notice/$1; + # } + # + # location ~ ^/[^/]+/status/([^/]+)$ { + # proxy_pass http://phoenix/notice/$1; + # } + location ~ ^/(media|proxy) { proxy_cache pleroma_media_cache; slice 1m; diff --git a/installation/pleroma.vcl b/installation/pleroma.vcl index 4752510ea..4eb2f3cfa 100644 --- a/installation/pleroma.vcl +++ b/installation/pleroma.vcl @@ -1,4 +1,5 @@ # Recommended varnishncsa logging format: '%h %l %u %t "%m %{X-Forwarded-Proto}i://%{Host}i%U%q %H" %s %b "%{Referer}i" "%{User-agent}i"' +# Please use Varnish 7.0+ for proper Range Requests / Chunked encoding support vcl 4.1; import std; @@ -22,11 +23,6 @@ sub vcl_recv { set req.http.X-Forwarded-Proto = "https"; } - # CHUNKED SUPPORT - if (req.http.Range ~ "bytes=") { - set req.http.x-range = req.http.Range; - } - # Pipe if WebSockets request is coming through if (req.http.upgrade ~ "(?i)websocket") { return (pipe); @@ -35,9 +31,9 @@ sub vcl_recv { # Allow purging of the cache if (req.method == "PURGE") { if (!client.ip ~ purge) { - return(synth(405,"Not allowed.")); + return (synth(405,"Not allowed.")); } - return(purge); + return (purge); } } @@ -53,17 +49,11 @@ sub vcl_backend_response { return (retry); } - # CHUNKED SUPPORT - if (bereq.http.x-range ~ "bytes=" && beresp.status == 206) { - set beresp.ttl = 10m; - set beresp.http.CR = beresp.http.content-range; - } - # Bypass cache for large files # 50000000 ~ 50MB if (std.integer(beresp.http.content-length, 0) > 50000000) { set beresp.uncacheable = true; - return(deliver); + return (deliver); } # Don't cache objects that require authentication @@ -94,7 +84,7 @@ sub vcl_synth { if (resp.status == 750) { set resp.status = 301; set resp.http.Location = req.http.x-redir; - return(deliver); + return (deliver); } } @@ -106,25 +96,12 @@ sub vcl_pipe { } } -sub vcl_hash { - # CHUNKED SUPPORT - if (req.http.x-range ~ "bytes=") { - hash_data(req.http.x-range); - unset req.http.Range; - } -} - sub vcl_backend_fetch { # Be more lenient for slow servers on the fediverse if (bereq.url ~ "^/proxy/") { set bereq.first_byte_timeout = 300s; } - # CHUNKED SUPPORT - if (bereq.http.x-range) { - set bereq.http.Range = bereq.http.x-range; - } - if (bereq.retries == 0) { # Clean up the X-Varnish-Backend-503 flag that is used internally # to mark broken backend responses that should be retried. @@ -143,14 +120,6 @@ sub vcl_backend_fetch { } } -sub vcl_deliver { - # CHUNKED SUPPORT - if (resp.http.CR) { - set resp.http.Content-Range = resp.http.CR; - unset resp.http.CR; - } -} - sub vcl_backend_error { # Retry broken backend responses. set bereq.http.X-Varnish-Backend-503 = "1"; diff --git a/lib/mix/tasks/pleroma/config.ex b/lib/mix/tasks/pleroma/config.ex index 33d147d36..3a2ea44f8 100644 --- a/lib/mix/tasks/pleroma/config.ex +++ b/lib/mix/tasks/pleroma/config.ex @@ -304,13 +304,8 @@ defp write_config(file, path, opts) do System.cmd("mix", ["format", path]) end - if Code.ensure_loaded?(Config.Reader) do - defp config_header, do: "import Config\r\n\r\n" - defp read_file(config_file), do: Config.Reader.read_imports!(config_file) - else - defp config_header, do: "use Mix.Config\r\n\r\n" - defp read_file(config_file), do: Mix.Config.eval!(config_file) - end + defp config_header, do: "import Config\r\n\r\n" + defp read_file(config_file), do: Config.Reader.read_imports!(config_file) defp write_and_delete(config, file, delete?) do config diff --git a/lib/mix/tasks/pleroma/database.ex b/lib/mix/tasks/pleroma/database.ex index 6b8f0ef68..ed560c177 100644 --- a/lib/mix/tasks/pleroma/database.ex +++ b/lib/mix/tasks/pleroma/database.ex @@ -154,9 +154,8 @@ def run(["ensure_expiration"]) do |> join(:inner, [a], o in Object, on: fragment( - "(?->>'id') = COALESCE((?)->'object'->> 'id', (?)->>'object')", + "(?->>'id') = associated_object_id((?))", o.data, - a.data, a.data ) ) diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 96d4eb90b..929fa1717 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -112,9 +112,10 @@ def run(["reset_password", nickname]) do {:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do shell_info("Generated password reset token for #{user.nickname}") - IO.puts("URL: #{Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint, - :reset, - token.token)}") + url = + Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint, :reset, token.token) + + IO.puts("URL: #{url}") else _ -> shell_error("No local user #{nickname}") @@ -421,6 +422,38 @@ def run(["list"]) do |> Stream.run() end + def run(["fix_follow_state", local_user, remote_user]) do + start_pleroma() + + with {:local, %User{} = local} <- {:local, User.get_by_nickname(local_user)}, + {:remote, %User{} = remote} <- {:remote, User.get_by_nickname(remote_user)}, + {:follow_data, %{data: %{"state" => request_state}}} <- + {:follow_data, Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(local, remote)} do + calculated_state = User.following?(local, remote) + + shell_info( + "Request state is #{request_state}, vs calculated state of following=#{calculated_state}" + ) + + if calculated_state == false && request_state == "accept" do + shell_info("Discrepancy found, fixing") + Pleroma.Web.CommonAPI.reject_follow_request(local, remote) + shell_info("Relationship fixed") + else + shell_info("No discrepancy found") + end + else + {:local, _} -> + shell_error("No local user #{local_user}") + + {:remote, _} -> + shell_error("No remote user #{remote_user}") + + {:follow_data, _} -> + shell_error("No follow data for #{local_user} and #{remote_user}") + end + end + defp set_moderator(user, value) do {:ok, user} = user diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 12c1a3b2e..3556aaf9e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -53,7 +53,7 @@ defmodule Pleroma.Activity do # # ``` # |> join(:inner, [activity], o in Object, - # on: fragment("(?->>'id') = COALESCE((?)->'object'->> 'id', (?)->>'object')", + # on: fragment("(?->>'id') = associated_object_id((?))", # o.data, activity.data, activity.data)) # |> preload([activity, object], [object: object]) # ``` @@ -69,9 +69,8 @@ def with_joined_object(query, join_type \\ :inner) do join(query, join_type, [activity], o in Object, on: fragment( - "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')", + "(?->>'id') = associated_object_id(?)", o.data, - activity.data, activity.data ), as: :object @@ -362,9 +361,11 @@ def following_requests_for_actor(%User{ap_id: ap_id}) do end def restrict_deactivated_users(query) do - deactivated_users_query = from(u in User.Query.build(%{deactivated: true}), select: u.ap_id) - - from(activity in query, where: activity.actor not in subquery(deactivated_users_query)) + query + |> join(:inner, [activity], user in User, + as: :user, + on: activity.actor == user.ap_id and user.is_active == true + ) end defdelegate search(user, query, options \\ []), to: Pleroma.Activity.Search diff --git a/lib/pleroma/activity/html.ex b/lib/pleroma/activity/html.ex index 071a89c8d..706b2d36c 100644 --- a/lib/pleroma/activity/html.ex +++ b/lib/pleroma/activity/html.ex @@ -8,6 +8,40 @@ defmodule Pleroma.Activity.HTML do @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + # We store a list of cache keys related to an activity in a + # separate cache, scrubber_management_cache. It has the same + # size as scrubber_cache (see application.ex). Every time we add + # a cache to scrubber_cache, we update scrubber_management_cache. + # + # The most recent write of a certain key in the management cache + # is the same as the most recent write of any record related to that + # key in the main cache. + # Assuming LRW ( https://hexdocs.pm/cachex/Cachex.Policy.LRW.html ), + # this means when the management cache is evicted by cachex, all + # related records in the main cache will also have been evicted. + + defp get_cache_keys_for(activity_id) do + with {:ok, list} when is_list(list) <- @cachex.get(:scrubber_management_cache, activity_id) do + list + else + _ -> [] + end + end + + defp add_cache_key_for(activity_id, additional_key) do + current = get_cache_keys_for(activity_id) + + unless additional_key in current do + @cachex.put(:scrubber_management_cache, activity_id, [additional_key | current]) + end + end + + def invalidate_cache_for(activity_id) do + keys = get_cache_keys_for(activity_id) + Enum.map(keys, &@cachex.del(:scrubber_cache, &1)) + @cachex.del(:scrubber_management_cache, activity_id) + end + def get_cached_scrubbed_html_for_activity( content, scrubbers, @@ -19,6 +53,8 @@ def get_cached_scrubbed_html_for_activity( @cachex.fetch!(:scrubber_cache, key, fn _key -> object = Object.normalize(activity, fetch: false) + + add_cache_key_for(activity.id, key) HTML.ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback) end) end diff --git a/lib/pleroma/activity/ir/topics.ex b/lib/pleroma/activity/ir/topics.ex index 56c52e9d1..8249cbe27 100644 --- a/lib/pleroma/activity/ir/topics.ex +++ b/lib/pleroma/activity/ir/topics.ex @@ -13,6 +13,14 @@ def get_activity_topics(activity) do |> List.flatten() end + defp generate_topics(%{data: %{"type" => "ChatMessage"}}, %{data: %{"type" => "Delete"}}) do + ["user", "user:pleroma_chat"] + end + + defp generate_topics(%{data: %{"type" => "ChatMessage"}}, %{data: %{"type" => "Create"}}) do + [] + end + defp generate_topics(%{data: %{"type" => "Answer"}}, _) do [] end @@ -21,7 +29,7 @@ defp generate_topics(object, activity) do ["user", "list"] ++ visibility_tags(object, activity) end - defp visibility_tags(object, activity) do + defp visibility_tags(object, %{data: %{"type" => type}} = activity) when type != "Announce" do case Visibility.get_visibility(activity) do "public" -> if activity.local do @@ -31,6 +39,10 @@ defp visibility_tags(object, activity) do end |> item_creation_tags(object, activity) + "local" -> + ["public:local"] + |> item_creation_tags(object, activity) + "direct" -> ["direct"] @@ -39,6 +51,10 @@ defp visibility_tags(object, activity) do end end + defp visibility_tags(_object, _activity) do + [] + end + defp item_creation_tags(tags, object, %{data: %{"type" => "Create"}} = activity) do tags ++ remote_topics(activity) ++ hashtags_to_topics(object) ++ attachment_topics(object, activity) @@ -63,7 +79,18 @@ defp remote_topics(_), do: [] defp attachment_topics(%{data: %{"attachment" => []}}, _act), do: [] - defp attachment_topics(_object, %{local: true}), do: ["public:media", "public:local:media"] + defp attachment_topics(_object, %{local: true} = activity) do + case Visibility.get_visibility(activity) do + "public" -> + ["public:media", "public:local:media"] + + "local" -> + ["public:local:media"] + + _ -> + [] + end + end defp attachment_topics(_object, %{actor: actor}) when is_binary(actor), do: ["public:media", "public:remote:media:" <> URI.parse(actor).host] diff --git a/lib/pleroma/activity/queries.ex b/lib/pleroma/activity/queries.ex index a898b2ea7..81c44ac05 100644 --- a/lib/pleroma/activity/queries.ex +++ b/lib/pleroma/activity/queries.ex @@ -52,8 +52,7 @@ def by_object_id(query, object_ids) when is_list(object_ids) do activity in query, where: fragment( - "coalesce((?)->'object'->>'id', (?)->>'object') = ANY(?)", - activity.data, + "associated_object_id((?)) = ANY(?)", activity.data, ^object_ids ) @@ -64,8 +63,7 @@ def by_object_id(query, object_id) when is_binary(object_id) do from(activity in query, where: fragment( - "coalesce((?)->'object'->>'id', (?)->>'object') = ?", - activity.data, + "associated_object_id((?)) = ?", activity.data, ^object_id ) diff --git a/lib/pleroma/activity/search.ex b/lib/pleroma/activity/search.ex index 694dc5709..0b9b24aa4 100644 --- a/lib/pleroma/activity/search.ex +++ b/lib/pleroma/activity/search.ex @@ -30,7 +30,7 @@ def search(user, search_query, options \\ []) do Activity |> Activity.with_preloaded_object() |> Activity.restrict_deactivated_users() - |> restrict_public() + |> restrict_public(user) |> query_with(index_type, search_query, search_function) |> maybe_restrict_local(user) |> maybe_restrict_author(author) @@ -57,7 +57,19 @@ def maybe_restrict_blocked(query, %User{} = user) do def maybe_restrict_blocked(query, _), do: query - defp restrict_public(q) do + defp restrict_public(q, user) when not is_nil(user) do + intended_recipients = [ + Pleroma.Constants.as_public(), + Pleroma.Web.ActivityPub.Utils.as_local_public() + ] + + from([a, o] in q, + where: fragment("?->>'type' = 'Create'", a.data), + where: fragment("? && ?", ^intended_recipients, a.recipients) + ) + end + + defp restrict_public(q, _user) do from([a, o] in q, where: fragment("?->>'type' = 'Create'", a.data), where: ^Pleroma.Constants.as_public() in a.recipients diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index d808bc732..1c1db8c10 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -94,7 +94,8 @@ def start(_type, _args) do Pleroma.Repo, Config.TransferTask, Pleroma.Emoji, - Pleroma.Web.Plugs.RateLimiter.Supervisor + Pleroma.Web.Plugs.RateLimiter.Supervisor, + {Task.Supervisor, name: Pleroma.TaskSupervisor} ] ++ cachex_children() ++ http_children(adapter, @mix_env) ++ @@ -112,7 +113,17 @@ def start(_type, _args) do # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options - opts = [strategy: :one_for_one, name: Pleroma.Supervisor] + # If we have a lot of caches, default max_restarts can cause test + # resets to fail. + # Go for the default 3 unless we're in test + max_restarts = + if @mix_env == :test do + 100 + else + 3 + end + + opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts] result = Supervisor.start_link(children, opts) set_postgres_server_version() @@ -189,6 +200,7 @@ defp cachex_children do build_cachex("object", default_ttl: 25_000, ttl_interval: 1000, limit: 2500), build_cachex("rich_media", default_ttl: :timer.minutes(120), limit: 5000), build_cachex("scrubber", limit: 2500), + build_cachex("scrubber_management", limit: 2500), build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500), build_cachex("web_resp", limit: 2500), build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10), @@ -238,7 +250,8 @@ defp dont_run_in_test(_) do defp background_migrators do [ - Pleroma.Migrators.HashtagsTableMigrator + Pleroma.Migrators.HashtagsTableMigrator, + Pleroma.Migrators.ContextObjectsDeletionMigrator ] end diff --git a/lib/pleroma/bbs/handler.ex b/lib/pleroma/bbs/handler.ex index a3b623bdf..27799338f 100644 --- a/lib/pleroma/bbs/handler.ex +++ b/lib/pleroma/bbs/handler.ex @@ -42,8 +42,45 @@ defp loop(state) do def puts_activity(activity) do status = Pleroma.Web.MastodonAPI.StatusView.render("show.json", %{activity: activity}) + IO.puts("-- #{status.id} by #{status.account.display_name} (#{status.account.acct})") - IO.puts(HTML.strip_tags(status.content)) + + status.content + |> String.split("
") + |> Enum.map(&HTML.strip_tags/1) + |> Enum.map(&HtmlEntities.decode/1) + |> Enum.map(&IO.puts/1) + end + + def puts_notification(activity, user) do + notification = + Pleroma.Web.MastodonAPI.NotificationView.render("show.json", %{ + notification: activity, + for: user + }) + + IO.puts( + "== (#{notification.type}) #{notification.status.id} by #{notification.account.display_name} (#{notification.account.acct})" + ) + + notification.status.content + |> String.split("
") + |> Enum.map(&HTML.strip_tags/1) + |> Enum.map(&HtmlEntities.decode/1) + |> (fn x -> + case x do + [content] -> + "> " <> content + + [head | _tail] -> + # "> " <> hd <> "..." + head + |> String.slice(1, 80) + |> (fn x -> "> " <> x <> "..." end).() + end + end).() + |> IO.puts() + IO.puts("") end @@ -53,6 +90,11 @@ def handle_command(state, "help") do IO.puts("home - Show the home timeline") IO.puts("p - Post the given text") IO.puts("r - Reply to the post with the given id") + IO.puts("t - Show a thread from the given id") + IO.puts("n - Show notifications") + IO.puts("n read - Mark all notifactions as read") + IO.puts("f - Favourites the post with the given id") + IO.puts("R - Repeat the post with the given id") IO.puts("quit - Quit") state @@ -73,11 +115,53 @@ def handle_command(%{user: user} = state, "r " <> text) do state end + def handle_command(%{user: user} = state, "t " <> activity_id) do + with %Activity{} = activity <- Activity.get_by_id(activity_id) do + activities = + ActivityPub.fetch_activities_for_context(activity.data["context"], %{ + blocking_user: user, + user: user, + exclude_id: activity.id + }) + + case activities do + [] -> + activity_id + |> Activity.get_by_id() + |> puts_activity() + + _ -> + activities + |> Enum.reverse() + |> Enum.each(&puts_activity/1) + end + else + _e -> IO.puts("Could not show this thread...") + end + + state + end + + def handle_command(%{user: user} = state, "n read") do + Pleroma.Notification.clear(user) + IO.puts("All notifications were marked as read") + + state + end + + def handle_command(%{user: user} = state, "n") do + user + |> Pleroma.Web.MastodonAPI.MastodonAPI.get_notifications(%{}) + |> Enum.each(&puts_notification(&1, user)) + + state + end + def handle_command(%{user: user} = state, "p " <> text) do text = String.trim(text) - with {:ok, _activity} <- CommonAPI.post(user, %{status: text}) do - IO.puts("Posted!") + with {:ok, activity} <- CommonAPI.post(user, %{status: text}) do + IO.puts("Posted! ID: #{activity.id}") else _e -> IO.puts("Could not post...") end @@ -85,6 +169,19 @@ def handle_command(%{user: user} = state, "p " <> text) do state end + def handle_command(%{user: user} = state, "f " <> id) do + id = String.trim(id) + + with %Activity{} = activity <- Activity.get_by_id(id), + {:ok, _activity} <- CommonAPI.favorite(user, activity) do + IO.puts("Favourited!") + else + _e -> IO.puts("Could not Favourite...") + end + + state + end + def handle_command(state, "home") do user = state.user @@ -123,7 +220,7 @@ defp wait_input(state, input) do loop(%{state | counter: state.counter + 1}) - {:error, :interrupted} -> + {:input, ^input, {:error, :interrupted}} -> IO.puts("Caught Ctrl+C...") loop(%{state | counter: state.counter + 1}) diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 599f1d3cf..b53b15d95 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -311,7 +311,7 @@ def check_gun_pool_options do warning_preface = """ !!!DEPRECATION WARNING!!! - Your config is using old setting name `timeout` instead of `recv_timeout` in pool settings. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later. + Your config is using old setting name `timeout` instead of `recv_timeout` in pool settings. The setting will not take effect until updated. """ updated_config = diff --git a/lib/pleroma/config/loader.ex b/lib/pleroma/config/loader.ex index 015be3d8e..bd85eccab 100644 --- a/lib/pleroma/config/loader.ex +++ b/lib/pleroma/config/loader.ex @@ -19,21 +19,10 @@ defmodule Pleroma.Config.Loader do :tesla ] - if Code.ensure_loaded?(Config.Reader) do - @reader Config.Reader - - def read(path), do: @reader.read!(path) - else - # support for Elixir less than 1.9 - @reader Mix.Config - def read(path) do - path - |> @reader.eval!() - |> elem(0) - end - end + @reader Config.Reader @spec read(Path.t()) :: keyword() + def read(path), do: @reader.read!(path) @spec merge(keyword(), keyword()) :: keyword() def merge(c1, c2), do: @reader.merge(c1, c2) diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex index 4199630af..44a984019 100644 --- a/lib/pleroma/config/transfer_task.ex +++ b/lib/pleroma/config/transfer_task.ex @@ -47,7 +47,7 @@ def load_and_update_env(deleted_settings \\ [], restart_pleroma? \\ true) do {logger, other} = (Repo.all(ConfigDB) ++ deleted_settings) |> Enum.map(&merge_with_default/1) - |> Enum.split_with(fn {group, _, _, _} -> group in [:logger, :quack] end) + |> Enum.split_with(fn {group, _, _, _} -> group in [:logger] end) logger |> Enum.sort() @@ -104,11 +104,6 @@ defp merge_with_default(%{group: group, key: key, value: value} = setting) do end # change logger configuration in runtime, without restart - defp configure({:quack, key, _, merged}) do - Logger.configure_backend(Quack.Logger, [{key, merged}]) - :ok = update_env(:quack, key, merged) - end - defp configure({_, :backends, _, merged}) do # removing current backends Enum.each(Application.get_env(:logger, :backends), &Logger.remove_backend/1) diff --git a/lib/pleroma/config_db.ex b/lib/pleroma/config_db.ex index 6befbbe19..846cede04 100644 --- a/lib/pleroma/config_db.ex +++ b/lib/pleroma/config_db.ex @@ -163,7 +163,6 @@ defp can_be_partially_updated?(%ConfigDB{} = config), do: not only_full_update?( defp only_full_update?(%ConfigDB{group: group, key: key}) do full_key_update = [ {:pleroma, :ecto_repos}, - {:quack, :meta}, {:mime, :types}, {:cors_plug, [:max_age, :methods, :expose, :headers]}, {:swarm, :node_blacklist}, @@ -386,7 +385,7 @@ defp find_valid_delimiter([delimiter | others], pattern, regex_delimiter) do @spec module_name?(String.t()) :: boolean() def module_name?(string) do - Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Quack|Ueberauth|Swoosh)\./, string) or + Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Ueberauth|Swoosh)\./, string) or string in ["Oban", "Ueberauth", "ExSyslogger", "ConcurrentLimiter"] end end diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex index 7b63ab06e..cfb405218 100644 --- a/lib/pleroma/constants.ex +++ b/lib/pleroma/constants.ex @@ -28,6 +28,42 @@ defmodule Pleroma.Constants do ~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css) ) + const(status_updatable_fields, + do: [ + "source", + "tag", + "updated", + "emoji", + "content", + "summary", + "sensitive", + "attachment", + "generator" + ] + ) + + const(updatable_object_types, + do: [ + "Note", + "Question", + "Audio", + "Video", + "Event", + "Article", + "Page" + ] + ) + + const(actor_types, + do: [ + "Application", + "Group", + "Organization", + "Person", + "Service" + ] + ) + # basic regex, just there to weed out potential mistakes # https://datatracker.ietf.org/doc/html/rfc2045#section-5.1 const(mime_regex, diff --git a/lib/pleroma/data_migration.ex b/lib/pleroma/data_migration.ex index 59d891d8d..8451678fc 100644 --- a/lib/pleroma/data_migration.ex +++ b/lib/pleroma/data_migration.ex @@ -42,4 +42,5 @@ def get_by_name(name) do end def populate_hashtags_table, do: get_by_name("populate_hashtags_table") + def delete_context_objects, do: get_by_name("delete_context_objects") end diff --git a/lib/pleroma/docs/translator.ex b/lib/pleroma/docs/translator.ex new file mode 100644 index 000000000..13e33c87e --- /dev/null +++ b/lib/pleroma/docs/translator.ex @@ -0,0 +1,10 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Docs.Translator do + require Pleroma.Docs.Translator.Compiler + require Pleroma.Web.Gettext + + @before_compile Pleroma.Docs.Translator.Compiler +end diff --git a/lib/pleroma/docs/translator/compiler.ex b/lib/pleroma/docs/translator/compiler.ex new file mode 100644 index 000000000..5d27d9fa2 --- /dev/null +++ b/lib/pleroma/docs/translator/compiler.ex @@ -0,0 +1,119 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Docs.Translator.Compiler do + @external_resource "config/description.exs" + @raw_config Pleroma.Config.Loader.read("config/description.exs") + @raw_descriptions @raw_config[:pleroma][:config_description] + + defmacro __before_compile__(_env) do + strings = + __MODULE__.descriptions() + |> __MODULE__.extract_strings() + + quote do + def placeholder do + unquote do + Enum.map( + strings, + fn {path, type, string} -> + ctxt = msgctxt_for(path, type) + + quote do + Pleroma.Web.Gettext.dpgettext_noop( + "config_descriptions", + unquote(ctxt), + unquote(string) + ) + end + end + ) + end + end + end + end + + def descriptions do + Pleroma.Web.ActivityPub.MRF.config_descriptions() + |> Enum.reduce(@raw_descriptions, fn description, acc -> [description | acc] end) + |> Pleroma.Docs.Generator.convert_to_strings() + end + + def extract_strings(descriptions) do + descriptions + |> Enum.reduce(%{strings: [], path: []}, &process_item/2) + |> Map.get(:strings) + end + + defp process_item(entity, acc) do + current_level = + acc + |> process_desc(entity) + |> process_label(entity) + + process_children(entity, current_level) + end + + defp process_desc(acc, %{description: desc} = item) do + %{ + strings: [{acc.path ++ [key_for(item)], "description", desc} | acc.strings], + path: acc.path + } + end + + defp process_desc(acc, _) do + acc + end + + defp process_label(acc, %{label: label} = item) do + %{ + strings: [{acc.path ++ [key_for(item)], "label", label} | acc.strings], + path: acc.path + } + end + + defp process_label(acc, _) do + acc + end + + defp process_children(%{children: children} = item, acc) do + current_level = Map.put(acc, :path, acc.path ++ [key_for(item)]) + + children + |> Enum.reduce(current_level, &process_item/2) + |> Map.put(:path, acc.path) + end + + defp process_children(_, acc) do + acc + end + + def msgctxt_for(path, type) do + "config #{type} at #{Enum.join(path, " > ")}" + end + + defp convert_group({_, group}) do + group + end + + defp convert_group(group) do + group + end + + def key_for(%{group: group, key: key}) do + "#{convert_group(group)}-#{key}" + end + + def key_for(%{group: group}) do + convert_group(group) + end + + def key_for(%{key: key}) do + key + end + + def key_for(_) do + nil + end +end diff --git a/lib/pleroma/emoji-test.txt b/lib/pleroma/emoji-test.txt index dd5493366..87d093d64 100644 --- a/lib/pleroma/emoji-test.txt +++ b/lib/pleroma/emoji-test.txt @@ -1,13 +1,13 @@ # emoji-test.txt -# Date: 2021-08-26, 17:22:23 GMT -# © 2021 Unicode®, Inc. +# Date: 2022-08-12, 20:24:39 GMT +# © 2022 Unicode®, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see http://www.unicode.org/terms_of_use.html +# For terms of use, see https://www.unicode.org/terms_of_use.html # # Emoji Keyboard/Display Test Data for UTS #51 -# Version: 14.0 +# Version: 15.0 # -# For documentation and usage, see http://www.unicode.org/reports/tr51 +# For documentation and usage, see https://www.unicode.org/reports/tr51 # # This file provides data for testing which emoji forms should be in keyboards and which should also be displayed/processed. # Format: code points; status # emoji name @@ -92,6 +92,7 @@ 1F62C ; fully-qualified # 😬 E1.0 grimacing face 1F62E 200D 1F4A8 ; fully-qualified # 😮‍💨 E13.1 face exhaling 1F925 ; fully-qualified # 🤥 E3.0 lying face +1FAE8 ; fully-qualified # 🫨 E15.0 shaking face # subgroup: face-sleepy 1F60C ; fully-qualified # 😌 E0.6 relieved face @@ -155,7 +156,7 @@ # subgroup: face-negative 1F624 ; fully-qualified # 😤 E0.6 face with steam from nose -1F621 ; fully-qualified # 😡 E0.6 pouting face +1F621 ; fully-qualified # 😡 E0.6 enraged face 1F620 ; fully-qualified # 😠 E0.6 angry face 1F92C ; fully-qualified # 🤬 E5.0 face with symbols on mouth 1F608 ; fully-qualified # 😈 E1.0 smiling face with horns @@ -190,8 +191,7 @@ 1F649 ; fully-qualified # 🙉 E0.6 hear-no-evil monkey 1F64A ; fully-qualified # 🙊 E0.6 speak-no-evil monkey -# subgroup: emotion -1F48B ; fully-qualified # 💋 E0.6 kiss mark +# subgroup: heart 1F48C ; fully-qualified # 💌 E0.6 love letter 1F498 ; fully-qualified # 💘 E0.6 heart with arrow 1F49D ; fully-qualified # 💝 E0.6 heart with ribbon @@ -210,14 +210,20 @@ 2764 200D 1FA79 ; unqualified # ❤‍🩹 E13.1 mending heart 2764 FE0F ; fully-qualified # ❤️ E0.6 red heart 2764 ; unqualified # ❤ E0.6 red heart +1FA77 ; fully-qualified # 🩷 E15.0 pink heart 1F9E1 ; fully-qualified # 🧡 E5.0 orange heart 1F49B ; fully-qualified # 💛 E0.6 yellow heart 1F49A ; fully-qualified # 💚 E0.6 green heart 1F499 ; fully-qualified # 💙 E0.6 blue heart +1FA75 ; fully-qualified # 🩵 E15.0 light blue heart 1F49C ; fully-qualified # 💜 E0.6 purple heart 1F90E ; fully-qualified # 🤎 E12.0 brown heart 1F5A4 ; fully-qualified # 🖤 E3.0 black heart +1FA76 ; fully-qualified # 🩶 E15.0 grey heart 1F90D ; fully-qualified # 🤍 E12.0 white heart + +# subgroup: emotion +1F48B ; fully-qualified # 💋 E0.6 kiss mark 1F4AF ; fully-qualified # 💯 E0.6 hundred points 1F4A2 ; fully-qualified # 💢 E0.6 anger symbol 1F4A5 ; fully-qualified # 💥 E0.6 collision @@ -226,21 +232,20 @@ 1F4A8 ; fully-qualified # 💨 E0.6 dashing away 1F573 FE0F ; fully-qualified # 🕳️ E0.7 hole 1F573 ; unqualified # 🕳 E0.7 hole -1F4A3 ; fully-qualified # 💣 E0.6 bomb 1F4AC ; fully-qualified # 💬 E0.6 speech balloon 1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # 👁️‍🗨️ E2.0 eye in speech bubble 1F441 200D 1F5E8 FE0F ; unqualified # 👁‍🗨️ E2.0 eye in speech bubble -1F441 FE0F 200D 1F5E8 ; unqualified # 👁️‍🗨 E2.0 eye in speech bubble +1F441 FE0F 200D 1F5E8 ; minimally-qualified # 👁️‍🗨 E2.0 eye in speech bubble 1F441 200D 1F5E8 ; unqualified # 👁‍🗨 E2.0 eye in speech bubble 1F5E8 FE0F ; fully-qualified # 🗨️ E2.0 left speech bubble 1F5E8 ; unqualified # 🗨 E2.0 left speech bubble 1F5EF FE0F ; fully-qualified # 🗯️ E0.7 right anger bubble 1F5EF ; unqualified # 🗯 E0.7 right anger bubble 1F4AD ; fully-qualified # 💭 E1.0 thought balloon -1F4A4 ; fully-qualified # 💤 E0.6 zzz +1F4A4 ; fully-qualified # 💤 E0.6 ZZZ -# Smileys & Emotion subtotal: 177 -# Smileys & Emotion subtotal: 177 w/o modifiers +# Smileys & Emotion subtotal: 180 +# Smileys & Emotion subtotal: 180 w/o modifiers # group: People & Body @@ -300,6 +305,18 @@ 1FAF4 1F3FD ; fully-qualified # 🫴🏽 E14.0 palm up hand: medium skin tone 1FAF4 1F3FE ; fully-qualified # 🫴🏾 E14.0 palm up hand: medium-dark skin tone 1FAF4 1F3FF ; fully-qualified # 🫴🏿 E14.0 palm up hand: dark skin tone +1FAF7 ; fully-qualified # 🫷 E15.0 leftwards pushing hand +1FAF7 1F3FB ; fully-qualified # 🫷🏻 E15.0 leftwards pushing hand: light skin tone +1FAF7 1F3FC ; fully-qualified # 🫷🏼 E15.0 leftwards pushing hand: medium-light skin tone +1FAF7 1F3FD ; fully-qualified # 🫷🏽 E15.0 leftwards pushing hand: medium skin tone +1FAF7 1F3FE ; fully-qualified # 🫷🏾 E15.0 leftwards pushing hand: medium-dark skin tone +1FAF7 1F3FF ; fully-qualified # 🫷🏿 E15.0 leftwards pushing hand: dark skin tone +1FAF8 ; fully-qualified # 🫸 E15.0 rightwards pushing hand +1FAF8 1F3FB ; fully-qualified # 🫸🏻 E15.0 rightwards pushing hand: light skin tone +1FAF8 1F3FC ; fully-qualified # 🫸🏼 E15.0 rightwards pushing hand: medium-light skin tone +1FAF8 1F3FD ; fully-qualified # 🫸🏽 E15.0 rightwards pushing hand: medium skin tone +1FAF8 1F3FE ; fully-qualified # 🫸🏾 E15.0 rightwards pushing hand: medium-dark skin tone +1FAF8 1F3FF ; fully-qualified # 🫸🏿 E15.0 rightwards pushing hand: dark skin tone # subgroup: hand-fingers-partial 1F44C ; fully-qualified # 👌 E0.6 OK hand @@ -473,11 +490,11 @@ 1F932 1F3FE ; fully-qualified # 🤲🏾 E5.0 palms up together: medium-dark skin tone 1F932 1F3FF ; fully-qualified # 🤲🏿 E5.0 palms up together: dark skin tone 1F91D ; fully-qualified # 🤝 E3.0 handshake -1F91D 1F3FB ; fully-qualified # 🤝🏻 E3.0 handshake: light skin tone -1F91D 1F3FC ; fully-qualified # 🤝🏼 E3.0 handshake: medium-light skin tone -1F91D 1F3FD ; fully-qualified # 🤝🏽 E3.0 handshake: medium skin tone -1F91D 1F3FE ; fully-qualified # 🤝🏾 E3.0 handshake: medium-dark skin tone -1F91D 1F3FF ; fully-qualified # 🤝🏿 E3.0 handshake: dark skin tone +1F91D 1F3FB ; fully-qualified # 🤝🏻 E14.0 handshake: light skin tone +1F91D 1F3FC ; fully-qualified # 🤝🏼 E14.0 handshake: medium-light skin tone +1F91D 1F3FD ; fully-qualified # 🤝🏽 E14.0 handshake: medium skin tone +1F91D 1F3FE ; fully-qualified # 🤝🏾 E14.0 handshake: medium-dark skin tone +1F91D 1F3FF ; fully-qualified # 🤝🏿 E14.0 handshake: dark skin tone 1FAF1 1F3FB 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏻‍🫲🏼 E14.0 handshake: light skin tone, medium-light skin tone 1FAF1 1F3FB 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏻‍🫲🏽 E14.0 handshake: light skin tone, medium skin tone 1FAF1 1F3FB 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏻‍🫲🏾 E14.0 handshake: light skin tone, medium-dark skin tone @@ -1455,7 +1472,7 @@ 1F575 1F3FF ; fully-qualified # 🕵🏿 E2.0 detective: dark skin tone 1F575 FE0F 200D 2642 FE0F ; fully-qualified # 🕵️‍♂️ E4.0 man detective 1F575 200D 2642 FE0F ; unqualified # 🕵‍♂️ E4.0 man detective -1F575 FE0F 200D 2642 ; unqualified # 🕵️‍♂ E4.0 man detective +1F575 FE0F 200D 2642 ; minimally-qualified # 🕵️‍♂ E4.0 man detective 1F575 200D 2642 ; unqualified # 🕵‍♂ E4.0 man detective 1F575 1F3FB 200D 2642 FE0F ; fully-qualified # 🕵🏻‍♂️ E4.0 man detective: light skin tone 1F575 1F3FB 200D 2642 ; minimally-qualified # 🕵🏻‍♂ E4.0 man detective: light skin tone @@ -1469,7 +1486,7 @@ 1F575 1F3FF 200D 2642 ; minimally-qualified # 🕵🏿‍♂ E4.0 man detective: dark skin tone 1F575 FE0F 200D 2640 FE0F ; fully-qualified # 🕵️‍♀️ E4.0 woman detective 1F575 200D 2640 FE0F ; unqualified # 🕵‍♀️ E4.0 woman detective -1F575 FE0F 200D 2640 ; unqualified # 🕵️‍♀ E4.0 woman detective +1F575 FE0F 200D 2640 ; minimally-qualified # 🕵️‍♀ E4.0 woman detective 1F575 200D 2640 ; unqualified # 🕵‍♀ E4.0 woman detective 1F575 1F3FB 200D 2640 FE0F ; fully-qualified # 🕵🏻‍♀️ E4.0 woman detective: light skin tone 1F575 1F3FB 200D 2640 ; minimally-qualified # 🕵🏻‍♀ E4.0 woman detective: light skin tone @@ -2302,7 +2319,7 @@ 1F3CC 1F3FF ; fully-qualified # 🏌🏿 E4.0 person golfing: dark skin tone 1F3CC FE0F 200D 2642 FE0F ; fully-qualified # 🏌️‍♂️ E4.0 man golfing 1F3CC 200D 2642 FE0F ; unqualified # 🏌‍♂️ E4.0 man golfing -1F3CC FE0F 200D 2642 ; unqualified # 🏌️‍♂ E4.0 man golfing +1F3CC FE0F 200D 2642 ; minimally-qualified # 🏌️‍♂ E4.0 man golfing 1F3CC 200D 2642 ; unqualified # 🏌‍♂ E4.0 man golfing 1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # 🏌🏻‍♂️ E4.0 man golfing: light skin tone 1F3CC 1F3FB 200D 2642 ; minimally-qualified # 🏌🏻‍♂ E4.0 man golfing: light skin tone @@ -2316,7 +2333,7 @@ 1F3CC 1F3FF 200D 2642 ; minimally-qualified # 🏌🏿‍♂ E4.0 man golfing: dark skin tone 1F3CC FE0F 200D 2640 FE0F ; fully-qualified # 🏌️‍♀️ E4.0 woman golfing 1F3CC 200D 2640 FE0F ; unqualified # 🏌‍♀️ E4.0 woman golfing -1F3CC FE0F 200D 2640 ; unqualified # 🏌️‍♀ E4.0 woman golfing +1F3CC FE0F 200D 2640 ; minimally-qualified # 🏌️‍♀ E4.0 woman golfing 1F3CC 200D 2640 ; unqualified # 🏌‍♀ E4.0 woman golfing 1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # 🏌🏻‍♀️ E4.0 woman golfing: light skin tone 1F3CC 1F3FB 200D 2640 ; minimally-qualified # 🏌🏻‍♀ E4.0 woman golfing: light skin tone @@ -2427,7 +2444,7 @@ 26F9 1F3FF ; fully-qualified # ⛹🏿 E2.0 person bouncing ball: dark skin tone 26F9 FE0F 200D 2642 FE0F ; fully-qualified # ⛹️‍♂️ E4.0 man bouncing ball 26F9 200D 2642 FE0F ; unqualified # ⛹‍♂️ E4.0 man bouncing ball -26F9 FE0F 200D 2642 ; unqualified # ⛹️‍♂ E4.0 man bouncing ball +26F9 FE0F 200D 2642 ; minimally-qualified # ⛹️‍♂ E4.0 man bouncing ball 26F9 200D 2642 ; unqualified # ⛹‍♂ E4.0 man bouncing ball 26F9 1F3FB 200D 2642 FE0F ; fully-qualified # ⛹🏻‍♂️ E4.0 man bouncing ball: light skin tone 26F9 1F3FB 200D 2642 ; minimally-qualified # ⛹🏻‍♂ E4.0 man bouncing ball: light skin tone @@ -2441,7 +2458,7 @@ 26F9 1F3FF 200D 2642 ; minimally-qualified # ⛹🏿‍♂ E4.0 man bouncing ball: dark skin tone 26F9 FE0F 200D 2640 FE0F ; fully-qualified # ⛹️‍♀️ E4.0 woman bouncing ball 26F9 200D 2640 FE0F ; unqualified # ⛹‍♀️ E4.0 woman bouncing ball -26F9 FE0F 200D 2640 ; unqualified # ⛹️‍♀ E4.0 woman bouncing ball +26F9 FE0F 200D 2640 ; minimally-qualified # ⛹️‍♀ E4.0 woman bouncing ball 26F9 200D 2640 ; unqualified # ⛹‍♀ E4.0 woman bouncing ball 26F9 1F3FB 200D 2640 FE0F ; fully-qualified # ⛹🏻‍♀️ E4.0 woman bouncing ball: light skin tone 26F9 1F3FB 200D 2640 ; minimally-qualified # ⛹🏻‍♀ E4.0 woman bouncing ball: light skin tone @@ -2462,7 +2479,7 @@ 1F3CB 1F3FF ; fully-qualified # 🏋🏿 E2.0 person lifting weights: dark skin tone 1F3CB FE0F 200D 2642 FE0F ; fully-qualified # 🏋️‍♂️ E4.0 man lifting weights 1F3CB 200D 2642 FE0F ; unqualified # 🏋‍♂️ E4.0 man lifting weights -1F3CB FE0F 200D 2642 ; unqualified # 🏋️‍♂ E4.0 man lifting weights +1F3CB FE0F 200D 2642 ; minimally-qualified # 🏋️‍♂ E4.0 man lifting weights 1F3CB 200D 2642 ; unqualified # 🏋‍♂ E4.0 man lifting weights 1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # 🏋🏻‍♂️ E4.0 man lifting weights: light skin tone 1F3CB 1F3FB 200D 2642 ; minimally-qualified # 🏋🏻‍♂ E4.0 man lifting weights: light skin tone @@ -2476,7 +2493,7 @@ 1F3CB 1F3FF 200D 2642 ; minimally-qualified # 🏋🏿‍♂ E4.0 man lifting weights: dark skin tone 1F3CB FE0F 200D 2640 FE0F ; fully-qualified # 🏋️‍♀️ E4.0 woman lifting weights 1F3CB 200D 2640 FE0F ; unqualified # 🏋‍♀️ E4.0 woman lifting weights -1F3CB FE0F 200D 2640 ; unqualified # 🏋️‍♀ E4.0 woman lifting weights +1F3CB FE0F 200D 2640 ; minimally-qualified # 🏋️‍♀ E4.0 woman lifting weights 1F3CB 200D 2640 ; unqualified # 🏋‍♀ E4.0 woman lifting weights 1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # 🏋🏻‍♀️ E4.0 woman lifting weights: light skin tone 1F3CB 1F3FB 200D 2640 ; minimally-qualified # 🏋🏻‍♀ E4.0 woman lifting weights: light skin tone @@ -3262,8 +3279,8 @@ 1FAC2 ; fully-qualified # 🫂 E13.0 people hugging 1F463 ; fully-qualified # 👣 E0.6 footprints -# People & Body subtotal: 2986 -# People & Body subtotal: 506 w/o modifiers +# People & Body subtotal: 2998 +# People & Body subtotal: 508 w/o modifiers # group: Component @@ -3306,6 +3323,8 @@ 1F405 ; fully-qualified # 🐅 E1.0 tiger 1F406 ; fully-qualified # 🐆 E1.0 leopard 1F434 ; fully-qualified # 🐴 E0.6 horse face +1FACE ; fully-qualified # 🫎 E15.0 moose +1FACF ; fully-qualified # 🫏 E15.0 donkey 1F40E ; fully-qualified # 🐎 E0.6 horse 1F984 ; fully-qualified # 🦄 E1.0 unicorn 1F993 ; fully-qualified # 🦓 E5.0 zebra @@ -3373,6 +3392,9 @@ 1F9A9 ; fully-qualified # 🦩 E12.0 flamingo 1F99A ; fully-qualified # 🦚 E11.0 peacock 1F99C ; fully-qualified # 🦜 E11.0 parrot +1FABD ; fully-qualified # 🪽 E15.0 wing +1F426 200D 2B1B ; fully-qualified # 🐦‍⬛ E15.0 black bird +1FABF ; fully-qualified # 🪿 E15.0 goose # subgroup: animal-amphibian 1F438 ; fully-qualified # 🐸 E0.6 frog @@ -3399,6 +3421,7 @@ 1F419 ; fully-qualified # 🐙 E0.6 octopus 1F41A ; fully-qualified # 🐚 E0.6 spiral shell 1FAB8 ; fully-qualified # 🪸 E14.0 coral +1FABC ; fully-qualified # 🪼 E15.0 jellyfish # subgroup: animal-bug 1F40C ; fully-qualified # 🐌 E0.6 snail @@ -3433,6 +3456,7 @@ 1F33B ; fully-qualified # 🌻 E0.6 sunflower 1F33C ; fully-qualified # 🌼 E0.6 blossom 1F337 ; fully-qualified # 🌷 E0.6 tulip +1FABB ; fully-qualified # 🪻 E15.0 hyacinth # subgroup: plant-other 1F331 ; fully-qualified # 🌱 E0.6 seedling @@ -3451,9 +3475,10 @@ 1F343 ; fully-qualified # 🍃 E0.6 leaf fluttering in wind 1FAB9 ; fully-qualified # 🪹 E14.0 empty nest 1FABA ; fully-qualified # 🪺 E14.0 nest with eggs +1F344 ; fully-qualified # 🍄 E0.6 mushroom -# Animals & Nature subtotal: 151 -# Animals & Nature subtotal: 151 w/o modifiers +# Animals & Nature subtotal: 159 +# Animals & Nature subtotal: 159 w/o modifiers # group: Food & Drink @@ -3492,10 +3517,11 @@ 1F966 ; fully-qualified # 🥦 E5.0 broccoli 1F9C4 ; fully-qualified # 🧄 E12.0 garlic 1F9C5 ; fully-qualified # 🧅 E12.0 onion -1F344 ; fully-qualified # 🍄 E0.6 mushroom 1F95C ; fully-qualified # 🥜 E3.0 peanuts 1FAD8 ; fully-qualified # 🫘 E14.0 beans 1F330 ; fully-qualified # 🌰 E0.6 chestnut +1FADA ; fully-qualified # 🫚 E15.0 ginger root +1FADB ; fully-qualified # 🫛 E15.0 pea pod # subgroup: food-prepared 1F35E ; fully-qualified # 🍞 E0.6 bread @@ -3607,8 +3633,8 @@ 1FAD9 ; fully-qualified # 🫙 E14.0 jar 1F3FA ; fully-qualified # 🏺 E1.0 amphora -# Food & Drink subtotal: 134 -# Food & Drink subtotal: 134 w/o modifiers +# Food & Drink subtotal: 135 +# Food & Drink subtotal: 135 w/o modifiers # group: Travel & Places @@ -3974,11 +4000,10 @@ 1F3AF ; fully-qualified # 🎯 E0.6 bullseye 1FA80 ; fully-qualified # 🪀 E12.0 yo-yo 1FA81 ; fully-qualified # 🪁 E12.0 kite +1F52B ; fully-qualified # 🔫 E0.6 water pistol 1F3B1 ; fully-qualified # 🎱 E0.6 pool 8 ball 1F52E ; fully-qualified # 🔮 E0.6 crystal ball 1FA84 ; fully-qualified # 🪄 E13.0 magic wand -1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet -1FAAC ; fully-qualified # 🪬 E14.0 hamsa 1F3AE ; fully-qualified # 🎮 E0.6 video game 1F579 FE0F ; fully-qualified # 🕹️ E0.7 joystick 1F579 ; unqualified # 🕹 E0.7 joystick @@ -4013,8 +4038,8 @@ 1F9F6 ; fully-qualified # 🧶 E11.0 yarn 1FAA2 ; fully-qualified # 🪢 E13.0 knot -# Activities subtotal: 97 -# Activities subtotal: 97 w/o modifiers +# Activities subtotal: 96 +# Activities subtotal: 96 w/o modifiers # group: Objects @@ -4040,6 +4065,7 @@ 1FA73 ; fully-qualified # 🩳 E12.0 shorts 1F459 ; fully-qualified # 👙 E0.6 bikini 1F45A ; fully-qualified # 👚 E0.6 woman’s clothes +1FAAD ; fully-qualified # 🪭 E15.0 folding hand fan 1F45B ; fully-qualified # 👛 E0.6 purse 1F45C ; fully-qualified # 👜 E0.6 handbag 1F45D ; fully-qualified # 👝 E0.6 clutch bag @@ -4055,6 +4081,7 @@ 1F461 ; fully-qualified # 👡 E0.6 woman’s sandal 1FA70 ; fully-qualified # 🩰 E12.0 ballet shoes 1F462 ; fully-qualified # 👢 E0.6 woman’s boot +1FAAE ; fully-qualified # 🪮 E15.0 hair pick 1F451 ; fully-qualified # 👑 E0.6 crown 1F452 ; fully-qualified # 👒 E0.6 woman’s hat 1F3A9 ; fully-qualified # 🎩 E0.6 top hat @@ -4103,6 +4130,8 @@ 1FA95 ; fully-qualified # 🪕 E12.0 banjo 1F941 ; fully-qualified # 🥁 E3.0 drum 1FA98 ; fully-qualified # 🪘 E13.0 long drum +1FA87 ; fully-qualified # 🪇 E15.0 maracas +1FA88 ; fully-qualified # 🪈 E15.0 flute # subgroup: phone 1F4F1 ; fully-qualified # 📱 E0.6 mobile phone @@ -4275,7 +4304,7 @@ 1F5E1 ; unqualified # 🗡 E0.7 dagger 2694 FE0F ; fully-qualified # ⚔️ E1.0 crossed swords 2694 ; unqualified # ⚔ E1.0 crossed swords -1F52B ; fully-qualified # 🔫 E0.6 water pistol +1F4A3 ; fully-qualified # 💣 E0.6 bomb 1FA83 ; fully-qualified # 🪃 E13.0 boomerang 1F3F9 ; fully-qualified # 🏹 E1.0 bow and arrow 1F6E1 FE0F ; fully-qualified # 🛡️ E0.7 shield @@ -4354,12 +4383,14 @@ 1FAA6 ; fully-qualified # 🪦 E13.0 headstone 26B1 FE0F ; fully-qualified # ⚱️ E1.0 funeral urn 26B1 ; unqualified # ⚱ E1.0 funeral urn +1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet +1FAAC ; fully-qualified # 🪬 E14.0 hamsa 1F5FF ; fully-qualified # 🗿 E0.6 moai 1FAA7 ; fully-qualified # 🪧 E13.0 placard 1FAAA ; fully-qualified # 🪪 E14.0 identification card -# Objects subtotal: 304 -# Objects subtotal: 304 w/o modifiers +# Objects subtotal: 310 +# Objects subtotal: 310 w/o modifiers # group: Symbols @@ -4455,6 +4486,7 @@ 262E ; unqualified # ☮ E1.0 peace symbol 1F54E ; fully-qualified # 🕎 E1.0 menorah 1F52F ; fully-qualified # 🔯 E0.6 dotted six-pointed star +1FAAF ; fully-qualified # 🪯 E15.0 khanda # subgroup: zodiac 2648 ; fully-qualified # ♈ E0.6 Aries @@ -4503,6 +4535,7 @@ 1F505 ; fully-qualified # 🔅 E1.0 dim button 1F506 ; fully-qualified # 🔆 E1.0 bright button 1F4F6 ; fully-qualified # 📶 E0.6 antenna bars +1F6DC ; fully-qualified # 🛜 E15.0 wireless 1F4F3 ; fully-qualified # 📳 E0.6 vibration mode 1F4F4 ; fully-qualified # 📴 E0.6 mobile phone off @@ -4693,8 +4726,8 @@ 1F533 ; fully-qualified # 🔳 E0.6 white square button 1F532 ; fully-qualified # 🔲 E0.6 black square button -# Symbols subtotal: 302 -# Symbols subtotal: 302 w/o modifiers +# Symbols subtotal: 304 +# Symbols subtotal: 304 w/o modifiers # group: Flags @@ -4709,7 +4742,7 @@ 1F3F3 200D 1F308 ; unqualified # 🏳‍🌈 E4.0 rainbow flag 1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # 🏳️‍⚧️ E13.0 transgender flag 1F3F3 200D 26A7 FE0F ; unqualified # 🏳‍⚧️ E13.0 transgender flag -1F3F3 FE0F 200D 26A7 ; unqualified # 🏳️‍⚧ E13.0 transgender flag +1F3F3 FE0F 200D 26A7 ; minimally-qualified # 🏳️‍⚧ E13.0 transgender flag 1F3F3 200D 26A7 ; unqualified # 🏳‍⚧ E13.0 transgender flag 1F3F4 200D 2620 FE0F ; fully-qualified # 🏴‍☠️ E11.0 pirate flag 1F3F4 200D 2620 ; minimally-qualified # 🏴‍☠ E11.0 pirate flag @@ -4983,9 +5016,9 @@ # Flags subtotal: 275 w/o modifiers # Status Counts -# fully-qualified : 3624 -# minimally-qualified : 817 -# unqualified : 252 +# fully-qualified : 3655 +# minimally-qualified : 827 +# unqualified : 242 # component : 9 #EOF diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex index 35f0da816..dd65d56ae 100644 --- a/lib/pleroma/emoji.ex +++ b/lib/pleroma/emoji.ex @@ -9,6 +9,7 @@ defmodule Pleroma.Emoji do """ use GenServer + alias Pleroma.Emoji.Combinations alias Pleroma.Emoji.Loader require Logger @@ -137,4 +138,17 @@ def is_unicode_emoji?(unquote(emoji)), do: true end def is_unicode_emoji?(_), do: false + + emoji_qualification_map = + emojis + |> Enum.filter(&String.contains?(&1, "\uFE0F")) + |> Combinations.variate_emoji_qualification() + + for {qualified, unqualified_list} <- emoji_qualification_map do + for unqualified <- unqualified_list do + def fully_qualify_emoji(unquote(unqualified)), do: unquote(qualified) + end + end + + def fully_qualify_emoji(emoji), do: emoji end diff --git a/lib/pleroma/emoji/combinations.ex b/lib/pleroma/emoji/combinations.ex new file mode 100644 index 000000000..981c73596 --- /dev/null +++ b/lib/pleroma/emoji/combinations.ex @@ -0,0 +1,45 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Emoji.Combinations do + # FE0F is the emoji variation sequence. It is used for fully-qualifying + # emoji, and that includes emoji combinations. + # This code generates combinations per emoji: for each FE0F, all possible + # combinations of the character being removed or staying will be generated. + # This is made as an attempt to find all partially-qualified and unqualified + # versions of a fully-qualified emoji. + # I have found *no cases* for which this would be a problem, after browsing + # the entire emoji list in emoji-test.txt. This is safe, and, sadly, most + # likely sane too. + + defp qualification_combinations(codepoints) do + qualification_combinations([[]], codepoints) + end + + defp qualification_combinations(acc, []), do: acc + + defp qualification_combinations(acc, ["\uFE0F" | tail]) do + acc + |> Enum.flat_map(fn x -> [x, x ++ ["\uFE0F"]] end) + |> qualification_combinations(tail) + end + + defp qualification_combinations(acc, [codepoint | tail]) do + acc + |> Enum.map(&Kernel.++(&1, [codepoint])) + |> qualification_combinations(tail) + end + + def variate_emoji_qualification(emoji) when is_binary(emoji) do + emoji + |> String.codepoints() + |> qualification_combinations() + |> Enum.map(&List.to_string/1) + end + + def variate_emoji_qualification(emoji) when is_list(emoji) do + emoji + |> Enum.map(fn emoji -> {emoji, variate_emoji_qualification(emoji)} end) + end +end diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex index e6449aa67..15664c876 100644 --- a/lib/pleroma/following_relationship.ex +++ b/lib/pleroma/following_relationship.ex @@ -194,12 +194,13 @@ def move_following(origin, target) do |> join(:inner, [r], f in assoc(r, :follower)) |> where(following_id: ^origin.id) |> where([r, f], f.allow_following_move == true) + |> where([r, f], f.local == true) |> limit(50) |> preload([:follower]) |> Repo.all() |> Enum.map(fn following_relationship -> - Repo.delete(following_relationship) Pleroma.Web.CommonAPI.follow(following_relationship.follower, target) + Pleroma.Web.CommonAPI.unfollow(following_relationship.follower, origin) end) |> case do [] -> diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex index 2e82ceff2..d41061538 100644 --- a/lib/pleroma/http.ex +++ b/lib/pleroma/http.ex @@ -106,5 +106,12 @@ defp adapter_middlewares(Tesla.Adapter.Gun) do [Tesla.Middleware.FollowRedirects, Pleroma.Tesla.Middleware.ConnectionPool] end - defp adapter_middlewares(_), do: [] + defp adapter_middlewares(_) do + if Pleroma.Config.get(:env) == :test do + # Emulate redirects in test env, which are handled by adapters in other environments + [Tesla.Middleware.FollowRedirects] + else + [] + end + end end diff --git a/lib/pleroma/migrators/context_objects_deletion_migrator.ex b/lib/pleroma/migrators/context_objects_deletion_migrator.ex new file mode 100644 index 000000000..fb224795a --- /dev/null +++ b/lib/pleroma/migrators/context_objects_deletion_migrator.ex @@ -0,0 +1,139 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Migrators.ContextObjectsDeletionMigrator do + defmodule State do + use Pleroma.Migrators.Support.BaseMigratorState + + @impl Pleroma.Migrators.Support.BaseMigratorState + defdelegate data_migration(), to: Pleroma.DataMigration, as: :delete_context_objects + end + + use Pleroma.Migrators.Support.BaseMigrator + + alias Pleroma.Migrators.Support.BaseMigrator + alias Pleroma.Object + + @doc "This migration removes objects created exclusively for contexts, containing only an `id` field." + + @impl BaseMigrator + def feature_config_path, do: [:features, :delete_context_objects] + + @impl BaseMigrator + def fault_rate_allowance, do: Config.get([:delete_context_objects, :fault_rate_allowance], 0) + + @impl BaseMigrator + def perform do + data_migration_id = data_migration_id() + max_processed_id = get_stat(:max_processed_id, 0) + + Logger.info("Deleting context objects from `objects` (from oid: #{max_processed_id})...") + + query() + |> where([object], object.id > ^max_processed_id) + |> Repo.chunk_stream(100, :batches, timeout: :infinity) + |> Stream.each(fn objects -> + object_ids = Enum.map(objects, & &1.id) + + results = Enum.map(object_ids, &delete_context_object(&1)) + + failed_ids = + results + |> Enum.filter(&(elem(&1, 0) == :error)) + |> Enum.map(&elem(&1, 1)) + + chunk_affected_count = + results + |> Enum.filter(&(elem(&1, 0) == :ok)) + |> length() + + for failed_id <- failed_ids do + _ = + Repo.query( + "INSERT INTO data_migration_failed_ids(data_migration_id, record_id) " <> + "VALUES ($1, $2) ON CONFLICT DO NOTHING;", + [data_migration_id, failed_id] + ) + end + + _ = + Repo.query( + "DELETE FROM data_migration_failed_ids " <> + "WHERE data_migration_id = $1 AND record_id = ANY($2)", + [data_migration_id, object_ids -- failed_ids] + ) + + max_object_id = Enum.at(object_ids, -1) + + put_stat(:max_processed_id, max_object_id) + increment_stat(:iteration_processed_count, length(object_ids)) + increment_stat(:processed_count, length(object_ids)) + increment_stat(:failed_count, length(failed_ids)) + increment_stat(:affected_count, chunk_affected_count) + put_stat(:records_per_second, records_per_second()) + persist_state() + + # A quick and dirty approach to controlling the load this background migration imposes + sleep_interval = Config.get([:delete_context_objects, :sleep_interval_ms], 0) + Process.sleep(sleep_interval) + end) + |> Stream.run() + end + + @impl BaseMigrator + def query do + # Context objects have no activity type, and only one field, `id`. + # Only those context objects are without types. + from( + object in Object, + where: fragment("(?)->'type' IS NULL", object.data), + select: %{ + id: object.id + } + ) + end + + @spec delete_context_object(integer()) :: {:ok | :error, integer()} + defp delete_context_object(id) do + result = + %Object{id: id} + |> Repo.delete() + |> elem(0) + + {result, id} + end + + @impl BaseMigrator + def retry_failed do + data_migration_id = data_migration_id() + + failed_objects_query() + |> Repo.chunk_stream(100, :one) + |> Stream.each(fn object -> + with {res, _} when res != :error <- delete_context_object(object.id) do + _ = + Repo.query( + "DELETE FROM data_migration_failed_ids " <> + "WHERE data_migration_id = $1 AND record_id = $2", + [data_migration_id, object.id] + ) + end + end) + |> Stream.run() + + put_stat(:failed_count, failures_count()) + persist_state() + + force_continue() + end + + defp failed_objects_query do + from(o in Object) + |> join(:inner, [o], dmf in fragment("SELECT * FROM data_migration_failed_ids"), + on: dmf.record_id == o.id + ) + |> where([_o, dmf], dmf.data_migration_id == ^data_migration_id()) + |> order_by([o], asc: o.id) + end +end diff --git a/lib/pleroma/migrators/hashtags_table_migrator.ex b/lib/pleroma/migrators/hashtags_table_migrator.ex index fa1190b7d..dca4bfa6f 100644 --- a/lib/pleroma/migrators/hashtags_table_migrator.ex +++ b/lib/pleroma/migrators/hashtags_table_migrator.ex @@ -183,7 +183,7 @@ def delete_non_create_activities_hashtags do DELETE FROM hashtags_objects WHERE object_id IN (SELECT DISTINCT objects.id FROM objects JOIN hashtags_objects ON hashtags_objects.object_id = objects.id LEFT JOIN activities - ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = + ON associated_object_id(activities) = (objects.data->>'id') AND activities.data->>'type' = 'Create' WHERE activities.id IS NULL); diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index cfc4bfca3..aba6096bc 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -117,9 +117,8 @@ def for_user_query(user, opts \\ %{}) do |> join(:left, [n, a], object in Object, on: fragment( - "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')", + "(?->>'id') = associated_object_id(?)", object.data, - a.data, a.data ) ) @@ -193,13 +192,11 @@ defp exclude_visibility(query, %{exclude_visibilities: visibility}) |> join(:left, [n, a], mutated_activity in Pleroma.Activity, on: fragment( - "COALESCE((?->'object')->>'id', ?->>'object')", - a.data, + "associated_object_id(?)", a.data ) == fragment( - "COALESCE((?->'object')->>'id', ?->>'object')", - mutated_activity.data, + "associated_object_id(?)", mutated_activity.data ) and fragment("(?->>'type' = 'Like' or ?->>'type' = 'Announce')", a.data, a.data) and @@ -377,7 +374,7 @@ def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = act end def create_notifications(%Activity{data: %{"type" => type}} = activity, options) - when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag"] do + when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag", "Update"] do do_create_notifications(activity, options) end @@ -431,6 +428,9 @@ defp type_from_activity(%{data: %{"type" => type}} = activity) do activity |> type_from_activity_object() + "Update" -> + "update" + t -> raise "No notification type for activity type #{t}" end @@ -505,7 +505,16 @@ def create_poll_notifications(%Activity{} = activity) do def get_notified_from_activity(activity, local_only \\ true) def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only) - when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact", "Flag"] do + when type in [ + "Create", + "Like", + "Announce", + "Follow", + "Move", + "EmojiReact", + "Flag", + "Update" + ] do potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity) potential_receivers = @@ -547,6 +556,21 @@ def get_potential_receiver_ap_ids(%{data: %{"type" => "Flag", "actor" => actor}} [actor] end + # Update activity: notify all who repeated this + def get_potential_receiver_ap_ids(%{data: %{"type" => "Update", "actor" => actor}} = activity) do + with %Object{data: %{"id" => object_id}} <- Object.normalize(activity, fetch: false) do + repeaters = + Activity.Queries.by_type("Announce") + |> Activity.Queries.by_object_id(object_id) + |> Activity.with_joined_user_actor() + |> where([a, u], u.local) + |> select([a, u], u.ap_id) + |> Repo.all() + + repeaters -- [actor] + end + end + def get_potential_receiver_ap_ids(activity) do [] |> Utils.maybe_notify_to_recipients(activity) diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index fe264b5e0..38accae5d 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -40,8 +40,7 @@ def with_joined_activity(query, activity_type \\ "Create", join_type \\ :inner) join(query, join_type, [{object, object_position}], a in Activity, on: fragment( - "COALESCE(?->'object'->>'id', ?->>'object') = (? ->> 'id') AND (?->>'type' = ?) ", - a.data, + "associated_object_id(?) = (? ->> 'id') AND (?->>'type' = ?) ", a.data, object.data, a.data, @@ -145,7 +144,7 @@ defp warn_on_no_object_preloaded(ap_id) do Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}") end - def normalize(_, options \\ [fetch: false]) + def normalize(_, options \\ [fetch: false, id_only: false]) # If we pass an Activity to Object.normalize(), we can try to use the preloaded object. # Use this whenever possible, especially when walking graphs in an O(N) loop! @@ -173,10 +172,15 @@ def normalize(%Activity{data: %{"object" => ap_id}}, options) do def normalize(%{"id" => ap_id}, options), do: normalize(ap_id, options) def normalize(ap_id, options) when is_binary(ap_id) do - if Keyword.get(options, :fetch) do - Fetcher.fetch_object_from_id!(ap_id, options) - else - get_cached_by_ap_id(ap_id) + cond do + Keyword.get(options, :id_only) -> + ap_id + + Keyword.get(options, :fetch) -> + Fetcher.fetch_object_from_id!(ap_id, options) + + true -> + get_cached_by_ap_id(ap_id) end end @@ -208,10 +212,6 @@ def get_cached_by_ap_id(ap_id) do end end - def context_mapping(context) do - Object.change(%Object{}, %{data: %{"id" => context}}) - end - def make_tombstone(%Object{data: %{"id" => id, "type" => type}}, deleted \\ DateTime.utc_now()) do %ObjectTombstone{ id: id, diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index deb3dc711..a9a9eeeed 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Object.Fetcher do alias Pleroma.HTTP + alias Pleroma.Instances alias Pleroma.Maps alias Pleroma.Object alias Pleroma.Object.Containment @@ -26,8 +27,42 @@ defp touch_changeset(changeset) do end defp maybe_reinject_internal_fields(%{data: %{} = old_data}, new_data) do + has_history? = fn + %{"formerRepresentations" => %{"orderedItems" => list}} when is_list(list) -> true + _ -> false + end + internal_fields = Map.take(old_data, Pleroma.Constants.object_internal_fields()) + remote_history_exists? = has_history?.(new_data) + + # If the remote history exists, we treat that as the only source of truth. + new_data = + if has_history?.(old_data) and not remote_history_exists? do + Map.put(new_data, "formerRepresentations", old_data["formerRepresentations"]) + else + new_data + end + + # If the remote does not have history information, we need to manage it ourselves + new_data = + if not remote_history_exists? do + changed? = + Pleroma.Constants.status_updatable_fields() + |> Enum.any?(fn field -> Map.get(old_data, field) != Map.get(new_data, field) end) + + %{updated_object: updated_object} = + new_data + |> Object.Updater.maybe_update_history(old_data, + updated: changed?, + use_history_in_new_object?: false + ) + + updated_object + else + new_data + end + Map.merge(new_data, internal_fields) end @@ -200,6 +235,10 @@ def fetch_and_contain_remote_object_from_id(id) when is_binary(id) do {:ok, body} <- get_object(id), {:ok, data} <- safe_json_decode(body), :ok <- Containment.contain_origin_from_id(id, data) do + if not Instances.reachable?(id) do + Instances.set_reachable(id) + end + {:ok, data} else {:scheme, _} -> diff --git a/lib/pleroma/object/updater.ex b/lib/pleroma/object/updater.ex new file mode 100644 index 000000000..ab38d3ed2 --- /dev/null +++ b/lib/pleroma/object/updater.ex @@ -0,0 +1,240 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Object.Updater do + require Pleroma.Constants + + def update_content_fields(orig_object_data, updated_object) do + Pleroma.Constants.status_updatable_fields() + |> Enum.reduce( + %{data: orig_object_data, updated: false}, + fn field, %{data: data, updated: updated} -> + updated = + updated or + (field != "updated" and + Map.get(updated_object, field) != Map.get(orig_object_data, field)) + + data = + if Map.has_key?(updated_object, field) do + Map.put(data, field, updated_object[field]) + else + Map.drop(data, [field]) + end + + %{data: data, updated: updated} + end + ) + end + + def maybe_history(object) do + with history <- Map.get(object, "formerRepresentations"), + true <- is_map(history), + "OrderedCollection" <- Map.get(history, "type"), + true <- is_list(Map.get(history, "orderedItems")), + true <- is_integer(Map.get(history, "totalItems")) do + history + else + _ -> nil + end + end + + def history_for(object) do + with history when not is_nil(history) <- maybe_history(object) do + history + else + _ -> history_skeleton() + end + end + + defp history_skeleton do + %{ + "type" => "OrderedCollection", + "totalItems" => 0, + "orderedItems" => [] + } + end + + def maybe_update_history( + updated_object, + orig_object_data, + opts + ) do + updated = opts[:updated] + use_history_in_new_object? = opts[:use_history_in_new_object?] + + if not updated do + %{updated_object: updated_object, used_history_in_new_object?: false} + else + # Put edit history + # Note that we may have got the edit history by first fetching the object + {new_history, used_history_in_new_object?} = + with true <- use_history_in_new_object?, + updated_history when not is_nil(updated_history) <- maybe_history(opts[:new_data]) do + {updated_history, true} + else + _ -> + history = history_for(orig_object_data) + + latest_history_item = + orig_object_data + |> Map.drop(["id", "formerRepresentations"]) + + updated_history = + history + |> Map.put("orderedItems", [latest_history_item | history["orderedItems"]]) + |> Map.put("totalItems", history["totalItems"] + 1) + + {updated_history, false} + end + + updated_object = + updated_object + |> Map.put("formerRepresentations", new_history) + + %{updated_object: updated_object, used_history_in_new_object?: used_history_in_new_object?} + end + end + + defp maybe_update_poll(to_be_updated, updated_object) do + choice_key = fn data -> + if Map.has_key?(data, "anyOf"), do: "anyOf", else: "oneOf" + end + + with true <- to_be_updated["type"] == "Question", + key <- choice_key.(updated_object), + true <- key == choice_key.(to_be_updated), + orig_choices <- to_be_updated[key] |> Enum.map(&Map.drop(&1, ["replies"])), + new_choices <- updated_object[key] |> Enum.map(&Map.drop(&1, ["replies"])), + true <- orig_choices == new_choices do + # Choices are the same, but counts are different + to_be_updated + |> Map.put(key, updated_object[key]) + else + # Choices (or vote type) have changed, do not allow this + _ -> to_be_updated + end + end + + # This calculates the data to be sent as the object of an Update. + # new_data's formerRepresentations is not considered. + # formerRepresentations is added to the returned data. + def make_update_object_data(original_data, new_data, date) do + %{data: updated_data, updated: updated} = + original_data + |> update_content_fields(new_data) + + if not updated do + updated_data + else + %{updated_object: updated_data} = + updated_data + |> maybe_update_history(original_data, updated: updated, use_history_in_new_object?: false) + + updated_data + |> Map.put("updated", date) + end + end + + # This calculates the data of the new Object from an Update. + # new_data's formerRepresentations is considered. + def make_new_object_data_from_update_object(original_data, new_data) do + update_is_reasonable = + with {_, updated} when not is_nil(updated) <- {:cur_updated, new_data["updated"]}, + {_, {:ok, updated_time, _}} <- {:cur_updated, DateTime.from_iso8601(updated)}, + {_, last_updated} when not is_nil(last_updated) <- + {:last_updated, original_data["updated"] || original_data["published"]}, + {_, {:ok, last_updated_time, _}} <- + {:last_updated, DateTime.from_iso8601(last_updated)}, + :gt <- DateTime.compare(updated_time, last_updated_time) do + :update_everything + else + # only allow poll updates + {:cur_updated, _} -> :no_content_update + :eq -> :no_content_update + # allow all updates + {:last_updated, _} -> :update_everything + # allow no updates + _ -> false + end + + %{ + updated_object: updated_data, + used_history_in_new_object?: used_history_in_new_object?, + updated: updated + } = + if update_is_reasonable == :update_everything do + %{data: updated_data, updated: updated} = + original_data + |> update_content_fields(new_data) + + updated_data + |> maybe_update_history(original_data, + updated: updated, + use_history_in_new_object?: true, + new_data: new_data + ) + |> Map.put(:updated, updated) + else + %{ + updated_object: original_data, + used_history_in_new_object?: false, + updated: false + } + end + + updated_data = + if update_is_reasonable != false do + updated_data + |> maybe_update_poll(new_data) + else + updated_data + end + + %{ + updated_data: updated_data, + updated: updated, + used_history_in_new_object?: used_history_in_new_object? + } + end + + def for_each_history_item(%{"orderedItems" => items} = history, _object, fun) do + new_items = + Enum.map(items, fun) + |> Enum.reduce_while( + {:ok, []}, + fn + {:ok, item}, {:ok, acc} -> {:cont, {:ok, acc ++ [item]}} + e, _acc -> {:halt, e} + end + ) + + case new_items do + {:ok, items} -> {:ok, Map.put(history, "orderedItems", items)} + e -> e + end + end + + def for_each_history_item(history, _, _) do + {:ok, history} + end + + def do_with_history(object, fun) do + with history <- object["formerRepresentations"], + object <- Map.drop(object, ["formerRepresentations"]), + {_, {:ok, object}} <- {:main_body, fun.(object)}, + {_, {:ok, history}} <- {:history_items, for_each_history_item(history, object, fun)} do + object = + if history do + Map.put(object, "formerRepresentations", history) + else + object + end + + {:ok, object} + else + {:main_body, e} -> e + {:history_items, e} -> e + end + end +end diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex index dbe6fd209..5cfdae051 100644 --- a/lib/pleroma/signature.ex +++ b/lib/pleroma/signature.ex @@ -10,17 +10,14 @@ defmodule Pleroma.Signature do alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub + @known_suffixes ["/publickey", "/main-key"] + def key_id_to_actor_id(key_id) do uri = - URI.parse(key_id) + key_id + |> URI.parse() |> Map.put(:fragment, nil) - - uri = - if not is_nil(uri.path) and String.ends_with?(uri.path, "/publickey") do - Map.put(uri, :path, String.replace(uri.path, "/publickey", "")) - else - uri - end + |> remove_suffix(@known_suffixes) maybe_ap_id = URI.to_string(uri) @@ -36,6 +33,16 @@ def key_id_to_actor_id(key_id) do end end + defp remove_suffix(uri, [test | rest]) do + if not is_nil(uri.path) and String.ends_with?(uri.path, test) do + Map.put(uri, :path, String.replace(uri.path, test, "")) + else + remove_suffix(uri, rest) + end + end + + defp remove_suffix(uri, []), do: uri + def fetch_public_key(conn) do with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn), {:ok, actor_id} <- key_id_to_actor_id(kid), @@ -59,9 +66,8 @@ def refetch_public_key(conn) do end end - def sign(%User{} = user, headers) do - with {:ok, %{keys: keys}} <- User.ensure_keys_present(user), - {:ok, private_key, _} <- Keys.keys_from_pem(keys) do + def sign(%User{keys: keys} = user, headers) do + with {:ok, private_key, _} <- Keys.keys_from_pem(keys) do HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers) end end diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index db2909276..4aee9326f 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -36,6 +36,7 @@ defmodule Pleroma.Upload do alias Ecto.UUID alias Pleroma.Config alias Pleroma.Maps + alias Pleroma.Web.ActivityPub.Utils require Logger @type source :: @@ -99,6 +100,7 @@ def store(upload, opts \\ []) do {:ok, url_spec} <- Pleroma.Uploaders.Uploader.put_file(opts.uploader, upload) do {:ok, %{ + "id" => Utils.generate_object_id(), "type" => opts.activity_type, "mediaType" => upload.content_type, "url" => [ diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 4201fff12..f6e30555c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -646,7 +646,13 @@ defp put_change_if_present(changeset, map_field, value_function) do {:ok, new_value} <- value_function.(value) do put_change(changeset, map_field, new_value) else - _ -> changeset + {:error, :file_too_large} -> + Ecto.Changeset.validate_change(changeset, map_field, fn map_field, _value -> + [{map_field, "file is too large"}] + end) + + _ -> + changeset end end @@ -746,6 +752,7 @@ def register_changeset_ldap(struct, params = %{password: password}) |> put_ap_id() |> unique_constraint(:ap_id) |> put_following_and_follower_and_featured_address() + |> put_private_key() end def register_changeset(struct, params \\ %{}, opts \\ []) do @@ -803,6 +810,7 @@ def register_changeset(struct, params \\ %{}, opts \\ []) do |> put_ap_id() |> unique_constraint(:ap_id) |> put_following_and_follower_and_featured_address() + |> put_private_key() end def validate_not_restricted_nickname(changeset, field) do @@ -881,6 +889,11 @@ defp put_following_and_follower_and_featured_address(changeset) do |> put_change(:featured_address, featured) end + defp put_private_key(changeset) do + {:ok, pem} = Keys.generate_rsa_pem() + put_change(changeset, :keys, pem) + end + defp autofollow_users(user) do candidates = Config.get([:instance, :autofollowed_nicknames]) @@ -933,7 +946,7 @@ def post_register_action(%User{is_approved: true, is_confirmed: true} = user) do end end - defp send_user_approval_email(user) do + defp send_user_approval_email(%User{email: email} = user) when is_binary(email) do user |> Pleroma.Emails.UserEmail.approval_pending_email() |> Pleroma.Emails.Mailer.deliver_async() @@ -941,6 +954,10 @@ defp send_user_approval_email(user) do {:ok, :enqueued} end + defp send_user_approval_email(_user) do + {:ok, :skipped} + end + defp send_admin_approval_emails(user) do all_superusers() |> Enum.filter(fn user -> not is_nil(user.email) end) @@ -1501,17 +1518,30 @@ def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do {:ok, list(UserRelationship.t())} | {:error, String.t()} def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do notifications? = Map.get(params, :notifications, true) - expires_in = Map.get(params, :expires_in, 0) + duration = Map.get(params, :duration, 0) - with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee), + expires_at = + if duration > 0 do + DateTime.utc_now() + |> DateTime.add(duration) + else + nil + end + + with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee, expires_at), {:ok, user_notification_mute} <- - (notifications? && UserRelationship.create_notification_mute(muter, mutee)) || + (notifications? && + UserRelationship.create_notification_mute( + muter, + mutee, + expires_at + )) || {:ok, nil} do - if expires_in > 0 do + if duration > 0 do Pleroma.Workers.MuteExpireWorker.enqueue( "unmute_user", %{"muter_id" => muter.id, "mutee_id" => mutee.id}, - schedule_in: expires_in + scheduled_at: expires_at ) end @@ -1582,13 +1612,19 @@ def block(%User{} = blocker, %User{} = blocked) do blocker end - # clear any requested follows as well + # clear any requested follows from both sides as well blocked = case CommonAPI.reject_follow_request(blocked, blocker) do {:ok, %User{} = updated_blocked} -> updated_blocked nil -> blocked end + blocker = + case CommonAPI.reject_follow_request(blocker, blocked) do + {:ok, %User{} = updated_blocker} -> updated_blocker + nil -> blocker + end + unsubscribe(blocked, blocker) unfollowing_blocked = Config.get([:activitypub, :unfollow_blocked], true) @@ -2088,6 +2124,7 @@ defp create_service_actor(uri, nickname) do follower_address: uri <> "/followers" } |> change + |> put_private_key() |> unique_constraint(:nickname) |> Repo.insert() |> set_cache() @@ -2120,7 +2157,8 @@ def ap_enabled?(_), do: false @doc "Gets or fetch a user by uri or nickname." @spec get_or_fetch(String.t()) :: {:ok, User.t()} | {:error, String.t()} - def get_or_fetch("http" <> _host = uri), do: get_or_fetch_by_ap_id(uri) + def get_or_fetch("http://" <> _host = uri), do: get_or_fetch_by_ap_id(uri) + def get_or_fetch("https://" <> _host = uri), do: get_or_fetch_by_ap_id(uri) def get_or_fetch(nickname), do: get_or_fetch_by_nickname(nickname) # wait a period of time and return newest version of the User structs @@ -2358,17 +2396,6 @@ def get_mascot(%{mascot: mascot}) when is_nil(mascot) do } end - def ensure_keys_present(%{keys: keys} = user) when not is_nil(keys), do: {:ok, user} - - def ensure_keys_present(%User{} = user) do - with {:ok, pem} <- Keys.generate_rsa_pem() do - user - |> cast(%{keys: pem}, [:keys]) - |> validate_required([:keys]) - |> update_and_set_cache() - end - end - def get_ap_ids_by_nicknames(nicknames) do from(u in User, where: u.nickname in ^nicknames, @@ -2411,6 +2438,38 @@ def change_email(user, email) do |> update_and_set_cache() end + def alias_users(user) do + user.also_known_as + |> Enum.map(&User.get_cached_by_ap_id/1) + |> Enum.filter(fn user -> user != nil end) + end + + def add_alias(user, new_alias_user) do + current_aliases = user.also_known_as || [] + new_alias_ap_id = new_alias_user.ap_id + + if new_alias_ap_id in current_aliases do + {:ok, user} + else + user + |> cast(%{also_known_as: current_aliases ++ [new_alias_ap_id]}, [:also_known_as]) + |> update_and_set_cache() + end + end + + def delete_alias(user, alias_user) do + current_aliases = user.also_known_as || [] + alias_ap_id = alias_user.ap_id + + if alias_ap_id in current_aliases do + user + |> cast(%{also_known_as: current_aliases -- [alias_ap_id]}, [:also_known_as]) + |> update_and_set_cache() + else + {:error, :no_such_alias} + end + end + # Internal function; public one is `deactivate/2` defp set_activation_status(user, status) do user diff --git a/lib/pleroma/user/backup.ex b/lib/pleroma/user/backup.ex index 9cb329663..9df010605 100644 --- a/lib/pleroma/user/backup.ex +++ b/lib/pleroma/user/backup.ex @@ -32,9 +32,7 @@ defmodule Pleroma.User.Backup do end def create(user, admin_id \\ nil) do - with :ok <- validate_email_enabled(), - :ok <- validate_user_email(user), - :ok <- validate_limit(user, admin_id), + with :ok <- validate_limit(user, admin_id), {:ok, backup} <- user |> new() |> Repo.insert() do BackupWorker.process(backup, admin_id) end @@ -86,20 +84,6 @@ defp validate_limit(user, nil) do end end - defp validate_email_enabled do - if Pleroma.Config.get([Pleroma.Emails.Mailer, :enabled]) do - :ok - else - {:error, dgettext("errors", "Backups require enabled email")} - end - end - - defp validate_user_email(%User{email: nil}) do - {:error, dgettext("errors", "Email is required")} - end - - defp validate_user_email(%User{email: email}) when is_binary(email), do: :ok - def get_last(user_id) do __MODULE__ |> where(user_id: ^user_id) diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex index cd6f69f56..a7fb8fb83 100644 --- a/lib/pleroma/user/search.ex +++ b/lib/pleroma/user/search.ex @@ -94,6 +94,7 @@ defp search_query(query_string, for_user, following, top_user_ids) do |> subquery() |> order_by(desc: :search_rank) |> maybe_restrict_local(for_user) + |> filter_deactivated_users() end defp select_top_users(query, top_user_ids) do @@ -166,6 +167,10 @@ defp filter_internal_users(query) do from(q in query, where: q.actor_type != "Application") end + defp filter_deactivated_users(query) do + from(q in query, where: q.is_active == true) + end + defp filter_blocked_user(query, %User{} = blocker) do query |> join(:left, [u], b in Pleroma.UserRelationship, diff --git a/lib/pleroma/user_relationship.ex b/lib/pleroma/user_relationship.ex index 1432a1d83..fbecf3129 100644 --- a/lib/pleroma/user_relationship.ex +++ b/lib/pleroma/user_relationship.ex @@ -18,16 +18,17 @@ defmodule Pleroma.UserRelationship do belongs_to(:source, User, type: FlakeId.Ecto.CompatType) belongs_to(:target, User, type: FlakeId.Ecto.CompatType) field(:relationship_type, Pleroma.UserRelationship.Type) + field(:expires_at, :utc_datetime) timestamps(updated_at: false) end for relationship_type <- Keyword.keys(Pleroma.UserRelationship.Type.__enum_map__()) do - # `def create_block/2`, `def create_mute/2`, `def create_reblog_mute/2`, - # `def create_notification_mute/2`, `def create_inverse_subscription/2`, - # `def endorsement/2` - def unquote(:"create_#{relationship_type}")(source, target), - do: create(unquote(relationship_type), source, target) + # `def create_block/3`, `def create_mute/3`, `def create_reblog_mute/3`, + # `def create_notification_mute/3`, `def create_inverse_subscription/3`, + # `def endorsement/3` + def unquote(:"create_#{relationship_type}")(source, target, expires_at \\ nil), + do: create(unquote(relationship_type), source, target, expires_at) # `def delete_block/2`, `def delete_mute/2`, `def delete_reblog_mute/2`, # `def delete_notification_mute/2`, `def delete_inverse_subscription/2`, @@ -37,9 +38,15 @@ def unquote(:"delete_#{relationship_type}")(source, target), # `def block_exists?/2`, `def mute_exists?/2`, `def reblog_mute_exists?/2`, # `def notification_mute_exists?/2`, `def inverse_subscription_exists?/2`, - # `def inverse_endorsement?/2` + # `def inverse_endorsement_exists?/2` def unquote(:"#{relationship_type}_exists?")(source, target), do: exists?(unquote(relationship_type), source, target) + + # `def get_block_expire_date/2`, `def get_mute_expire_date/2`, + # `def get_reblog_mute_expire_date/2`, `def get_notification_mute_exists?/2`, + # `def get_inverse_subscription_expire_date/2`, `def get_inverse_endorsement_expire_date/2` + def unquote(:"get_#{relationship_type}_expire_date")(source, target), + do: get_expire_date(unquote(relationship_type), source, target) end def user_relationship_types, do: Keyword.keys(user_relationship_mappings()) @@ -48,7 +55,7 @@ def user_relationship_mappings, do: Pleroma.UserRelationship.Type.__enum_map__() def changeset(%UserRelationship{} = user_relationship, params \\ %{}) do user_relationship - |> cast(params, [:relationship_type, :source_id, :target_id]) + |> cast(params, [:relationship_type, :source_id, :target_id, :expires_at]) |> validate_required([:relationship_type, :source_id, :target_id]) |> unique_constraint(:relationship_type, name: :user_relationships_source_id_relationship_type_target_id_index @@ -62,16 +69,31 @@ def exists?(relationship_type, %User{} = source, %User{} = target) do |> Repo.exists?() end - def create(relationship_type, %User{} = source, %User{} = target) do + def get_expire_date(relationship_type, %User{} = source, %User{} = target) do + %UserRelationship{expires_at: expires_at} = + UserRelationship + |> where( + relationship_type: ^relationship_type, + source_id: ^source.id, + target_id: ^target.id + ) + |> Repo.one!() + + expires_at + end + + def create(relationship_type, %User{} = source, %User{} = target, expires_at \\ nil) do %UserRelationship{} |> changeset(%{ relationship_type: relationship_type, source_id: source.id, - target_id: target.id + target_id: target.id, + expires_at: expires_at }) |> Repo.insert( - on_conflict: {:replace_all_except, [:id]}, - conflict_target: [:source_id, :relationship_type, :target_id] + on_conflict: {:replace_all_except, [:id, :inserted_at]}, + conflict_target: [:source_id, :relationship_type, :target_id], + returning: true ) end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 06c894efd..b9206b4da 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -190,7 +190,16 @@ defp insert_activity_with_expiration(data, local, recipients) do def notify_and_stream(activity) do Notification.create_notifications(activity) - conversation = create_or_bump_conversation(activity, activity.actor) + original_activity = + case activity do + %{data: %{"type" => "Update"}, object: %{data: %{"id" => id}}} -> + Activity.get_create_by_object_ap_id_with_object(id) + + _ -> + activity + end + + conversation = create_or_bump_conversation(original_activity, original_activity.actor) participations = get_participations(conversation) stream_out(activity) stream_out_participations(participations) @@ -256,7 +265,7 @@ def stream_out_participations(_, _), do: :noop @impl true def stream_out(%Activity{data: %{"type" => data_type}} = activity) - when data_type in ["Create", "Announce", "Delete"] do + when data_type in ["Create", "Announce", "Delete", "Update"] do activity |> Topics.get_activity_topics() |> Streamer.stream(activity) @@ -413,7 +422,8 @@ def move(%User{} = origin, %User{} = target, local \\ true) do "type" => "Move", "actor" => origin.ap_id, "object" => origin.ap_id, - "target" => target.ap_id + "target" => target.ap_id, + "to" => [origin.follower_address] } with true <- origin.ap_id in target.also_known_as, @@ -501,9 +511,18 @@ def fetch_activities(recipients, opts \\ %{}, pagination \\ :keyset) do @spec fetch_public_or_unlisted_activities(map(), Pagination.type()) :: [Activity.t()] def fetch_public_or_unlisted_activities(opts \\ %{}, pagination \\ :keyset) do + includes_local_public = Map.get(opts, :includes_local_public, false) + opts = Map.delete(opts, :user) - [Constants.as_public()] + intended_recipients = + if includes_local_public do + [Constants.as_public(), as_local_public()] + else + [Constants.as_public()] + end + + intended_recipients |> fetch_activities_query(opts) |> restrict_unlisted(opts) |> fetch_paginated_optimized(opts, pagination) @@ -603,9 +622,11 @@ defp restrict_thread_visibility(query, %{user: %User{skip_thread_containment: tr do: query defp restrict_thread_visibility(query, %{user: %User{ap_id: ap_id}}, _) do + local_public = as_local_public() + from( a in query, - where: fragment("thread_visibility(?, (?)->>'id') = true", ^ap_id, a.data) + where: fragment("thread_visibility(?, (?)->>'id', ?) = true", ^ap_id, a.data, ^local_public) ) end @@ -692,8 +713,12 @@ defp fetch_activities_for_reading_user(reading_user, params) do defp user_activities_recipients(%{godmode: true}), do: [] defp user_activities_recipients(%{reading_user: reading_user}) do - if reading_user do - [Constants.as_public(), reading_user.ap_id | User.following(reading_user)] + if not is_nil(reading_user) and reading_user.local do + [ + Constants.as_public(), + as_local_public(), + reading_user.ap_id | User.following(reading_user) + ] else [Constants.as_public()] end @@ -1134,8 +1159,7 @@ defp restrict_pinned(query, %{pinned: true, pinned_object_ids: ids}) do [activity, object: o] in query, where: fragment( - "(?)->>'type' = 'Create' and coalesce((?)->'object'->>'id', (?)->>'object') = any (?)", - activity.data, + "(?)->>'type' = 'Create' and associated_object_id((?)) = any (?)", activity.data, activity.data, ^ids @@ -1215,15 +1239,15 @@ defp exclude_chat_messages(query, _) do end end + defp exclude_invisible_actors(query, %{type: "Flag"}), do: query defp exclude_invisible_actors(query, %{invisible_actors: true}), do: query defp exclude_invisible_actors(query, _opts) do - invisible_ap_ids = - User.Query.build(%{invisible: true, select: [:ap_id]}) - |> Repo.all() - |> Enum.map(fn %{ap_id: ap_id} -> ap_id end) - - from([activity] in query, where: activity.actor not in ^invisible_ap_ids) + query + |> join(:inner, [activity], u in User, + as: :u, + on: activity.actor == u.ap_id and u.invisible == false + ) end defp exclude_id(query, %{exclude_id: id}) when is_binary(id) do @@ -1353,7 +1377,7 @@ def fetch_activities_query(recipients, opts \\ %{}) do |> restrict_instance(opts) |> restrict_announce_object_actor(opts) |> restrict_filtered(opts) - |> Activity.restrict_deactivated_users() + |> maybe_restrict_deactivated_users(opts) |> exclude_poll_votes(opts) |> exclude_chat_messages(opts) |> exclude_invisible_actors(opts) @@ -1458,7 +1482,7 @@ defp normalize_image(%{"url" => url}) do defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image() defp normalize_image(_), do: nil - defp object_to_user_data(data) do + defp object_to_user_data(data, additional) do fields = data |> Map.get("attachment", []) @@ -1490,15 +1514,11 @@ defp object_to_user_data(data) do public_key = if is_map(data["publicKey"]) && is_binary(data["publicKey"]["publicKeyPem"]) do data["publicKey"]["publicKeyPem"] - else - nil end shared_inbox = if is_map(data["endpoints"]) && is_binary(data["endpoints"]["sharedInbox"]) do data["endpoints"]["sharedInbox"] - else - nil end birthday = @@ -1507,13 +1527,15 @@ defp object_to_user_data(data) do {:ok, date} -> date {:error, _} -> nil end - else - nil end show_birthday = !!birthday - user_data = %{ + # if WebFinger request was already done, we probably have acct, otherwise + # we request WebFinger here + nickname = additional[:nickname_from_acct] || generate_nickname(data) + + %{ ap_id: data["id"], uri: get_actor_url(data["url"]), ap_enabled: true, @@ -1535,23 +1557,29 @@ defp object_to_user_data(data) do inbox: data["inbox"], shared_inbox: shared_inbox, accepts_chat_messages: accepts_chat_messages, - pinned_objects: pinned_objects, birthday: birthday, - show_birthday: show_birthday + show_birthday: show_birthday, + pinned_objects: pinned_objects, + nickname: nickname } + end - # nickname can be nil because of virtual actors - if data["preferredUsername"] do - Map.put( - user_data, - :nickname, - "#{data["preferredUsername"]}@#{URI.parse(data["id"]).host}" - ) + defp generate_nickname(%{"preferredUsername" => username} = data) when is_binary(username) do + generated = "#{username}@#{URI.parse(data["id"]).host}" + + if Config.get([WebFinger, :update_nickname_on_user_fetch]) do + case WebFinger.finger(generated) do + {:ok, %{"subject" => "acct:" <> acct}} -> acct + _ -> generated + end else - Map.put(user_data, :nickname, nil) + generated end end + # nickname can be nil because of virtual actors + defp generate_nickname(_), do: nil + def fetch_follow_information_for_user(user) do with {:ok, following_data} <- Fetcher.fetch_and_contain_remote_object_from_id(user.following_address), @@ -1623,17 +1651,17 @@ defp collection_private(%{"first" => first}) do defp collection_private(_data), do: {:ok, true} - def user_data_from_user_object(data) do + def user_data_from_user_object(data, additional \\ []) do with {:ok, data} <- MRF.filter(data) do - {:ok, object_to_user_data(data)} + {:ok, object_to_user_data(data, additional)} else e -> {:error, e} end end - def fetch_and_prepare_user_from_ap_id(ap_id) do + def fetch_and_prepare_user_from_ap_id(ap_id, additional \\ []) do with {:ok, data} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id), - {:ok, data} <- user_data_from_user_object(data) do + {:ok, data} <- user_data_from_user_object(data, additional) do {:ok, maybe_update_follow_information(data)} else # If this has been deleted, only log a debug and not an error @@ -1711,13 +1739,13 @@ def pinned_fetch_task(%{pinned_objects: pins}) do end end - def make_user_from_ap_id(ap_id) do + def make_user_from_ap_id(ap_id, additional \\ []) do user = User.get_cached_by_ap_id(ap_id) if user && !User.ap_enabled?(user) do Transmogrifier.upgrade_user_from_ap_id(ap_id) else - with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id) do + with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id, additional) do {:ok, _pid} = Task.start(fn -> pinned_fetch_task(data) end) if user do @@ -1737,8 +1765,9 @@ def make_user_from_ap_id(ap_id) do end def make_user_from_nickname(nickname) do - with {:ok, %{"ap_id" => ap_id}} when not is_nil(ap_id) <- WebFinger.finger(nickname) do - make_user_from_ap_id(ap_id) + with {:ok, %{"ap_id" => ap_id, "subject" => "acct:" <> acct}} when not is_nil(ap_id) <- + WebFinger.finger(nickname) do + make_user_from_ap_id(ap_id, nickname_from_acct: acct) else _e -> {:error, "No AP id in WebFinger"} end @@ -1760,4 +1789,9 @@ def fetch_direct_messages_query do |> restrict_visibility(%{visibility: "direct"}) |> order_by([activity], asc: activity.id) end + + defp maybe_restrict_deactivated_users(activity, %{type: "Flag"}), do: activity + + defp maybe_restrict_deactivated_users(activity, _opts), + do: Activity.restrict_deactivated_users(activity) end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index b8f63d69d..1357c379c 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -66,8 +66,7 @@ defp relay_active?(conn, _) do end def user(conn, %{"nickname" => nickname}) do - with %User{local: true} = user <- User.get_cached_by_nickname(nickname), - {:ok, user} <- User.ensure_keys_present(user) do + with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -174,7 +173,6 @@ def relay_following(conn, _params) do def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user), {:show_follows, true} <- {:show_follows, (for_user && for_user == user) || !user.hide_follows} do {page, _} = Integer.parse(page) @@ -192,8 +190,7 @@ def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "p end def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -213,7 +210,6 @@ def relay_followers(conn, _params) do def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user), {:show_followers, true} <- {:show_followers, (for_user && for_user == user) || !user.hide_followers} do {page, _} = Integer.parse(page) @@ -231,8 +227,7 @@ def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "p end def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -245,8 +240,7 @@ def outbox( %{"nickname" => nickname, "page" => page?} = params ) when page? in [true, "true"] do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {:ok, user} <- User.ensure_keys_present(user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do # "include_poll_votes" is a hack because postgres generates inefficient # queries when filtering by 'Answer', poll votes will be hidden by the # visibility filter in this case anyway @@ -270,8 +264,7 @@ def outbox( end def outbox(conn, %{"nickname" => nickname}) do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {:ok, user} <- User.ensure_keys_present(user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -328,14 +321,10 @@ defp post_inbox_relayed_create(conn, params) do end defp represent_service_actor(%User{} = user, conn) do - with {:ok, user} <- User.ensure_keys_present(user) do - conn - |> put_resp_content_type("application/activity+json") - |> put_view(UserView) - |> render("user.json", %{user: user}) - else - nil -> {:error, :not_found} - end + conn + |> put_resp_content_type("application/activity+json") + |> put_view(UserView) + |> render("user.json", %{user: user}) end defp represent_service_actor(nil, _), do: {:error, :not_found} @@ -388,12 +377,10 @@ def read_inbox( def read_inbox(%{assigns: %{user: %User{nickname: nickname} = user}} = conn, %{ "nickname" => nickname }) do - with {:ok, user} <- User.ensure_keys_present(user) do - conn - |> put_resp_content_type("application/activity+json") - |> put_view(UserView) - |> render("activity_collection.json", %{iri: "#{user.ap_id}/inbox"}) - end + conn + |> put_resp_content_type("application/activity+json") + |> put_view(UserView) + |> render("activity_collection.json", %{iri: "#{user.ap_id}/inbox"}) end def read_inbox(%{assigns: %{user: %User{nickname: as_nickname}}} = conn, %{ @@ -530,19 +517,6 @@ defp set_requester_reachable(%Plug.Conn{} = conn, _) do conn end - defp ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do - {:ok, new_user} = User.ensure_keys_present(user) - - for_user = - if new_user != user and match?(%User{}, for_user) do - User.get_cached_by_nickname(for_user.nickname) - else - for_user - end - - {new_user, for_user} - end - def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do with {:ok, object} <- ActivityPub.upload( diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex index 5b25138a4..532047599 100644 --- a/lib/pleroma/web/activity_pub/builder.ex +++ b/lib/pleroma/web/activity_pub/builder.ex @@ -218,10 +218,16 @@ def like(actor, object) do end end - # Retricted to user updates for now, always public @spec update(User.t(), Object.t()) :: {:ok, map(), keyword()} def update(actor, object) do - to = [Pleroma.Constants.as_public(), actor.follower_address] + {to, cc} = + if object["type"] in Pleroma.Constants.actor_types() do + # User updates, always public + {[Pleroma.Constants.as_public(), actor.follower_address], []} + else + # Status updates, follow the recipients in the object + {object["to"] || [], object["cc"] || []} + end {:ok, %{ @@ -229,7 +235,8 @@ def update(actor, object) do "type" => "Update", "actor" => actor.ap_id, "object" => object, - "to" => to + "to" => to, + "cc" => cc }, []} end diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex index 323ecdbf1..ff9f84497 100644 --- a/lib/pleroma/web/activity_pub/mrf.ex +++ b/lib/pleroma/web/activity_pub/mrf.ex @@ -53,10 +53,53 @@ defmodule Pleroma.Web.ActivityPub.MRF do @required_description_keys [:key, :related_policy] + def filter_one(policy, message) do + should_plug_history? = + if function_exported?(policy, :history_awareness, 0) do + policy.history_awareness() + else + :manual + end + |> Kernel.==(:auto) + + if not should_plug_history? do + policy.filter(message) + else + main_result = policy.filter(message) + + with {_, {:ok, main_message}} <- {:main, main_result}, + {_, + %{ + "formerRepresentations" => %{ + "orderedItems" => [_ | _] + } + }} = {_, object} <- {:object, message["object"]}, + {_, {:ok, new_history}} <- + {:history, + Pleroma.Object.Updater.for_each_history_item( + object["formerRepresentations"], + object, + fn item -> + with {:ok, filtered} <- policy.filter(Map.put(message, "object", item)) do + {:ok, filtered["object"]} + else + e -> e + end + end + )} do + {:ok, put_in(main_message, ["object", "formerRepresentations"], new_history)} + else + {:main, _} -> main_result + {:object, _} -> main_result + {:history, e} -> e + end + end + end + def filter(policies, %{} = message) do policies |> Enum.reduce({:ok, message}, fn - policy, {:ok, message} -> policy.filter(message) + policy, {:ok, message} -> filter_one(policy, message) _, error -> error end) end diff --git a/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex index f0504ead4..3ec9c52ee 100644 --- a/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex @@ -9,6 +9,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do require Logger + @impl true + def history_awareness, do: :auto + # has the user successfully posted before? defp old_user?(%User{} = u) do u.note_count > 0 || u.follower_count > 0 diff --git a/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex b/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex index 51596c09f..a148cc1e7 100644 --- a/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex +++ b/lib/pleroma/web/activity_pub/mrf/ensure_re_prepended.ex @@ -10,6 +10,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do @reply_prefix Regex.compile!("^re:[[:space:]]*", [:caseless]) + def history_awareness, do: :auto + def filter_by_summary( %{data: %{"summary" => parent_summary}} = _in_reply_to, %{"summary" => child_summary} = child @@ -27,8 +29,8 @@ def filter_by_summary( def filter_by_summary(_in_reply_to, child), do: child - def filter(%{"type" => "Create", "object" => child_object} = object) - when is_map(child_object) do + def filter(%{"type" => type, "object" => child_object} = object) + when type in ["Create", "Update"] and is_map(child_object) do child = child_object["inReplyTo"] |> Object.normalize(fetch: false) diff --git a/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex b/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex index 255910b2f..70224561c 100644 --- a/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex +++ b/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex @@ -11,6 +11,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do @behaviour Pleroma.Web.ActivityPub.MRF.Policy + @impl true + def history_awareness, do: :auto + defp do_extract({:a, attrs, _}, acc) do if Enum.find(attrs, fn {name, value} -> name == "class" && value in ["mention", "u-url mention", "mention u-url"] @@ -74,11 +77,11 @@ defp clean_recipients(recipients, object) do @impl true def filter( %{ - "type" => "Create", + "type" => type, "object" => %{"type" => "Note", "to" => to, "inReplyTo" => in_reply_to} } = object ) - when is_list(to) and is_binary(in_reply_to) do + when type in ["Create", "Update"] and is_list(to) and is_binary(in_reply_to) do # image-only posts from pleroma apparently reach this MRF without the content field content = object["object"]["content"] || "" diff --git a/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex b/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex index 2142b7add..b73fd974c 100644 --- a/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex @@ -16,6 +16,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do @behaviour Pleroma.Web.ActivityPub.MRF.Policy + @impl true + def history_awareness, do: :manual + defp check_reject(message, hashtags) do if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do {:reject, "[HashtagPolicy] Matches with rejected keyword"} @@ -47,22 +50,46 @@ defp check_ftl_removal(%{"to" => to} = message, hashtags) do defp check_ftl_removal(message, _hashtags), do: {:ok, message} - defp check_sensitive(message, hashtags) do - if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do - {:ok, Kernel.put_in(message, ["object", "sensitive"], true)} - else - {:ok, message} - end + defp check_sensitive(message) do + {:ok, new_object} = + Object.Updater.do_with_history(message["object"], fn object -> + hashtags = Object.hashtags(%Object{data: object}) + + if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do + {:ok, Map.put(object, "sensitive", true)} + else + {:ok, object} + end + end) + + {:ok, Map.put(message, "object", new_object)} end @impl true - def filter(%{"type" => "Create", "object" => object} = message) do - hashtags = Object.hashtags(%Object{data: object}) + def filter(%{"type" => type, "object" => object} = message) when type in ["Create", "Update"] do + history_items = + with %{"formerRepresentations" => %{"orderedItems" => items}} <- object do + items + else + _ -> [] + end + + historical_hashtags = + Enum.reduce(history_items, [], fn item, acc -> + acc ++ Object.hashtags(%Object{data: item}) + end) + + hashtags = Object.hashtags(%Object{data: object}) ++ historical_hashtags if hashtags != [] do with {:ok, message} <- check_reject(message, hashtags), - {:ok, message} <- check_ftl_removal(message, hashtags), - {:ok, message} <- check_sensitive(message, hashtags) do + {:ok, message} <- + (if "type" == "Create" do + check_ftl_removal(message, hashtags) + else + {:ok, message} + end), + {:ok, message} <- check_sensitive(message) do {:ok, message} end else diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex index 00b64744f..687ec6c2f 100644 --- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex @@ -27,24 +27,46 @@ defp object_payload(%{} = object) do end defp check_reject(%{"object" => %{} = object} = message) do - payload = object_payload(object) + with {:ok, _new_object} <- + Pleroma.Object.Updater.do_with_history(object, fn object -> + payload = object_payload(object) - if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern -> - string_matches?(payload, pattern) - end) do - {:reject, "[KeywordPolicy] Matches with rejected keyword"} - else + if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern -> + string_matches?(payload, pattern) + end) do + {:reject, "[KeywordPolicy] Matches with rejected keyword"} + else + {:ok, message} + end + end) do {:ok, message} + else + e -> e end end - defp check_ftl_removal(%{"to" => to, "object" => %{} = object} = message) do - payload = object_payload(object) + defp check_ftl_removal(%{"type" => "Create", "to" => to, "object" => %{} = object} = message) do + check_keyword = fn object -> + payload = object_payload(object) - if Pleroma.Constants.as_public() in to and - Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern -> + if Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern -> string_matches?(payload, pattern) end) do + {:should_delist, nil} + else + {:ok, %{}} + end + end + + should_delist? = fn object -> + with {:ok, _} <- Pleroma.Object.Updater.do_with_history(object, check_keyword) do + false + else + _ -> true + end + end + + if Pleroma.Constants.as_public() in to and should_delist?.(object) do to = List.delete(to, Pleroma.Constants.as_public()) cc = [Pleroma.Constants.as_public() | message["cc"] || []] @@ -59,8 +81,12 @@ defp check_ftl_removal(%{"to" => to, "object" => %{} = object} = message) do end end + defp check_ftl_removal(message) do + {:ok, message} + end + defp check_replace(%{"object" => %{} = object} = message) do - object = + replace_kw = fn object -> ["content", "name", "summary"] |> Enum.filter(fn field -> Map.has_key?(object, field) && object[field] end) |> Enum.reduce(object, fn field, object -> @@ -73,6 +99,10 @@ defp check_replace(%{"object" => %{} = object} = message) do Map.put(object, field, data) end) + |> (fn object -> {:ok, object} end).() + end + + {:ok, object} = Pleroma.Object.Updater.do_with_history(object, replace_kw) message = Map.put(message, "object", object) @@ -80,7 +110,8 @@ defp check_replace(%{"object" => %{} = object} = message) do end @impl true - def filter(%{"type" => "Create", "object" => %{"content" => _content}} = message) do + def filter(%{"type" => type, "object" => %{"content" => _content}} = message) + when type in ["Create", "Update"] do with {:ok, message} <- check_reject(message), {:ok, message} <- check_ftl_removal(message), {:ok, message} <- check_replace(message) do diff --git a/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex b/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex index 0eac8f021..c95d35bb9 100644 --- a/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/media_proxy_warming_policy.ex @@ -16,6 +16,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do recv_timeout: 10_000 ] + @impl true + def history_awareness, do: :auto + defp prefetch(url) do # Fetching only proxiable resources if MediaProxy.enabled?() and MediaProxy.url_proxiable?(url) do @@ -54,10 +57,8 @@ defp preload(%{"object" => %{"attachment" => attachments}} = _message) do end @impl true - def filter( - %{"type" => "Create", "object" => %{"attachment" => attachments} = _object} = message - ) - when is_list(attachments) and length(attachments) > 0 do + def filter(%{"type" => type, "object" => %{"attachment" => attachments} = _object} = message) + when type in ["Create", "Update"] and is_list(attachments) and length(attachments) > 0 do preload(message) {:ok, message} diff --git a/lib/pleroma/web/activity_pub/mrf/no_empty_policy.ex b/lib/pleroma/web/activity_pub/mrf/no_empty_policy.ex index 4dc96e068..855cda3b9 100644 --- a/lib/pleroma/web/activity_pub/mrf/no_empty_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/no_empty_policy.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoEmptyPolicy do @impl true def filter(%{"actor" => actor} = object) do with true <- is_local?(actor), + true <- is_eligible_type?(object), true <- is_note?(object), false <- has_attachment?(object), true <- only_mentions?(object) do @@ -32,7 +33,6 @@ defp is_local?(actor) do end defp has_attachment?(%{ - "type" => "Create", "object" => %{"type" => "Note", "attachment" => attachments} }) when length(attachments) > 0, @@ -40,7 +40,13 @@ defp has_attachment?(%{ defp has_attachment?(_), do: false - defp only_mentions?(%{"type" => "Create", "object" => %{"type" => "Note", "source" => source}}) do + defp only_mentions?(%{"object" => %{"type" => "Note", "source" => source}}) do + source = + case source do + %{"content" => text} -> text + _ -> source + end + non_mentions = source |> String.split() |> Enum.filter(&(not String.starts_with?(&1, "@"))) |> length @@ -53,9 +59,12 @@ defp only_mentions?(%{"type" => "Create", "object" => %{"type" => "Note", "sourc defp only_mentions?(_), do: false - defp is_note?(%{"type" => "Create", "object" => %{"type" => "Note"}}), do: true + defp is_note?(%{"object" => %{"type" => "Note"}}), do: true defp is_note?(_), do: false + defp is_eligible_type?(%{"type" => type}) when type in ["Create", "Update"], do: true + defp is_eligible_type?(_), do: false + @impl true def describe, do: {:ok, %{}} end diff --git a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex index aab647d8e..f81e9e52a 100644 --- a/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/no_placeholder_text_policy.ex @@ -6,14 +6,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy do @moduledoc "Ensure no content placeholder is present (such as the dot from mastodon)" @behaviour Pleroma.Web.ActivityPub.MRF.Policy + @impl true + def history_awareness, do: :auto + @impl true def filter( %{ - "type" => "Create", + "type" => type, "object" => %{"content" => content, "attachment" => _} = _child_object } = object ) - when content in [".", "

.

"] do + when type in ["Create", "Update"] and content in [".", "

.

"] do {:ok, put_in(object, ["object", "content"], "")} end diff --git a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex index dc2c19d49..2dfc9a901 100644 --- a/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex +++ b/lib/pleroma/web/activity_pub/mrf/normalize_markup.ex @@ -9,7 +9,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do @behaviour Pleroma.Web.ActivityPub.MRF.Policy @impl true - def filter(%{"type" => "Create", "object" => child_object} = object) do + def history_awareness, do: :auto + + @impl true + def filter(%{"type" => type, "object" => child_object} = object) + when type in ["Create", "Update"] do scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy]) content = diff --git a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex index 0e9d25a0a..df1a6dcbb 100644 --- a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex @@ -131,7 +131,7 @@ def config_description do type: {:list, :atom}, description: "A list of actions to apply to the post. `:delist` removes the post from public timelines; " <> - "`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <> + "`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines, additionally for followers-only it degrades to a direct message; " <> "`:reject` rejects the message entirely", suggestions: [:delist, :strip_followers, :reject] } diff --git a/lib/pleroma/web/activity_pub/mrf/policy.ex b/lib/pleroma/web/activity_pub/mrf/policy.ex index 0ac250c3d..0234de4d5 100644 --- a/lib/pleroma/web/activity_pub/mrf/policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/policy.ex @@ -12,5 +12,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.Policy do label: String.t(), description: String.t() } - @optional_callbacks config_description: 0 + @callback history_awareness() :: :auto | :manual + @optional_callbacks config_description: 0, history_awareness: 0 end diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index f3e31c931..5bcd6da46 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -103,8 +103,8 @@ def validate( meta ) when objtype in ~w[Question Answer Audio Video Event Article Note Page] do - with {:ok, object_data} <- cast_and_apply(object), - meta = Keyword.put(meta, :object_data, object_data |> stringify_keys), + with {:ok, object_data} <- cast_and_apply_and_stringify_with_history(object), + meta = Keyword.put(meta, :object_data, object_data), {:ok, create_activity} <- create_activity |> CreateGenericValidator.cast_and_validate(meta) @@ -128,19 +128,53 @@ def validate(%{"type" => type} = object, meta) end with {:ok, object} <- - object - |> validator.cast_and_validate() - |> Ecto.Changeset.apply_action(:insert) do - object = stringify_keys(object) + do_separate_with_history(object, fn object -> + with {:ok, object} <- + object + |> validator.cast_and_validate() + |> Ecto.Changeset.apply_action(:insert) do + object = stringify_keys(object) - # Insert copy of hashtags as strings for the non-hashtag table indexing - tag = (object["tag"] || []) ++ Object.hashtags(%Object{data: object}) - object = Map.put(object, "tag", tag) + # Insert copy of hashtags as strings for the non-hashtag table indexing + tag = (object["tag"] || []) ++ Object.hashtags(%Object{data: object}) + object = Map.put(object, "tag", tag) + {:ok, object} + end + end) do {:ok, object, meta} end end + def validate( + %{"type" => "Update", "object" => %{"type" => objtype} = object} = update_activity, + meta + ) + when objtype in ~w[Question Answer Audio Video Event Article Note Page] do + with {_, false} <- {:local, Access.get(meta, :local, false)}, + {_, {:ok, object_data, _}} <- {:object_validation, validate(object, meta)}, + meta = Keyword.put(meta, :object_data, object_data), + {:ok, update_activity} <- + update_activity + |> UpdateValidator.cast_and_validate() + |> Ecto.Changeset.apply_action(:insert) do + update_activity = stringify_keys(update_activity) + {:ok, update_activity, meta} + else + {:local, _} -> + with {:ok, object} <- + update_activity + |> UpdateValidator.cast_and_validate() + |> Ecto.Changeset.apply_action(:insert) do + object = stringify_keys(object) + {:ok, object, meta} + end + + {:object_validation, e} -> + e + end + end + def validate(%{"type" => type} = object, meta) when type in ~w[Accept Reject Follow Update Like EmojiReact Announce ChatMessage Answer] do @@ -178,6 +212,15 @@ def validate(%{"type" => type} = object, meta) when type in ~w(Add Remove) do def validate(o, m), do: {:error, {:validator_not_set, {o, m}}} + def cast_and_apply_and_stringify_with_history(object) do + do_separate_with_history(object, fn object -> + with {:ok, object_data} <- cast_and_apply(object), + object_data <- object_data |> stringify_keys() do + {:ok, object_data} + end + end) + end + def cast_and_apply(%{"type" => "ChatMessage"} = object) do ChatMessageValidator.cast_and_apply(object) end @@ -204,8 +247,7 @@ def cast_and_apply(%{"type" => type} = object) when type in ~w[Article Note Page def cast_and_apply(o), do: {:error, {:validator_not_set, o}} - # is_struct/1 appears in Elixir 1.11 - def stringify_keys(%{__struct__: _} = object) do + def stringify_keys(object) when is_struct(object) do object |> Map.from_struct() |> stringify_keys @@ -236,4 +278,54 @@ def fetch_actor_and_object(object) do Object.normalize(object["object"], fetch: true) :ok end + + defp for_each_history_item( + %{"type" => "OrderedCollection", "orderedItems" => items} = history, + object, + fun + ) do + processed_items = + Enum.map(items, fn item -> + with item <- Map.put(item, "id", object["id"]), + {:ok, item} <- fun.(item) do + item + else + _ -> nil + end + end) + + if Enum.all?(processed_items, &(not is_nil(&1))) do + {:ok, Map.put(history, "orderedItems", processed_items)} + else + {:error, :invalid_history} + end + end + + defp for_each_history_item(nil, _object, _fun) do + {:ok, nil} + end + + defp for_each_history_item(_, _object, _fun) do + {:error, :invalid_history} + end + + # fun is (object -> {:ok, validated_object_with_string_keys}) + defp do_separate_with_history(object, fun) do + with history <- object["formerRepresentations"], + object <- Map.drop(object, ["formerRepresentations"]), + {_, {:ok, object}} <- {:main_body, fun.(object)}, + {_, {:ok, history}} <- {:history_items, for_each_history_item(history, object, fun)} do + object = + if history do + Map.put(object, "formerRepresentations", history) + else + object + end + + {:ok, object} + else + {:main_body, e} -> e + {:history_items, e} -> e + end + end 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 ca335bc8a..2670e3f17 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 @@ -49,7 +49,10 @@ defp fix_url(%{"url" => url} = data) when is_bitstring(url), do: data defp fix_url(%{"url" => url} = data) when is_map(url), do: Map.put(data, "url", url["href"]) defp fix_url(data), do: data - defp fix_tag(%{"tag" => tag} = data) when is_list(tag), do: data + defp fix_tag(%{"tag" => tag} = data) when is_list(tag) do + Map.put(data, "tag", Enum.filter(tag, &is_map/1)) + end + defp fix_tag(%{"tag" => tag} = data) when is_map(tag), do: Map.put(data, "tag", [tag]) defp fix_tag(data), do: Map.drop(data, ["tag"]) @@ -60,11 +63,19 @@ defp fix_replies(%{"replies" => %{"first" => %{"items" => replies}}} = data) defp fix_replies(%{"replies" => %{"items" => replies}} = data) when is_list(replies), do: Map.put(data, "replies", replies) - defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies), + # TODO: Pleroma does not have any support for Collections at the moment. + # If the `replies` field is not something the ObjectID validator can handle, + # the activity/object would be rejected, which is bad behavior. + defp fix_replies(%{"replies" => replies} = data) when not is_list(replies), do: Map.drop(data, ["replies"]) defp fix_replies(data), do: data + def fix_attachments(%{"attachment" => attachment} = data) when is_map(attachment), + do: Map.put(data, "attachment", [attachment]) + + def fix_attachments(data), do: data + defp fix(data) do data |> CommonFixes.fix_actor() @@ -72,6 +83,7 @@ defp fix(data) do |> fix_url() |> fix_tag() |> fix_replies() + |> fix_attachments() |> Transmogrifier.fix_emoji() |> Transmogrifier.fix_content_map() end @@ -88,7 +100,7 @@ def changeset(struct, data) do defp validate_data(data_cng) do data_cng |> validate_inclusion(:type, ["Article", "Note", "Page"]) - |> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id]) + |> validate_required([:id, :actor, :attributedTo, :type, :context]) |> CommonValidations.validate_any_presence([:cc, :to]) |> CommonValidations.validate_fields_match([:actor, :attributedTo]) |> CommonValidations.validate_actor_presence() diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex index 8b641d88d..398020bff 100644 --- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do @primary_key false embedded_schema do + field(:id, :string) field(:type, :string) field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream") field(:name, :string) @@ -43,10 +44,10 @@ def changeset(struct, data) do |> fix_url() struct - |> cast(data, [:type, :mediaType, :name, :blurhash]) - |> cast_embed(:url, with: &url_changeset/2) + |> cast(data, [:id, :type, :mediaType, :name, :blurhash]) + |> cast_embed(:url, with: &url_changeset/2, required: true) |> validate_inclusion(:type, ~w[Link Document Audio Image Video]) - |> validate_required([:type, :mediaType, :url]) + |> validate_required([:type, :mediaType]) end def url_changeset(struct, data) do @@ -59,7 +60,7 @@ def url_changeset(struct, data) do end def fix_media_type(data) do - Map.put_new(data, "mediaType", data["mimeType"]) + Map.put_new(data, "mediaType", data["mimeType"] || "application/octet-stream") end defp handle_href(href, mediaType, data) do @@ -90,6 +91,6 @@ defp fix_url(data) do defp validate_data(cng) do cng |> validate_inclusion(:type, ~w[Document Audio Image Video]) - |> validate_required([:mediaType, :url, :type]) + |> validate_required([:mediaType, :type]) end end diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex index 432bd9039..671a7ef0c 100644 --- a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex @@ -104,14 +104,14 @@ def changeset(struct, data) do struct |> cast(data, __schema__(:fields) -- [:attachment, :tag]) - |> cast_embed(:attachment) + |> cast_embed(:attachment, required: true) |> cast_embed(:tag) end defp validate_data(data_cng) do data_cng |> validate_inclusion(:type, ["Audio", "Video"]) - |> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment]) + |> validate_required([:id, :actor, :attributedTo, :type, :context]) |> CommonValidations.validate_any_presence([:cc, :to]) |> CommonValidations.validate_fields_match([:actor, :attributedTo]) |> CommonValidations.validate_actor_presence() diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex index 8e768ffbf..7b60c139a 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex @@ -33,6 +33,7 @@ defmacro object_fields do field(:content, :string) field(:published, ObjectValidators.DateTime) + field(:updated, ObjectValidators.DateTime) field(:emoji, ObjectValidators.Emoji, default: %{}) embeds_many(:attachment, AttachmentValidator) end @@ -51,8 +52,6 @@ defmacro status_object_fields do field(:summary, :string) field(:context, :string) - # short identifier for PleromaFE to group statuses by context - field(:context_id, :integer) field(:sensitive, :boolean, default: false) field(:replies_count, :integer, default: 0) diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex index 4f8c083eb..add46d561 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex @@ -22,14 +22,15 @@ def cast_and_filter_recipients(message, field, follower_collection, field_fallba end def fix_object_defaults(data) do - %{data: %{"id" => context}, id: context_id} = - Utils.create_context(data["context"] || data["conversation"]) + context = + Utils.maybe_create_context( + data["context"] || data["conversation"] || data["inReplyTo"] || data["id"] + ) %User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"]) data |> Map.put("context", context) - |> Map.put("context_id", context_id) |> cast_and_filter_recipients("to", follower_collection) |> cast_and_filter_recipients("cc", follower_collection) |> cast_and_filter_recipients("bto", follower_collection) diff --git a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex index c9a621cb1..2395abfd4 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex @@ -75,7 +75,7 @@ def fix(data, meta) do data |> CommonFixes.fix_actor() - |> Map.put_new("context", object["context"]) + |> Map.put("context", object["context"]) |> fix_addressing(object) end diff --git a/lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex b/lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex index ed072b888..0858281e5 100644 --- a/lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex @@ -49,6 +49,7 @@ def changeset(struct, data) do defp fix(data) do data = data + |> fix_emoji_qualification() |> CommonFixes.fix_actor() |> CommonFixes.fix_activity_addressing() @@ -61,6 +62,23 @@ defp fix(data) do end end + defp fix_emoji_qualification(%{"content" => emoji} = data) do + new_emoji = Pleroma.Emoji.fully_qualify_emoji(emoji) + + cond do + Pleroma.Emoji.is_unicode_emoji?(emoji) -> + data + + Pleroma.Emoji.is_unicode_emoji?(new_emoji) -> + data |> Map.put("content", new_emoji) + + true -> + data + end + end + + defp fix_emoji_qualification(data), do: data + defp validate_emoji(cng) do content = get_field(cng, :content) diff --git a/lib/pleroma/web/activity_pub/object_validators/event_validator.ex b/lib/pleroma/web/activity_pub/object_validators/event_validator.ex index 0e99f2037..ab204f69a 100644 --- a/lib/pleroma/web/activity_pub/object_validators/event_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/event_validator.ex @@ -62,7 +62,7 @@ def changeset(struct, data) do defp validate_data(data_cng) do data_cng |> validate_inclusion(:type, ["Event"]) - |> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id]) + |> validate_required([:id, :actor, :attributedTo, :type, :context]) |> CommonValidations.validate_any_presence([:cc, :to]) |> CommonValidations.validate_fields_match([:actor, :attributedTo]) |> CommonValidations.validate_actor_presence() diff --git a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex index 9412be4bc..ce3305142 100644 --- a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex @@ -80,7 +80,7 @@ def changeset(struct, data) do defp validate_data(data_cng) do data_cng |> validate_inclusion(:type, ["Question"]) - |> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id]) + |> validate_required([:id, :actor, :attributedTo, :type, :context]) |> CommonValidations.validate_any_presence([:cc, :to]) |> CommonValidations.validate_fields_match([:actor, :attributedTo]) |> CommonValidations.validate_actor_presence() diff --git a/lib/pleroma/web/activity_pub/object_validators/update_validator.ex b/lib/pleroma/web/activity_pub/object_validators/update_validator.ex index a5def312e..1e940a400 100644 --- a/lib/pleroma/web/activity_pub/object_validators/update_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/update_validator.ex @@ -51,7 +51,9 @@ def validate_updating_rights(cng) do with actor = get_field(cng, :actor), object = get_field(cng, :object), {:ok, object_id} <- ObjectValidators.ObjectID.cast(object), - true <- actor == object_id do + actor_uri <- URI.parse(actor), + object_uri <- URI.parse(object_id), + true <- actor_uri.host == object_uri.host do cng else _e -> diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index b997c15db..a2152b945 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -25,6 +25,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do alias Pleroma.Web.Streamer alias Pleroma.Workers.PollWorker + require Pleroma.Constants require Logger @cachex Pleroma.Config.get([:cachex, :provider], Cachex) @@ -153,23 +154,26 @@ def handle( # Tasks this handles: # - Update the user + # - Update a non-user object (Note, Question, etc.) # # For a local user, we also get a changeset with the full information, so we # can update non-federating, non-activitypub settings as well. @impl true def handle(%{data: %{"type" => "Update", "object" => updated_object}} = object, meta) do - if changeset = Keyword.get(meta, :user_update_changeset) do - changeset - |> User.update_and_set_cache() + updated_object_id = updated_object["id"] + + with {_, true} <- {:has_id, is_binary(updated_object_id)}, + %{"type" => type} <- updated_object, + {_, is_user} <- {:is_user, type in Pleroma.Constants.actor_types()} do + if is_user do + handle_update_user(object, meta) + else + handle_update_object(object, meta) + end else - {:ok, new_user_data} = ActivityPub.user_data_from_user_object(updated_object) - - User.get_by_ap_id(updated_object["id"]) - |> User.remote_user_changeset(new_user_data) - |> User.update_and_set_cache() + _ -> + {:ok, object, meta} end - - {:ok, object, meta} end # Tasks this handles: @@ -278,7 +282,6 @@ def handle(%{data: %{"type" => "EmojiReact"}} = object, meta) do # Tasks this handles: # - Delete and unpins the create activity # - Replace object with Tombstone - # - Set up notification # - Reduce the user note count # - Reduce the reply count # - Stream out the activity @@ -320,7 +323,6 @@ def handle(%{data: %{"type" => "Delete", "object" => deleted_object}} = object, end if result == :ok do - Notification.create_notifications(object) {:ok, object, meta} else {:error, result} @@ -390,6 +392,79 @@ def handle(object, meta) do {:ok, object, meta} end + defp handle_update_user( + %{data: %{"type" => "Update", "object" => updated_object}} = object, + meta + ) do + if changeset = Keyword.get(meta, :user_update_changeset) do + changeset + |> User.update_and_set_cache() + else + {:ok, new_user_data} = ActivityPub.user_data_from_user_object(updated_object) + + User.get_by_ap_id(updated_object["id"]) + |> User.remote_user_changeset(new_user_data) + |> User.update_and_set_cache() + end + + {:ok, object, meta} + end + + defp handle_update_object( + %{data: %{"type" => "Update", "object" => updated_object}} = object, + meta + ) do + orig_object_ap_id = updated_object["id"] + orig_object = Object.get_by_ap_id(orig_object_ap_id) + orig_object_data = orig_object.data + + updated_object = + if meta[:local] do + # If this is a local Update, we don't process it by transmogrifier, + # so we use the embedded object as-is. + updated_object + else + meta[:object_data] + end + + if orig_object_data["type"] in Pleroma.Constants.updatable_object_types() do + %{ + updated_data: updated_object_data, + updated: updated, + used_history_in_new_object?: used_history_in_new_object? + } = Object.Updater.make_new_object_data_from_update_object(orig_object_data, updated_object) + + changeset = + orig_object + |> Repo.preload(:hashtags) + |> Object.change(%{data: updated_object_data}) + + with {:ok, new_object} <- Repo.update(changeset), + {:ok, _} <- Object.invalid_object_cache(new_object), + {:ok, _} <- Object.set_cache(new_object), + # The metadata/utils.ex uses the object id for the cache. + {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(new_object.id) do + if used_history_in_new_object? do + with create_activity when not is_nil(create_activity) <- + Pleroma.Activity.get_create_by_object_ap_id(orig_object_ap_id), + {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(create_activity.id) do + nil + else + _ -> nil + end + end + + if updated do + object + |> Activity.normalize() + |> ActivityPub.notify_and_stream() + end + end + end + + {:ok, object, meta} + end + def handle_object_creation(%{"type" => "ChatMessage"} = object, _activity, meta) do with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do actor = User.get_cached_by_ap_id(object.data["actor"]) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index d6622df86..e4c04da0d 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -687,6 +687,24 @@ def prepare_object(object) do |> strip_internal_fields |> strip_internal_tags |> set_type + |> maybe_process_history + end + + defp maybe_process_history(%{"formerRepresentations" => %{"orderedItems" => history}} = object) do + processed_history = + Enum.map( + history, + fn + item when is_map(item) -> prepare_object(item) + item -> item + end + ) + + put_in(object, ["formerRepresentations", "orderedItems"], processed_history) + end + + defp maybe_process_history(object) do + object end # @doc @@ -711,6 +729,21 @@ def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data) {:ok, data} end + def prepare_outgoing(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data) + when objtype in Pleroma.Constants.updatable_object_types() do + object = + object + |> prepare_object + + data = + data + |> Map.put("object", object) + |> Map.merge(Utils.make_json_ld_header()) + |> Map.delete("bcc") + + {:ok, data} + end + def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do object = object_id diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 9cde7805c..b898d6fe8 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -154,22 +154,7 @@ def get_notified_from_object(object) do Notification.get_notified_from_activity(%Activity{data: object}, false) end - def create_context(context) do - context = context || generate_id("contexts") - - # Ecto has problems accessing the constraint inside the jsonb, - # so we explicitly check for the existed object before insert - object = Object.get_cached_by_ap_id(context) - - with true <- is_nil(object), - changeset <- Object.context_mapping(context), - {:ok, inserted_object} <- Repo.insert(changeset) do - inserted_object - else - _ -> - object - end - end + def maybe_create_context(context), do: context || generate_id("contexts") @doc """ Enqueues an activity for federation if it's local @@ -201,18 +186,16 @@ def lazy_put_activity_defaults(map, true) do |> Map.put_new("id", "pleroma:fakeid") |> Map.put_new_lazy("published", &make_date/0) |> Map.put_new("context", "pleroma:fakecontext") - |> Map.put_new("context_id", -1) |> lazy_put_object_defaults(true) end def lazy_put_activity_defaults(map, _fake?) do - %{data: %{"id" => context}, id: context_id} = create_context(map["context"]) + context = maybe_create_context(map["context"]) map |> Map.put_new_lazy("id", &generate_activity_id/0) |> Map.put_new_lazy("published", &make_date/0) |> Map.put_new("context", context) - |> Map.put_new("context_id", context_id) |> lazy_put_object_defaults(false) end @@ -226,7 +209,6 @@ defp lazy_put_object_defaults(%{"object" => map} = activity, true) |> Map.put_new("id", "pleroma:fake_object_id") |> Map.put_new_lazy("published", &make_date/0) |> Map.put_new("context", activity["context"]) - |> Map.put_new("context_id", activity["context_id"]) |> Map.put_new("fake", true) %{activity | "object" => object} @@ -239,7 +221,6 @@ defp lazy_put_object_defaults(%{"object" => map} = activity, _) |> Map.put_new_lazy("id", &generate_object_id/0) |> Map.put_new_lazy("published", &make_date/0) |> Map.put_new("context", activity["context"]) - |> Map.put_new("context_id", activity["context_id"]) %{activity | "object" => object} end @@ -714,20 +695,24 @@ defp build_flag_object(%{statuses: statuses}) do Enum.map(statuses || [], &build_flag_object/1) end - defp build_flag_object(%Activity{data: %{"id" => id}, object: %{data: data}}) do - activity_actor = User.get_by_ap_id(data["actor"]) + defp build_flag_object(%Activity{} = activity) do + object = Object.normalize(activity, fetch: false) - %{ - "type" => "Note", - "id" => id, - "content" => data["content"], - "published" => data["published"], - "actor" => - AccountView.render( - "show.json", - %{user: activity_actor, skip_visibility_check: true} - ) - } + # Do not allow people to report Creates. Instead, report the Object that is Created. + if activity.data["type"] != "Create" do + build_flag_object_with_actor_and_id( + object, + User.get_by_ap_id(activity.data["actor"]), + activity.data["id"] + ) + else + build_flag_object(object) + end + end + + defp build_flag_object(%Object{} = object) do + actor = User.get_by_ap_id(object.data["actor"]) + build_flag_object_with_actor_and_id(object, actor, object.data["id"]) end defp build_flag_object(act) when is_map(act) or is_binary(act) do @@ -739,12 +724,12 @@ defp build_flag_object(act) when is_map(act) or is_binary(act) do end case Activity.get_by_ap_id_with_object(id) do - %Activity{} = activity -> - build_flag_object(activity) + %Activity{object: object} = _ -> + build_flag_object(object) nil -> - if activity = Activity.get_by_object_ap_id_with_object(id) do - build_flag_object(activity) + if %Object{} = object = Object.get_by_ap_id(id) do + build_flag_object(object) else %{"id" => id, "deleted" => true} end @@ -753,6 +738,20 @@ defp build_flag_object(act) when is_map(act) or is_binary(act) do defp build_flag_object(_), do: [] + defp build_flag_object_with_actor_and_id(%Object{data: data}, actor, id) do + %{ + "type" => "Note", + "id" => id, + "content" => data["content"], + "published" => data["published"], + "actor" => + AccountView.render( + "show.json", + %{user: actor, skip_visibility_check: true} + ) + } + end + #### Report-related helpers def get_reports(params, page, page_size) do params = @@ -767,22 +766,21 @@ def get_reports(params, page, page_size) do ActivityPub.fetch_activities([], params, :offset) end - def update_report_state(%Activity{} = activity, state) - when state in @strip_status_report_states do - {:ok, stripped_activity} = strip_report_status_data(activity) - - new_data = - activity.data - |> Map.put("state", state) - |> Map.put("object", stripped_activity.data["object"]) - - activity - |> Changeset.change(data: new_data) - |> Repo.update() + defp maybe_strip_report_status(data, state) do + with true <- Config.get([:instance, :report_strip_status]), + true <- state in @strip_status_report_states, + {:ok, stripped_activity} = strip_report_status_data(%Activity{data: data}) do + data |> Map.put("object", stripped_activity.data["object"]) + else + _ -> data + end end def update_report_state(%Activity{} = activity, state) when state in @supported_report_states do - new_data = Map.put(activity.data, "state", state) + new_data = + activity.data + |> Map.put("state", state) + |> maybe_strip_report_status(state) activity |> Changeset.change(data: new_data) diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index f848aba3a..63caa915c 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -29,11 +29,11 @@ def render("object.json", %{object: %Activity{data: %{"type" => activity_type}} def render("object.json", %{object: %Activity{} = activity}) do base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header() - object = Object.normalize(activity, fetch: false) + object_id = Object.normalize(activity, id_only: true) additional = Transmogrifier.prepare_object(activity.data) - |> Map.put("object", object.data["id"]) + |> Map.put("object", object_id) Map.merge(base, additional) end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 52f6bb56d..f69fca075 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -34,7 +34,6 @@ def render("endpoints.json", %{user: %User{local: true} = _user}) do def render("endpoints.json", _), do: %{} def render("service.json", %{user: user}) do - {:ok, user} = User.ensure_keys_present(user) {:ok, _, public_key} = Keys.keys_from_pem(user.keys) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_encode([public_key]) @@ -71,7 +70,6 @@ def render("user.json", %{user: %User{nickname: "internal." <> _} = user}), do: render("service.json", %{user: user}) |> Map.put("preferredUsername", user.nickname) def render("user.json", %{user: user}) do - {:ok, user} = User.ensure_keys_present(user) {:ok, _, public_key} = Keys.keys_from_pem(user.keys) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_encode([public_key]) diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex index 465f8a9b7..7c57f88f9 100644 --- a/lib/pleroma/web/activity_pub/visibility.ex +++ b/lib/pleroma/web/activity_pub/visibility.ex @@ -84,7 +84,10 @@ def visible_for_user?(%{__struct__: module} = message, user) when module in [Activity, Object] do x = [user.ap_id | User.following(user)] y = [message.data["actor"]] ++ message.data["to"] ++ (message.data["cc"] || []) - is_public?(message) || Enum.any?(x, &(&1 in y)) + + user_is_local = user.local + federatable = not is_local_public?(message) + (is_public?(message) || Enum.any?(x, &(&1 in y))) and (user_is_local || federatable) end def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do diff --git a/lib/pleroma/web/admin_api/controllers/chat_controller.ex b/lib/pleroma/web/admin_api/controllers/chat_controller.ex index c3e9e12ce..298543fcf 100644 --- a/lib/pleroma/web/admin_api/controllers/chat_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/chat_controller.ex @@ -8,7 +8,6 @@ defmodule Pleroma.Web.AdminAPI.ChatController do alias Pleroma.Activity alias Pleroma.Chat alias Pleroma.Chat.MessageReference - alias Pleroma.ModerationLog alias Pleroma.Pagination alias Pleroma.Web.AdminAPI alias Pleroma.Web.CommonAPI @@ -42,12 +41,6 @@ def delete_message(%{assigns: %{user: user}} = conn, %{ ^chat_id <- to_string(cm_ref.chat_id), %Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object_ap_id), {:ok, _} <- CommonAPI.delete(activity_id, user) do - ModerationLog.insert_log(%{ - action: "chat_message_delete", - actor: user, - subject_id: message_id - }) - conn |> put_view(MessageReferenceView) |> render("show.json", chat_message_reference: cm_ref) diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex index 55ab6d063..a03318c0e 100644 --- a/lib/pleroma/web/admin_api/controllers/config_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex @@ -22,10 +22,58 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.ConfigOperation + defp translate_descriptions(descriptions, path \\ []) do + Enum.map(descriptions, fn desc -> translate_item(desc, path) end) + end + + defp translate_string(str, path, type) do + Gettext.dpgettext( + Pleroma.Web.Gettext, + "config_descriptions", + Pleroma.Docs.Translator.Compiler.msgctxt_for(path, type), + str + ) + end + + defp maybe_put_translated(item, key, path) do + if item[key] do + Map.put( + item, + key, + translate_string( + item[key], + path ++ [Pleroma.Docs.Translator.Compiler.key_for(item)], + to_string(key) + ) + ) + else + item + end + end + + defp translate_item(item, path) do + item + |> maybe_put_translated(:label, path) + |> maybe_put_translated(:description, path) + |> translate_children(path) + end + + defp translate_children(%{children: children} = item, path) when is_list(children) do + item + |> Map.put( + :children, + translate_descriptions(children, path ++ [Pleroma.Docs.Translator.Compiler.key_for(item)]) + ) + end + + defp translate_children(item, _path) do + item + end + def descriptions(conn, _params) do descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1) - json(conn, descriptions) + json(conn, translate_descriptions(descriptions)) end def show(conn, %{only_db: true}) do diff --git a/lib/pleroma/web/admin_api/controllers/status_controller.ex b/lib/pleroma/web/admin_api/controllers/status_controller.ex index c9a4bfde9..9a3d49b57 100644 --- a/lib/pleroma/web/admin_api/controllers/status_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/status_controller.ex @@ -65,12 +65,6 @@ def update(%{assigns: %{user: admin}, body_params: params} = conn, %{id: id}) do def delete(%{assigns: %{user: user}} = conn, %{id: id}) do with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do - ModerationLog.insert_log(%{ - action: "status_delete", - actor: user, - subject_id: id - }) - json(conn, %{}) end end diff --git a/lib/pleroma/web/admin_api/report.ex b/lib/pleroma/web/admin_api/report.ex index 8d1abfa56..c79bee27e 100644 --- a/lib/pleroma/web/admin_api/report.ex +++ b/lib/pleroma/web/admin_api/report.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.AdminAPI.Report do alias Pleroma.Activity + alias Pleroma.Object alias Pleroma.User def extract_report_info( @@ -16,10 +17,44 @@ def extract_report_info( status_ap_ids |> Enum.reject(&is_nil(&1)) |> Enum.map(fn - act when is_map(act) -> Activity.get_by_ap_id_with_object(act["id"]) - act when is_binary(act) -> Activity.get_by_ap_id_with_object(act) + act when is_map(act) -> + Activity.get_create_by_object_ap_id_with_object(act["id"]) || + Activity.get_by_ap_id_with_object(act["id"]) || make_fake_activity(act, user) + + act when is_binary(act) -> + Activity.get_create_by_object_ap_id_with_object(act) || + Activity.get_by_ap_id_with_object(act) end) %{report: report, user: user, account: account, statuses: statuses} end + + defp make_fake_activity(act, user) do + %Activity{ + id: "pleroma:fake", + data: %{ + "actor" => user.ap_id, + "type" => "Create", + "to" => [], + "cc" => [], + "object" => act["id"], + "published" => act["published"], + "id" => act["id"], + "context" => "pleroma:fake" + }, + recipients: [user.ap_id], + object: %Object{ + data: %{ + "actor" => user.ap_id, + "type" => "Note", + "content" => act["content"], + "published" => act["published"], + "to" => [], + "cc" => [], + "id" => act["id"], + "context" => "pleroma:fake" + } + } + } + end end diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index a64762285..aabe988f7 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -64,7 +64,8 @@ def update_credentials_operation do requestBody: request_body("Parameters", update_credentials_request(), required: true), responses: %{ 200 => Operation.response("Account", "application/json", Account), - 403 => Operation.response("Error", "application/json", ApiError) + 403 => Operation.response("Error", "application/json", ApiError), + 413 => Operation.response("Error", "application/json", ApiError) } } end @@ -223,12 +224,12 @@ def follow_operation do type: :object, properties: %{ reblogs: %Schema{ - type: :boolean, + allOf: [BooleanLike], description: "Receive this account's reblogs in home timeline? Defaults to true.", default: true }, notify: %Schema{ - type: :boolean, + allOf: [BooleanLike], description: "Receive notifications for all statuses posted by the account? Defaults to false.", default: false @@ -278,11 +279,17 @@ def mute_operation do %Schema{allOf: [BooleanLike], default: true}, "Mute notifications in addition to statuses? Defaults to `true`." ), + Operation.parameter( + :duration, + :query, + %Schema{type: :integer}, + "Expire the mute in `duration` seconds. Default 0 for infinity" + ), Operation.parameter( :expires_in, :query, %Schema{type: :integer, default: 0}, - "Expire the mute in `expires_in` seconds. Default 0 for infinity" + "Deprecated, use `duration` instead" ) ], responses: %{ @@ -370,6 +377,22 @@ def unendorse_operation do } end + def remove_from_followers_operation do + %Operation{ + tags: ["Account actions"], + summary: "Remove from followers", + operationId: "AccountController.remove_from_followers", + security: [%{"oAuth" => ["follow", "write:follows"]}], + description: "Remove the given account from followers", + parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}], + responses: %{ + 200 => Operation.response("Relationship", "application/json", AccountRelationship), + 400 => Operation.response("Error", "application/json", ApiError), + 404 => Operation.response("Error", "application/json", ApiError) + } + } + end + def note_operation do %Operation{ tags: ["Account actions"], @@ -545,10 +568,18 @@ defp create_request do description: "Invite token required when the registrations aren't public" }, birthday: %Schema{ - type: :string, nullable: true, description: "User's birthday", - format: :date + anyOf: [ + %Schema{ + type: :string, + format: :date + }, + %Schema{ + type: :string, + maxLength: 0 + } + ] }, language: %Schema{ type: :string, @@ -733,10 +764,18 @@ defp update_credentials_request do }, actor_type: ActorType, birthday: %Schema{ - type: :string, nullable: true, description: "User's birthday", - format: :date + anyOf: [ + %Schema{ + type: :string, + format: :date + }, + %Schema{ + type: :string, + maxLength: 0 + } + ] }, show_birthday: %Schema{ allOf: [BooleanLike], @@ -861,10 +900,15 @@ defp mute_request do description: "Mute notifications in addition to statuses? Defaults to true.", default: true }, + duration: %Schema{ + type: :integer, + nullable: true, + description: "Expire the mute in `expires_in` seconds. Default 0 for infinity" + }, expires_in: %Schema{ type: :integer, nullable: true, - description: "Expire the mute in `expires_in` seconds. Default 0 for infinity", + description: "Deprecated, use `duration` instead", default: 0 } }, diff --git a/lib/pleroma/web/api_spec/operations/notification_operation.ex b/lib/pleroma/web/api_spec/operations/notification_operation.ex index 7f2336ff6..56aa129d2 100644 --- a/lib/pleroma/web/api_spec/operations/notification_operation.ex +++ b/lib/pleroma/web/api_spec/operations/notification_operation.ex @@ -51,6 +51,12 @@ def index_operation do :include_types, :query, %Schema{type: :array, items: notification_type()}, + "Deprecated, use `types` instead" + ), + Operation.parameter( + :types, + :query, + %Schema{type: :array, items: notification_type()}, "Include the notifications for activities with the given types" ), Operation.parameter( diff --git a/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex index 82ec1e7bb..45fa2b058 100644 --- a/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex +++ b/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex @@ -16,7 +16,7 @@ def index_operation do %Operation{ tags: ["Backups"], summary: "List backups", - security: [%{"oAuth" => ["read:account"]}], + security: [%{"oAuth" => ["read:backups"]}], operationId: "PleromaAPI.BackupController.index", responses: %{ 200 => @@ -37,7 +37,7 @@ def create_operation do %Operation{ tags: ["Backups"], summary: "Create a backup", - security: [%{"oAuth" => ["read:account"]}], + security: [%{"oAuth" => ["read:backups"]}], operationId: "PleromaAPI.BackupController.create", responses: %{ 200 => diff --git a/lib/pleroma/web/api_spec/operations/pleroma_settings_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_settings_operation.ex new file mode 100644 index 000000000..e2cef4f67 --- /dev/null +++ b/lib/pleroma/web/api_spec/operations/pleroma_settings_operation.ex @@ -0,0 +1,72 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.PleromaSettingsOperation do + alias OpenApiSpex.Operation + alias OpenApiSpex.Schema + + import Pleroma.Web.ApiSpec.Helpers + + def open_api_operation(action) do + operation = String.to_existing_atom("#{action}_operation") + apply(__MODULE__, operation, []) + end + + def show_operation do + %Operation{ + tags: ["Settings"], + summary: "Get settings for an application", + description: "Get synchronized settings for an application", + operationId: "SettingsController.show", + parameters: [app_name_param()], + security: [%{"oAuth" => ["read:accounts"]}], + responses: %{ + 200 => Operation.response("object", "application/json", object()) + } + } + end + + def update_operation do + %Operation{ + tags: ["Settings"], + summary: "Update settings for an application", + description: "Update synchronized settings for an application", + operationId: "SettingsController.update", + parameters: [app_name_param()], + security: [%{"oAuth" => ["write:accounts"]}], + requestBody: request_body("Parameters", update_request(), required: true), + responses: %{ + 200 => Operation.response("object", "application/json", object()) + } + } + end + + def app_name_param do + Operation.parameter(:app, :path, %Schema{type: :string}, "Application name", + example: "pleroma-fe", + required: true + ) + end + + def object do + %Schema{ + title: "Settings object", + description: "The object that contains settings for the application.", + type: :object + } + end + + def update_request do + %Schema{ + title: "SettingsUpdateRequest", + type: :object, + description: + "The settings object to be merged with the current settings. To remove a field, set it to null.", + example: %{ + "config1" => true, + "config2_to_unset" => nil + } + } + end +end diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex index 639f24d49..e921128c7 100644 --- a/lib/pleroma/web/api_spec/operations/status_operation.ex +++ b/lib/pleroma/web/api_spec/operations/status_operation.ex @@ -6,9 +6,13 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do alias OpenApiSpex.Operation alias OpenApiSpex.Schema alias Pleroma.Web.ApiSpec.AccountOperation + alias Pleroma.Web.ApiSpec.Schemas.Account alias Pleroma.Web.ApiSpec.Schemas.ApiError + alias Pleroma.Web.ApiSpec.Schemas.Attachment alias Pleroma.Web.ApiSpec.Schemas.BooleanLike + alias Pleroma.Web.ApiSpec.Schemas.Emoji alias Pleroma.Web.ApiSpec.Schemas.FlakeID + alias Pleroma.Web.ApiSpec.Schemas.Poll alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus alias Pleroma.Web.ApiSpec.Schemas.Status alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope @@ -434,6 +438,59 @@ def bookmarks_operation do } end + def show_history_operation do + %Operation{ + tags: ["Retrieve status history"], + summary: "Status history", + description: "View history of a status", + operationId: "StatusController.show_history", + security: [%{"oAuth" => ["read:statuses"]}], + parameters: [ + id_param() + ], + responses: %{ + 200 => status_history_response(), + 404 => Operation.response("Not Found", "application/json", ApiError) + } + } + end + + def show_source_operation do + %Operation{ + tags: ["Retrieve status source"], + summary: "Status source", + description: "View source of a status", + operationId: "StatusController.show_source", + security: [%{"oAuth" => ["read:statuses"]}], + parameters: [ + id_param() + ], + responses: %{ + 200 => status_source_response(), + 404 => Operation.response("Not Found", "application/json", ApiError) + } + } + end + + def update_operation do + %Operation{ + tags: ["Update status"], + summary: "Update status", + description: "Change the content of a status", + operationId: "StatusController.update", + security: [%{"oAuth" => ["write:statuses"]}], + parameters: [ + id_param() + ], + requestBody: request_body("Parameters", update_request(), required: true), + responses: %{ + 200 => status_response(), + 403 => Operation.response("Forbidden", "application/json", ApiError), + 404 => Operation.response("Not Found", "application/json", ApiError) + } + } + end + def array_of_statuses do %Schema{type: :array, items: Status, example: [Status.schema().example]} end @@ -537,6 +594,60 @@ defp create_request do } end + defp update_request do + %Schema{ + title: "StatusUpdateRequest", + type: :object, + properties: %{ + status: %Schema{ + type: :string, + nullable: true, + description: + "Text content of the status. If `media_ids` is provided, this becomes optional. Attaching a `poll` is optional while `status` is provided." + }, + media_ids: %Schema{ + nullable: true, + type: :array, + items: %Schema{type: :string}, + description: "Array of Attachment ids to be attached as media." + }, + poll: poll_params(), + sensitive: %Schema{ + allOf: [BooleanLike], + nullable: true, + description: "Mark status and attached media as sensitive?" + }, + spoiler_text: %Schema{ + type: :string, + nullable: true, + description: + "Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field." + }, + content_type: %Schema{ + type: :string, + nullable: true, + description: + "The MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint." + }, + to: %Schema{ + type: :array, + nullable: true, + items: %Schema{type: :string}, + description: + "A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for for post visibility are not affected by this and will still apply" + } + }, + example: %{ + "status" => "What time is it?", + "sensitive" => "false", + "poll" => %{ + "options" => ["Cofe", "Adventure"], + "expires_in" => 420 + } + } + } + end + def poll_params do %Schema{ nullable: true, @@ -579,6 +690,87 @@ defp status_response do Operation.response("Status", "application/json", Status) end + defp status_history_response do + Operation.response( + "Status History", + "application/json", + %Schema{ + title: "Status history", + description: "Response schema for history of a status", + type: :array, + items: %Schema{ + type: :object, + properties: %{ + account: %Schema{ + allOf: [Account], + description: "The account that authored this status" + }, + content: %Schema{ + type: :string, + format: :html, + description: "HTML-encoded status content" + }, + sensitive: %Schema{ + type: :boolean, + description: "Is this status marked as sensitive content?" + }, + spoiler_text: %Schema{ + type: :string, + description: + "Subject or summary line, below which status content is collapsed until expanded" + }, + created_at: %Schema{ + type: :string, + format: "date-time", + description: "The date when this status was created" + }, + media_attachments: %Schema{ + type: :array, + items: Attachment, + description: "Media that is attached to this status" + }, + emojis: %Schema{ + type: :array, + items: Emoji, + description: "Custom emoji to be used when rendering status content" + }, + poll: %Schema{ + allOf: [Poll], + nullable: true, + description: "The poll attached to the status" + } + } + } + } + ) + end + + defp status_source_response do + Operation.response( + "Status Source", + "application/json", + %Schema{ + type: :object, + properties: %{ + id: FlakeID, + text: %Schema{ + type: :string, + description: "Raw source of status content" + }, + spoiler_text: %Schema{ + type: :string, + description: + "Subject or summary line, below which status content is collapsed until expanded" + }, + content_type: %Schema{ + type: :string, + description: "The content type of the source" + } + } + } + ) + end + defp context do %Schema{ title: "StatusContext", diff --git a/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex b/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex index c59e3b12a..29df03e34 100644 --- a/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex +++ b/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex @@ -214,6 +214,146 @@ def captcha_operation do } end + def move_account_operation do + %Operation{ + tags: ["Account credentials"], + summary: "Move account", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.move_account", + requestBody: request_body("Parameters", move_account_request(), required: true), + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{status: %Schema{type: :string, example: "success"}} + }), + 400 => Operation.response("Error", "application/json", ApiError), + 403 => Operation.response("Error", "application/json", ApiError), + 404 => Operation.response("Error", "application/json", ApiError) + } + } + end + + defp move_account_request do + %Schema{ + title: "MoveAccountRequest", + description: "POST body for moving the account", + type: :object, + required: [:password, :target_account], + properties: %{ + password: %Schema{type: :string, description: "Current password"}, + target_account: %Schema{ + type: :string, + description: "The nickname of the target account to move to" + } + } + } + end + + def list_aliases_operation do + %Operation{ + tags: ["Account credentials"], + summary: "List account aliases", + security: [%{"oAuth" => ["read:accounts"]}], + operationId: "UtilController.list_aliases", + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{ + aliases: %Schema{ + type: :array, + items: %Schema{type: :string}, + example: ["foo@example.org"] + } + } + }), + 400 => Operation.response("Error", "application/json", ApiError), + 403 => Operation.response("Error", "application/json", ApiError) + } + } + end + + def add_alias_operation do + %Operation{ + tags: ["Account credentials"], + summary: "Add an alias to this account", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.add_alias", + requestBody: request_body("Parameters", add_alias_request(), required: true), + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{ + status: %Schema{ + type: :string, + example: "success" + } + } + }), + 400 => Operation.response("Error", "application/json", ApiError), + 403 => Operation.response("Error", "application/json", ApiError), + 404 => Operation.response("Error", "application/json", ApiError) + } + } + end + + defp add_alias_request do + %Schema{ + title: "AddAliasRequest", + description: "PUT body for adding aliases", + type: :object, + required: [:alias], + properties: %{ + alias: %Schema{ + type: :string, + description: "The nickname of the account to add to aliases" + } + } + } + end + + def delete_alias_operation do + %Operation{ + tags: ["Account credentials"], + summary: "Delete an alias from this account", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.delete_alias", + requestBody: request_body("Parameters", delete_alias_request(), required: true), + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{ + status: %Schema{ + type: :string, + example: "success" + } + } + }), + 400 => Operation.response("Error", "application/json", ApiError), + 403 => Operation.response("Error", "application/json", ApiError), + 404 => Operation.response("Error", "application/json", ApiError) + } + } + end + + defp delete_alias_request do + %Schema{ + title: "DeleteAliasRequest", + description: "PUT body for deleting aliases", + type: :object, + required: [:alias], + properties: %{ + alias: %Schema{ + type: :string, + description: "The nickname of the account to delete from aliases" + } + } + } + end + def healthcheck_operation do %Operation{ tags: ["Accounts"], @@ -265,6 +405,16 @@ defp remote_interaction_request do } end + def show_subscribe_form_operation do + %Operation{ + tags: ["Accounts"], + summary: "Show remote subscribe form", + operationId: "UtilController.show_subscribe_form", + parameters: [], + responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})} + } + end + defp delete_account_request do %Schema{ title: "AccountDeleteRequest", diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex index e8a529f2e..8aeb821a8 100644 --- a/lib/pleroma/web/api_spec/schemas/account.ex +++ b/lib/pleroma/web/api_spec/schemas/account.ex @@ -33,6 +33,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do header: %Schema{type: :string, format: :uri}, id: FlakeID, locked: %Schema{type: :boolean}, + mute_expires_at: %Schema{type: :string, format: "date-time", nullable: true}, note: %Schema{type: :string, format: :html}, statuses_count: %Schema{type: :integer}, url: %Schema{type: :string, format: :uri}, diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex index 6e6e30315..698f11794 100644 --- a/lib/pleroma/web/api_spec/schemas/status.ex +++ b/lib/pleroma/web/api_spec/schemas/status.ex @@ -73,6 +73,12 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do format: "date-time", description: "The date when this status was created" }, + edited_at: %Schema{ + type: :string, + format: "date-time", + nullable: true, + description: "The date when this status was last edited" + }, emojis: %Schema{ type: :array, items: Emoji, @@ -142,9 +148,15 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do description: "A map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`" }, + context: %Schema{ + type: :string, + description: "The thread identifier the status is associated with" + }, conversation_id: %Schema{ type: :integer, - description: "The ID of the AP context the status is associated with (if any)" + deprecated: true, + description: + "The ID of the AP context the status is associated with (if any); deprecated, please use `context` instead" }, direct_conversation_id: %Schema{ type: :integer, @@ -319,6 +331,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do "pinned" => false, "pleroma" => %{ "content" => %{"text/plain" => "foobar"}, + "context" => "http://localhost:4001/objects/8b4c0c80-6a37-4d2a-b1b9-05a19e3875aa", "conversation_id" => 345_972, "direct_conversation_id" => nil, "emoji_reactions" => [], diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex index 4ac5df63f..97f2aec3b 100644 --- a/lib/pleroma/web/common_api.ex +++ b/lib/pleroma/web/common_api.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.CommonAPI do alias Pleroma.Activity alias Pleroma.Conversation.Participation alias Pleroma.Formatter + alias Pleroma.ModerationLog alias Pleroma.Object alias Pleroma.ThreadMute alias Pleroma.User @@ -147,6 +148,21 @@ def delete(activity_id, user) do true <- User.privileged?(user, :messages_delete) || user.ap_id == object.data["actor"], {:ok, delete_data, _} <- Builder.delete(user, object.data["id"]), {:ok, delete, _} <- Pipeline.common_pipeline(delete_data, local: true) do + if User.superuser?(user) and user.ap_id != object.data["actor"] do + action = + if object.data["type"] == "ChatMessage" do + "chat_message_delete" + else + "status_delete" + end + + ModerationLog.insert_log(%{ + action: action, + actor: user, + subject_id: activity_id + }) + end + {:ok, delete} else {:find_activity, _} -> @@ -402,6 +418,41 @@ def post(user, %{status: _} = data) do end end + def update(user, orig_activity, changes) do + with orig_object <- Object.normalize(orig_activity), + {:ok, new_object} <- make_update_data(user, orig_object, changes), + {:ok, update_data, _} <- Builder.update(user, new_object), + {:ok, update, _} <- Pipeline.common_pipeline(update_data, local: true) do + {:ok, update} + else + _ -> {:error, nil} + end + end + + defp make_update_data(user, orig_object, changes) do + kept_params = %{ + visibility: Visibility.get_visibility(orig_object), + in_reply_to_id: + with replied_id when is_binary(replied_id) <- orig_object.data["inReplyTo"], + %Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(replied_id) do + activity_id + else + _ -> nil + end + } + + params = Map.merge(changes, kept_params) + + with {:ok, draft} <- ActivityDraft.create(user, params) do + change = + Object.Updater.make_update_object_data(orig_object.data, draft.object, Utils.make_date()) + + {:ok, change} + else + _ -> {:error, nil} + end + end + @spec pin(String.t(), User.t()) :: {:ok, Activity.t()} | {:error, term()} def pin(id, %User{} = user) do with %Activity{} = activity <- create_activity_by_id(id), diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex index 7c21c8c3a..9af635da8 100644 --- a/lib/pleroma/web/common_api/activity_draft.ex +++ b/lib/pleroma/web/common_api/activity_draft.ex @@ -224,7 +224,10 @@ defp object(draft) do object = note_data |> Map.put("emoji", emoji) - |> Map.put("source", draft.status) + |> Map.put("source", %{ + "content" => draft.status, + "mediaType" => Utils.get_content_type(draft.params[:content_type]) + }) |> Map.put("generator", draft.params[:generator]) %__MODULE__{draft | object: object} diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index ce850b038..ff0814329 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -37,7 +37,7 @@ def attachments_from_ids_no_descs([]), do: [] def attachments_from_ids_no_descs(ids) do Enum.map(ids, fn media_id -> - case Repo.get(Object, media_id) do + case get_attachment(media_id) do %Object{data: data} -> data _ -> nil end @@ -51,13 +51,17 @@ def attachments_from_ids_descs(ids, descs_str) do {_, descs} = Jason.decode(descs_str) Enum.map(ids, fn media_id -> - with %Object{data: data} <- Repo.get(Object, media_id) do + with %Object{data: data} <- get_attachment(media_id) do Map.put(data, "name", descs[media_id]) end end) |> Enum.reject(&is_nil/1) end + defp get_attachment(media_id) do + Repo.get(Object, media_id) + end + @spec get_to_and_cc(ActivityDraft.t()) :: {list(String.t()), list(String.t())} def get_to_and_cc(%{in_reply_to_conversation: %Participation{} = participation}) do @@ -219,7 +223,7 @@ def make_content_html(%ActivityDraft{} = draft) do |> maybe_add_attachments(draft.attachments, attachment_links) end - defp get_content_type(content_type) do + def get_content_type(content_type) do if Enum.member?(Config.get([:instance, :allowed_post_formats]), content_type) do content_type else @@ -449,35 +453,6 @@ def get_report_statuses(%User{ap_id: actor}, %{status_ids: status_ids}) def get_report_statuses(_, _), do: {:ok, nil} - # DEPRECATED mostly, context objects are now created at insertion time. - def context_to_conversation_id(context) do - with %Object{id: id} <- Object.get_cached_by_ap_id(context) do - id - else - _e -> - changeset = Object.context_mapping(context) - - case Repo.insert(changeset) do - {:ok, %{id: id}} -> - id - - # This should be solved by an upsert, but it seems ecto - # has problems accessing the constraint inside the jsonb. - {:error, _} -> - Object.get_cached_by_ap_id(context).id - end - end - end - - def conversation_id_to_context(id) do - with %Object{data: %{"id" => context}} <- Repo.get(Object, id) do - context - else - _e -> - {:error, dgettext("errors", "No such conversation")} - end - end - def validate_character_limit("" = _full_payload, [] = _attachments) do {:error, dgettext("errors", "Cannot post an empty status without attachments")} end diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex index e7feefc07..318b6cb11 100644 --- a/lib/pleroma/web/federator.ex +++ b/lib/pleroma/web/federator.ex @@ -47,10 +47,15 @@ def publish(%{id: "pleroma:fakeid"} = activity) do end @impl true - def publish(activity) do - PublisherWorker.enqueue("publish", %{"activity_id" => activity.id}) + def publish(%Pleroma.Activity{data: %{"type" => type}} = activity) do + PublisherWorker.enqueue("publish", %{"activity_id" => activity.id}, + priority: publish_priority(type) + ) end + defp publish_priority("Delete"), do: 3 + defp publish_priority(_), do: 0 + # Job Worker Callbacks @spec perform(atom(), module(), any()) :: {:ok, any()} | {:error, any()} @@ -61,10 +66,8 @@ def perform(:publish_one, module, params) do def perform(:publish, activity) do Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end) - with %User{} = actor <- User.get_cached_by_ap_id(activity.data["actor"]), - {:ok, actor} <- User.ensure_keys_present(actor) do - Publisher.publish(actor, activity) - end + %User{} = actor = User.get_cached_by_ap_id(activity.data["actor"]) + Publisher.publish(actor, activity) end def perform(:incoming_ap_doc, params) do diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 50c12a1b1..ea6e593d9 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -76,16 +76,18 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do plug( OAuthScopesPlug, - %{scopes: ["follow", "write:follows"]} when action in [:follow_by_uri, :follow, :unfollow] + %{scopes: ["follow", "write:follows"]} + when action in [:follow_by_uri, :follow, :unfollow, :remove_from_followers] ) plug(OAuthScopesPlug, %{scopes: ["follow", "read:mutes"]} when action == :mutes) plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action in [:mute, :unmute]) - @relationship_actions [:follow, :unfollow] + @relationship_actions [:follow, :unfollow, :remove_from_followers] @needs_account ~W( - followers following lists follow unfollow mute unmute block unblock note endorse unendorse + followers following lists follow unfollow mute unmute block unblock + note endorse unendorse remove_from_followers )a plug( @@ -252,7 +254,17 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p with_pleroma_settings: true ) else - _e -> render_error(conn, :forbidden, "Invalid request") + {:error, %Ecto.Changeset{errors: [avatar: {"file is too large", _}]}} -> + render_error(conn, :request_entity_too_large, "File is too large") + + {:error, %Ecto.Changeset{errors: [banner: {"file is too large", _}]}} -> + render_error(conn, :request_entity_too_large, "File is too large") + + {:error, %Ecto.Changeset{errors: [background: {"file is too large", _}]}} -> + render_error(conn, :request_entity_too_large, "File is too large") + + _e -> + render_error(conn, :forbidden, "Invalid request") end end @@ -411,6 +423,10 @@ def unfollow(%{assigns: %{user: follower, account: followed}} = conn, _params) d @doc "POST /api/v1/accounts/:id/mute" def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do + params = + params + |> Map.put_new(:duration, Map.get(params, :expires_in, 0)) + with {:ok, _user_relationships} <- User.mute(muter, muted, params) do render(conn, "relationship.json", user: muter, target: muted) else @@ -473,6 +489,20 @@ def unendorse(%{assigns: %{user: endorser, account: endorsed}} = conn, _params) end end + @doc "POST /api/v1/accounts/:id/remove_from_followers" + def remove_from_followers(%{assigns: %{user: %{id: id}, account: %{id: id}}}, _params) do + {:error, "Can not unfollow yourself"} + end + + def remove_from_followers(%{assigns: %{user: followed, account: follower}} = conn, _params) do + with {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do + render(conn, "relationship.json", user: followed, target: follower) + else + nil -> + render_error(conn, :not_found, "Record not found") + end + end + @doc "POST /api/v1/follows" def follow_by_uri(%{body_params: %{uri: uri}} = conn, _) do case User.get_cached_by_nickname(uri) do @@ -491,7 +521,7 @@ def mutes(%{assigns: %{user: user}} = conn, params) do users = user |> User.muted_users_relation(_restrict_deactivated = true) - |> Pleroma.Pagination.fetch_paginated(Map.put(params, :skip_order, true)) + |> Pleroma.Pagination.fetch_paginated(params) conn |> add_link_headers(users) @@ -499,7 +529,8 @@ def mutes(%{assigns: %{user: user}} = conn, params) do users: users, for: user, as: :user, - embed_relationships: embed_relationships?(params) + embed_relationships: embed_relationships?(params), + mutes: true ) end @@ -508,7 +539,7 @@ def blocks(%{assigns: %{user: user}} = conn, params) do users = user |> User.blocked_users_relation(_restrict_deactivated = true) - |> Pleroma.Pagination.fetch_paginated(Map.put(params, :skip_order, true)) + |> Pleroma.Pagination.fetch_paginated(params) conn |> add_link_headers(users) diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex index 932bc6423..a490e8319 100644 --- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex @@ -51,11 +51,12 @@ def index(conn, %{account_id: account_id} = params) do move pleroma:emoji_reaction poll + update } def index(%{assigns: %{user: user}} = conn, params) do params = Map.new(params, fn {k, v} -> {to_string(k), v} end) - |> Map.put_new("include_types", @default_notification_types) + |> Map.put_new("types", Map.get(params, :include_types, @default_notification_types)) notifications = MastodonAPI.get_notifications(user, params) diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 42a95bdc5..e594ea491 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -38,7 +38,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do :index, :show, :card, - :context + :context, + :show_history, + :show_source ] ) @@ -49,7 +51,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do :create, :delete, :reblog, - :unreblog + :unreblog, + :update ] ) @@ -191,6 +194,59 @@ def create(%{assigns: %{user: _user}, body_params: %{media_ids: _} = params} = c create(%Plug.Conn{conn | body_params: params}, %{}) end + @doc "GET /api/v1/statuses/:id/history" + def show_history(%{assigns: assigns} = conn, %{id: id} = params) do + with user = assigns[:user], + %Activity{} = activity <- Activity.get_by_id_with_object(id), + true <- Visibility.visible_for_user?(activity, user) do + try_render(conn, "history.json", + activity: activity, + for: user, + with_direct_conversation_id: true, + with_muted: Map.get(params, :with_muted, false) + ) + else + _ -> {:error, :not_found} + end + end + + @doc "GET /api/v1/statuses/:id/source" + def show_source(%{assigns: assigns} = conn, %{id: id} = _params) do + with user = assigns[:user], + %Activity{} = activity <- Activity.get_by_id_with_object(id), + true <- Visibility.visible_for_user?(activity, user) do + try_render(conn, "source.json", + activity: activity, + for: user + ) + else + _ -> {:error, :not_found} + end + end + + @doc "PUT /api/v1/statuses/:id" + def update(%{assigns: %{user: user}, body_params: body_params} = conn, %{id: id} = params) do + with {_, %Activity{}} = {_, activity} <- {:activity, Activity.get_by_id_with_object(id)}, + {_, true} <- {:visible, Visibility.visible_for_user?(activity, user)}, + {_, true} <- {:is_create, activity.data["type"] == "Create"}, + actor <- Activity.user_actor(activity), + {_, true} <- {:own_status, actor.id == user.id}, + changes <- body_params |> put_application(conn), + {_, {:ok, _update_activity}} <- {:pipeline, CommonAPI.update(user, activity, changes)}, + {_, %Activity{}} = {_, activity} <- {:refetched, Activity.get_by_id_with_object(id)} do + try_render(conn, "show.json", + activity: activity, + for: user, + with_direct_conversation_id: true, + with_muted: Map.get(params, :with_muted, false) + ) + else + {:own_status, _} -> {:error, :forbidden} + {:pipeline, _} -> {:error, :internal_server_error} + _ -> {:error, :not_found} + end + end + @doc "GET /api/v1/statuses/:id" def show(%{assigns: %{user: user}} = conn, %{id: id} = params) do with %Activity{} = activity <- Activity.get_by_id_with_object(id), diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex index ba7239476..293c61b41 100644 --- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex @@ -112,6 +112,8 @@ def public(%{assigns: %{user: user}} = conn, params) do |> Map.put(:muting_user, user) |> Map.put(:reply_filtering_user, user) |> Map.put(:instance, params[:instance]) + # Restricts unfederated content to authenticated users + |> Map.put(:includes_local_public, not is_nil(user)) |> ActivityPub.fetch_public_activities() conn diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex index 932e5d4eb..c51230b92 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex @@ -77,7 +77,7 @@ def get_notifications(user, params \\ %{}) do user |> Notification.for_user_query(options) - |> restrict(:include_types, options) + |> restrict(:types, options) |> restrict(:exclude_types, options) |> restrict(:account_ap_id, options) |> Pagination.fetch_paginated(params) @@ -92,7 +92,7 @@ def get_scheduled_activities(user, params \\ %{}) do defp cast_params(params) do param_types = %{ exclude_types: {:array, :string}, - include_types: {:array, :string}, + types: {:array, :string}, exclude_visibilities: {:array, :string}, reblogs: :boolean, with_muted: :boolean, @@ -104,7 +104,7 @@ defp cast_params(params) do changeset.changes end - defp restrict(query, :include_types, %{include_types: mastodon_types = [_ | _]}) do + defp restrict(query, :types, %{types: mastodon_types = [_ | _]}) do where(query, [n], n.type in ^mastodon_types) end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 34b34dc19..cc3e3582f 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -311,6 +311,7 @@ defp do_render("show.json", %{user: user} = opts) do |> maybe_put_unread_conversation_count(user, opts[:for]) |> maybe_put_unread_notification_count(user, opts[:for]) |> maybe_put_email_address(user, opts[:for]) + |> maybe_put_mute_expires_at(user, opts[:for], opts) |> maybe_show_birthday(user, opts[:for]) end @@ -437,6 +438,16 @@ defp maybe_put_email_address(data, %User{id: user_id}, %User{id: user_id} = user defp maybe_put_email_address(data, _, _), do: data + defp maybe_put_mute_expires_at(data, %User{} = user, target, %{mutes: true}) do + Map.put( + data, + :mute_expires_at, + UserRelationship.get_mute_expire_date(target, user) + ) + end + + defp maybe_put_mute_expires_at(data, _, _, _), do: data + defp maybe_show_birthday(data, %User{id: user_id} = user, %User{id: user_id}) do data |> Kernel.put_in([:pleroma, :birthday], user.birthday) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index fa2dd4731..917725839 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -68,6 +68,7 @@ def features do "shareable_emoji_packs", "multifetch", "pleroma:api/v1/notifications:include_types_filter", + "editing", if Config.get([:activitypub, :blockers_visible]) do "blockers_visible" end, @@ -97,7 +98,8 @@ def features do end, if Config.get([:instance, :profile_directory]) do "profile_directory" - end + end, + "pleroma:get:main/ostatus" ] |> Enum.filter(& &1) end diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex index 0dc7f3beb..b5b5b2376 100644 --- a/lib/pleroma/web/mastodon_api/views/notification_view.ex +++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex @@ -19,7 +19,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView - @parent_types ~w{Like Announce EmojiReact} + defp object_id_for(%{data: %{"object" => %{"id" => id}}}) when is_binary(id), do: id + + defp object_id_for(%{data: %{"object" => id}}) when is_binary(id), do: id + + @parent_types ~w{Like Announce EmojiReact Update} def render("index.json", %{notifications: notifications, for: reading_user} = opts) do activities = Enum.map(notifications, & &1.activity) @@ -30,7 +34,7 @@ def render("index.json", %{notifications: notifications, for: reading_user} = op %{data: %{"type" => type}} -> type in @parent_types end) - |> Enum.map(& &1.data["object"]) + |> Enum.map(&object_id_for/1) |> Activity.create_by_object_ap_id() |> Activity.with_preloaded_object(:left) |> Pleroma.Repo.all() @@ -78,9 +82,9 @@ def render( parent_activity_fn = fn -> if opts[:parent_activities] do - Activity.Queries.find_by_object_ap_id(opts[:parent_activities], activity.data["object"]) + Activity.Queries.find_by_object_ap_id(opts[:parent_activities], object_id_for(activity)) else - Activity.get_create_by_object_ap_id(activity.data["object"]) + Activity.get_create_by_object_ap_id(object_id_for(activity)) end end @@ -109,6 +113,9 @@ def render( "reblog" -> put_status(response, parent_activity_fn.(), reading_user, status_render_opts) + "update" -> + put_status(response, parent_activity_fn.(), reading_user, status_render_opts) + "move" -> put_target(response, activity, reading_user, %{}) diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 1ebfd6740..0a8c98b44 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -57,11 +57,19 @@ defp get_replied_to_activities(activities) do end) end - defp get_context_id(%{data: %{"context_id" => context_id}}) when not is_nil(context_id), - do: context_id + # DEPRECATED This field seems to be a left-over from the StatusNet era. + # If your application uses `pleroma.conversation_id`: this field is deprecated. + # It is currently stubbed instead by doing a CRC32 of the context, and + # clearing the MSB to avoid overflow exceptions with signed integers on the + # different clients using this field (Java/Kotlin code, mostly; see Husky.) + # This should be removed in a future version of Pleroma. Pleroma-FE currently + # depends on this field, as well. + defp get_context_id(%{data: %{"context" => context}}) when is_binary(context) do + import Bitwise - defp get_context_id(%{data: %{"context" => context}}) when is_binary(context), - do: Utils.context_to_conversation_id(context) + :erlang.crc32(context) + |> band(bnot(0x8000_0000)) + end defp get_context_id(_), do: nil @@ -258,10 +266,30 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} created_at = Utils.to_masto_date(object.data["published"]) + edited_at = + with %{"updated" => updated} <- object.data, + date <- Utils.to_masto_date(updated), + true <- date != "" do + date + else + _ -> + nil + end + reply_to = get_reply_to(activity, opts) reply_to_user = reply_to && CommonAPI.get_user(reply_to.data["actor"]) + history_len = + 1 + + (Object.Updater.history_for(object.data) + |> Map.get("orderedItems") + |> length()) + + # See render("history.json", ...) for more details + # Here the implicit index of the current content is 0 + chrono_order = history_len - 1 + content = object |> render_content() @@ -271,14 +299,14 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} |> Activity.HTML.get_cached_scrubbed_html_for_activity( User.html_filter_policy(opts[:for]), activity, - "mastoapi:content" + "mastoapi:content:#{chrono_order}" ) content_plaintext = content |> Activity.HTML.get_cached_stripped_html_for_activity( activity, - "mastoapi:content" + "mastoapi:content:#{chrono_order}" ) summary = object.data["summary"] || "" @@ -344,8 +372,9 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} reblog: nil, card: card, content: content_html, - text: opts[:with_source] && object.data["source"], + text: opts[:with_source] && get_source_text(object.data["source"]), created_at: created_at, + edited_at: edited_at, reblogs_count: announcement_count, replies_count: object.data["repliesCount"] || 0, favourites_count: like_count, @@ -367,6 +396,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} pleroma: %{ local: activity.local, conversation_id: get_context_id(activity), + context: object.data["context"], in_reply_to_account_acct: reply_to_user && reply_to_user.nickname, content: %{"text/plain" => content_plaintext}, spoiler_text: %{"text/plain" => summary}, @@ -384,6 +414,100 @@ def render("show.json", _) do nil end + def render("history.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do + object = Object.normalize(activity, fetch: false) + + hashtags = Object.hashtags(object) + + user = CommonAPI.get_user(activity.data["actor"]) + + past_history = + Object.Updater.history_for(object.data) + |> Map.get("orderedItems") + |> Enum.map(&Map.put(&1, "id", object.data["id"])) + |> Enum.map(&%Object{data: &1, id: object.id}) + + history = + [object | past_history] + # Mastodon expects the original to be at the first + |> Enum.reverse() + |> Enum.with_index() + |> Enum.map(fn {object, chrono_order} -> + %{ + # The history is prepended every time there is a new edit. + # In chrono_order, the oldest item is always at 0, and so on. + # The chrono_order is an invariant kept between edits. + chrono_order: chrono_order, + object: object + } + end) + + individual_opts = + opts + |> Map.put(:as, :item) + |> Map.put(:user, user) + |> Map.put(:hashtags, hashtags) + + render_many(history, StatusView, "history_item.json", individual_opts) + end + + def render( + "history_item.json", + %{ + activity: activity, + user: user, + item: %{object: object, chrono_order: chrono_order}, + hashtags: hashtags + } = opts + ) do + sensitive = object.data["sensitive"] || Enum.member?(hashtags, "nsfw") + + attachment_data = object.data["attachment"] || [] + attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment) + + created_at = Utils.to_masto_date(object.data["updated"] || object.data["published"]) + + content = + object + |> render_content() + + content_html = + content + |> Activity.HTML.get_cached_scrubbed_html_for_activity( + User.html_filter_policy(opts[:for]), + activity, + "mastoapi:content:#{chrono_order}" + ) + + summary = object.data["summary"] || "" + + %{ + account: + AccountView.render("show.json", %{ + user: user, + for: opts[:for] + }), + content: content_html, + sensitive: sensitive, + spoiler_text: summary, + created_at: created_at, + media_attachments: attachments, + emojis: build_emojis(object.data["emoji"]), + poll: render(PollView, "show.json", object: object, for: opts[:for]) + } + end + + def render("source.json", %{activity: %{data: %{"object" => _object}} = activity} = _opts) do + object = Object.normalize(activity, fetch: false) + + %{ + id: activity.id, + text: get_source_text(Map.get(object.data, "source", "")), + spoiler_text: Map.get(object.data, "summary", ""), + content_type: get_source_content_type(object.data["source"]) + } + end + def render("card.json", %{rich_media: rich_media, page_url: page_url}) do page_url_data = URI.parse(page_url) @@ -436,10 +560,19 @@ def render("attachment.json", %{attachment: attachment}) do true -> "unknown" end - <> = :crypto.hash(:md5, href) + attachment_id = + with {_, ap_id} when is_binary(ap_id) <- {:ap_id, attachment["id"]}, + {_, %Object{data: _object_data, id: object_id}} <- + {:object, Object.get_by_ap_id(ap_id)} do + to_string(object_id) + else + _ -> + <> = :crypto.hash(:md5, href) + to_string(attachment["id"] || hash_id) + end %{ - id: to_string(attachment["id"] || hash_id), + id: attachment_id, url: href, remote_url: href, preview_url: href_preview, @@ -601,4 +734,24 @@ defp build_image_url(%URI{} = image_url_data, %URI{} = page_url_data) do end defp build_image_url(_, _), do: nil + + defp get_source_text(%{"content" => content} = _source) do + content + end + + defp get_source_text(source) when is_binary(source) do + source + end + + defp get_source_text(_) do + "" + end + + defp get_source_content_type(%{"mediaType" => type} = _source) do + type + end + + defp get_source_content_type(_source) do + Utils.get_content_type(nil) + end end diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index e62b8a135..88444106d 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -32,7 +32,8 @@ def init(%{qs: qs} = req, state) do req end - {:cowboy_websocket, req, %{user: user, topic: topic, count: 0, timer: nil}, + {:cowboy_websocket, req, + %{user: user, topic: topic, oauth_token: oauth_token, count: 0, timer: nil}, %{idle_timeout: @timeout}} else {:error, :bad_topic} -> @@ -52,7 +53,7 @@ def websocket_init(state) do "#{__MODULE__} accepted websocket connection for user #{(state.user || %{id: "anonymous"}).id}, topic #{state.topic}" ) - Streamer.add_socket(state.topic, state.user) + Streamer.add_socket(state.topic, state.oauth_token) {:ok, %{state | timer: timer()}} end @@ -98,6 +99,10 @@ def websocket_info(:tick, state) do {:reply, :ping, %{state | timer: nil, count: 0}, :hibernate} end + def websocket_info(:close, state) do + {:stop, state} + end + # State can be `[]` only in case we terminate before switching to websocket, # we already log errors for these cases in `init/1`, so just do nothing here def terminate(_reason, _req, []), do: :ok diff --git a/lib/pleroma/web/media_proxy/media_proxy_controller.ex b/lib/pleroma/web/media_proxy/media_proxy_controller.ex index 3d6716d43..d2ad62c13 100644 --- a/lib/pleroma/web/media_proxy/media_proxy_controller.ex +++ b/lib/pleroma/web/media_proxy/media_proxy_controller.ex @@ -54,7 +54,7 @@ defp handle_preview(conn, url) do media_proxy_url = MediaProxy.url(url) with {:ok, %{status: status} = head_response} when status in 200..299 <- - Pleroma.HTTP.request("head", media_proxy_url, [], [], pool: :media) do + Pleroma.HTTP.request("HEAD", media_proxy_url, [], [], pool: :media) do content_type = Tesla.get_header(head_response, "content-type") content_length = Tesla.get_header(head_response, "content-length") content_length = content_length && String.to_integer(content_length) diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex index 8052eaa44..15414a988 100644 --- a/lib/pleroma/web/metadata/utils.ex +++ b/lib/pleroma/web/metadata/utils.ex @@ -8,8 +8,8 @@ defmodule Pleroma.Web.Metadata.Utils do alias Pleroma.Formatter alias Pleroma.HTML - def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do - content + defp scrub_html_and_truncate_object_field(field, object) do + field # html content comes from DB already encoded, decode first and scrub after |> HtmlEntities.decode() |> String.replace(~r//, " ") @@ -19,6 +19,17 @@ def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do |> Formatter.truncate() end + def scrub_html_and_truncate(%{data: %{"summary" => summary}} = object) + when is_binary(summary) and summary != "" do + summary + |> scrub_html_and_truncate_object_field(object) + end + + def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do + content + |> scrub_html_and_truncate_object_field(object) + end + def scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do content |> scrub_html diff --git a/lib/pleroma/web/o_auth/token/strategy/revoke.ex b/lib/pleroma/web/o_auth/token/strategy/revoke.ex index 752efca89..3b265b339 100644 --- a/lib/pleroma/web/o_auth/token/strategy/revoke.ex +++ b/lib/pleroma/web/o_auth/token/strategy/revoke.ex @@ -21,6 +21,18 @@ def revoke(%App{} = app, %{"token" => token} = _attrs) do @doc "Revokes access token" @spec revoke(Token.t()) :: {:ok, Token.t()} | {:error, Ecto.Changeset.t()} def revoke(%Token{} = token) do - Repo.delete(token) + with {:ok, token} <- Repo.delete(token) do + Task.Supervisor.start_child( + Pleroma.TaskSupervisor, + Pleroma.Web.Streamer, + :close_streams_by_oauth_token, + [token], + restart: :transient + ) + + {:ok, token} + else + result -> result + end end end diff --git a/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex b/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex index 1a0548295..b9daed22b 100644 --- a/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex @@ -9,7 +9,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupController do alias Pleroma.Web.Plugs.OAuthScopesPlug action_fallback(Pleroma.Web.MastodonAPI.FallbackController) - plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action in [:index, :create]) + plug(OAuthScopesPlug, %{scopes: ["read:backups"]} when action in [:index, :create]) plug(Pleroma.Web.ApiSpec.CastAndValidate) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaBackupOperation diff --git a/lib/pleroma/web/pleroma_api/controllers/settings_controller.ex b/lib/pleroma/web/pleroma_api/controllers/settings_controller.ex new file mode 100644 index 000000000..1136575b6 --- /dev/null +++ b/lib/pleroma/web/pleroma_api/controllers/settings_controller.ex @@ -0,0 +1,79 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.SettingsController do + use Pleroma.Web, :controller + + alias Pleroma.Web.Plugs.OAuthScopesPlug + + plug(Pleroma.Web.ApiSpec.CastAndValidate) + + plug( + OAuthScopesPlug, + %{scopes: ["write:accounts"]} when action in [:update] + ) + + plug( + OAuthScopesPlug, + %{scopes: ["read:accounts"]} when action in [:show] + ) + + defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaSettingsOperation + + @doc "GET /api/v1/pleroma/settings/:app" + def show(%{assigns: %{user: user}} = conn, %{app: app} = _params) do + conn + |> json(get_settings(user, app)) + end + + @doc "PATCH /api/v1/pleroma/settings/:app" + def update(%{assigns: %{user: user}, body_params: body_params} = conn, %{app: app} = _params) do + settings = + get_settings(user, app) + |> merge_recursively(body_params) + + with changeset <- + Pleroma.User.update_changeset( + user, + %{pleroma_settings_store: %{app => settings}} + ), + {:ok, _} <- Pleroma.Repo.update(changeset) do + conn + |> json(settings) + end + end + + defp merge_recursively(old, %{} = new) do + old = ensure_object(old) + + Enum.reduce( + new, + old, + fn + {k, nil}, acc -> + Map.drop(acc, [k]) + + {k, %{} = new_child}, acc -> + Map.put(acc, k, merge_recursively(acc[k], new_child)) + + {k, v}, acc -> + Map.put(acc, k, v) + end + ) + end + + defp get_settings(user, app) do + user.pleroma_settings_store + |> Map.get(app, %{}) + |> ensure_object() + end + + defp ensure_object(%{} = object) do + object + end + + defp ensure_object(_) do + %{} + end +end diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex index b89948cec..34895c8d5 100644 --- a/lib/pleroma/web/plugs/http_security_plug.ex +++ b/lib/pleroma/web/plugs/http_security_plug.ex @@ -68,7 +68,7 @@ def headers do ] } - [{"reply-to", Jason.encode!(report_group)} | headers] + [{"report-to", Jason.encode!(report_group)} | headers] else headers end @@ -117,7 +117,7 @@ defp csp_string do if Config.get(:env) == :dev do "script-src 'self' 'unsafe-eval'" else - "script-src 'self'" + "script-src 'self' 'wasm-unsafe-eval'" end report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"] diff --git a/lib/pleroma/web/plugs/http_signature_plug.ex b/lib/pleroma/web/plugs/http_signature_plug.ex index d023754a6..4bf325218 100644 --- a/lib/pleroma/web/plugs/http_signature_plug.ex +++ b/lib/pleroma/web/plugs/http_signature_plug.ex @@ -25,21 +25,58 @@ def call(conn, _opts) do end end + defp validate_signature(conn, request_target) do + # Newer drafts for HTTP signatures now use @request-target instead of the + # old (request-target). We'll now support both for incoming signatures. + conn = + conn + |> put_req_header("(request-target)", request_target) + |> put_req_header("@request-target", request_target) + + HTTPSignatures.validate_conn(conn) + end + + defp validate_signature(conn) do + # This (request-target) is non-standard, but many implementations do it + # this way due to a misinterpretation of + # https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-06 + # "path" was interpreted as not having the query, though later examples + # show that it must be the absolute path + query. This behavior is kept to + # make sure most software (Pleroma itself, Mastodon, and probably others) + # do not break. + request_target = String.downcase("#{conn.method}") <> " #{conn.request_path}" + + # This is the proper way to build the @request-target, as expected by + # many HTTP signature libraries, clarified in the following draft: + # https://www.ietf.org/archive/id/draft-ietf-httpbis-message-signatures-11.html#section-2.2.6 + # It is the same as before, but containing the query part as well. + proper_target = request_target <> "?#{conn.query_string}" + + cond do + # Normal, non-standard behavior but expected by Pleroma and more. + validate_signature(conn, request_target) -> + true + + # Has query string and the previous one failed: let's try the standard. + conn.query_string != "" -> + validate_signature(conn, proper_target) + + # If there's no query string and signature fails, it's rotten. + true -> + false + end + end + defp maybe_assign_valid_signature(conn) do if has_signature_header?(conn) do - # set (request-target) header to the appropriate value - # we also replace the digest header with the one we computed - request_target = String.downcase("#{conn.method}") <> " #{conn.request_path}" - + # we replace the digest header with the one we computed in DigestPlug conn = - conn - |> put_req_header("(request-target)", request_target) - |> case do + case conn do %{assigns: %{digest: digest}} = conn -> put_req_header(conn, "digest", digest) conn -> conn end - assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn)) + assign(conn, :valid_signature, validate_signature(conn)) else Logger.debug("No signature header!") conn diff --git a/lib/pleroma/web/plugs/o_auth_plug.ex b/lib/pleroma/web/plugs/o_auth_plug.ex index 0f74d626b..ba04ddb72 100644 --- a/lib/pleroma/web/plugs/o_auth_plug.ex +++ b/lib/pleroma/web/plugs/o_auth_plug.ex @@ -47,15 +47,17 @@ def call(conn, _) do # @spec fetch_user_and_token(String.t()) :: {:ok, User.t(), Token.t()} | nil defp fetch_user_and_token(token) do - query = + token_query = from(t in Token, - where: t.token == ^token, - join: user in assoc(t, :user), - preload: [user: user] + where: t.token == ^token ) - with %Token{user: user} = token_record <- Repo.one(query) do + with %Token{user_id: user_id} = token_record <- Repo.one(token_query), + false <- is_nil(user_id), + %User{} = user <- User.get_cached_by_id(user_id) do {:ok, user, token_record} + else + _ -> nil end end diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index daf3eeb9e..3c5f00764 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -16,7 +16,7 @@ defmodule Pleroma.Web.Push.Impl do require Logger import Ecto.Query - @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact"] + @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact", "Update"] @doc "Performs sending notifications for user subscriptions" @spec perform(Notification.t()) :: list(any) | :error | {:error, :unknown_type} @@ -174,6 +174,15 @@ def format_body( end end + def format_body( + %{activity: %{data: %{"type" => "Update"}}}, + actor, + _object, + _mastodon_type + ) do + "@#{actor.nickname} edited a status" + end + def format_title(activity, mastodon_type \\ nil) def format_title(%{activity: %{data: %{"directMessage" => true}}}, _mastodon_type) do @@ -187,6 +196,7 @@ def format_title(%{type: type}, mastodon_type) do "follow_request" -> "New Follow Request" "reblog" -> "New Repeat" "favourite" -> "New Favorite" + "update" -> "New Update" "pleroma:chat_mention" -> "New Chat Message" "pleroma:emoji_reaction" -> "New Reaction" type -> "New #{String.capitalize(type || "event")}" diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index a50232422..ba1d64ab2 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -462,6 +462,7 @@ defmodule Pleroma.Web.Router do pipe_through(:pleroma_html) post("/main/ostatus", UtilController, :remote_subscribe) + get("/main/ostatus", UtilController, :show_subscribe_form) get("/ostatus_subscribe", RemoteFollowController, :follow) post("/ostatus_subscribe", RemoteFollowController, :do_follow) end @@ -474,6 +475,11 @@ defmodule Pleroma.Web.Router do post("/delete_account", UtilController, :delete_account) put("/notification_settings", UtilController, :update_notificaton_settings) post("/disable_account", UtilController, :disable_account) + post("/move_account", UtilController, :move_account) + + put("/aliases", UtilController, :add_alias) + get("/aliases", UtilController, :list_aliases) + delete("/aliases", UtilController, :delete_alias) end scope "/api/pleroma", Pleroma.Web.PleromaAPI do @@ -583,6 +589,13 @@ defmodule Pleroma.Web.Router do get("/birthdays", AccountController, :birthdays) end + scope [] do + pipe_through(:authenticated_api) + + get("/settings/:app", SettingsController, :show) + patch("/settings/:app", SettingsController, :update) + end + post("/accounts/confirmation_resend", AccountController, :confirmation_resend) end @@ -622,6 +635,7 @@ defmodule Pleroma.Web.Router do post("/accounts/:id/note", AccountController, :note) post("/accounts/:id/pin", AccountController, :endorse) post("/accounts/:id/unpin", AccountController, :unendorse) + post("/accounts/:id/remove_from_followers", AccountController, :remove_from_followers) get("/conversations", ConversationController, :index) post("/conversations/:id/read", ConversationController, :mark_as_read) @@ -683,6 +697,7 @@ defmodule Pleroma.Web.Router do get("/bookmarks", StatusController, :bookmarks) post("/statuses", StatusController, :create) + put("/statuses/:id", StatusController, :update) delete("/statuses/:id", StatusController, :delete) post("/statuses/:id/reblog", StatusController, :reblog) post("/statuses/:id/unreblog", StatusController, :unreblog) @@ -742,6 +757,8 @@ defmodule Pleroma.Web.Router do get("/statuses/:id/card", StatusController, :card) get("/statuses/:id/favourited_by", StatusController, :favourited_by) get("/statuses/:id/reblogged_by", StatusController, :reblogged_by) + get("/statuses/:id/history", StatusController, :show_history) + get("/statuses/:id/source", StatusController, :show_source) get("/custom_emojis", CustomEmojiController, :index) @@ -803,11 +820,6 @@ defmodule Pleroma.Web.Router do get("/activities/:uuid", OStatus.OStatusController, :activity) get("/notice/:id", OStatus.OStatusController, :notice) - # Notice compatibility routes for other frontends - get("/@:nickname/:id", OStatus.OStatusController, :notice) - get("/@:nickname/posts/:id", OStatus.OStatusController, :notice) - get("/:nickname/status/:id", OStatus.OStatusController, :notice) - # Mastodon compatibility routes get("/users/:nickname/statuses/:id", OStatus.OStatusController, :object) get("/users/:nickname/statuses/:id/activity", OStatus.OStatusController, :activity) diff --git a/lib/pleroma/web/static_fe/static_fe_controller.ex b/lib/pleroma/web/static_fe/static_fe_controller.ex index b20a3689c..97c41c6f9 100644 --- a/lib/pleroma/web/static_fe/static_fe_controller.ex +++ b/lib/pleroma/web/static_fe/static_fe_controller.ex @@ -167,15 +167,6 @@ defp represent(%Activity{object: %Object{data: data}} = activity, selected) do defp assign_id(%{path_info: ["notice", notice_id]} = conn, _opts), do: assign(conn, :notice_id, notice_id) - defp assign_id(%{path_info: ["@" <> _nickname, notice_id]} = conn, _opts), - do: assign(conn, :notice_id, notice_id) - - defp assign_id(%{path_info: ["@" <> _nickname, "posts", notice_id]} = conn, _opts), - do: assign(conn, :notice_id, notice_id) - - defp assign_id(%{path_info: [_nickname, "status", notice_id]} = conn, _opts), - do: assign(conn, :notice_id, notice_id) - defp assign_id(%{path_info: ["users", user_id]} = conn, _opts), do: assign(conn, :username_or_id, user_id) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index ff7f62a1e..3c0da5c27 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -37,7 +37,7 @@ def registry, do: @registry {:ok, topic :: String.t()} | {:error, :bad_topic} | {:error, :unauthorized} def get_topic_and_add_socket(stream, user, oauth_token, params \\ %{}) do with {:ok, topic} <- get_topic(stream, user, oauth_token, params) do - add_socket(topic, user) + add_socket(topic, oauth_token) end end @@ -120,10 +120,10 @@ def get_topic(_stream, _user, _oauth_token, _params) do end @doc "Registers the process for streaming. Use `get_topic/3` to get the full authorized topic." - def add_socket(topic, user) do + def add_socket(topic, oauth_token) do if should_env_send?() do - auth? = if user, do: true - Registry.register(@registry, topic, auth?) + oauth_token_id = if oauth_token, do: oauth_token.id, else: false + Registry.register(@registry, topic, oauth_token_id) end {:ok, topic} @@ -296,6 +296,24 @@ defp push_to_socket(topic, %Activity{ defp push_to_socket(_topic, %Activity{data: %{"type" => "Delete"}}), do: :noop + defp push_to_socket(topic, %Activity{data: %{"type" => "Update"}} = item) do + create_activity = + Pleroma.Activity.get_create_by_object_ap_id(item.object.data["id"]) + |> Map.put(:object, item.object) + + anon_render = StreamerView.render("status_update.json", create_activity) + + Registry.dispatch(@registry, topic, fn list -> + Enum.each(list, fn {pid, auth?} -> + if auth? do + send(pid, {:render_with_user, StreamerView, "status_update.json", create_activity}) + else + send(pid, {:text, anon_render}) + end + end) + end) + end + defp push_to_socket(topic, item) do anon_render = StreamerView.render("update.json", item) @@ -320,6 +338,22 @@ defp thread_containment(activity, user) do end end + def close_streams_by_oauth_token(oauth_token) do + if should_env_send?() do + Registry.select( + @registry, + [ + { + {:"$1", :"$2", :"$3"}, + [{:==, :"$3", oauth_token.id}], + [:"$2"] + } + ] + ) + |> Enum.each(fn pid -> send(pid, :close) end) + end + end + # In test environement, only return true if the registry is started. # In benchmark environment, returns false. # In any other environment, always returns true. diff --git a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex index aa3035bca..7e2e587e1 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex @@ -2,7 +2,7 @@ http://activitystrea.ms/schema/1.0/note http://activitystrea.ms/schema/1.0/post - <%= render @view_module, "_tag_author.atom", assigns %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %> <%= @data["id"] %> <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index 6d497e84c..8c551feaf 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -17,6 +17,6 @@ <%= most_recent_update(@activities) %> <%= for activity <- @activities do %> - <%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/tag.rss.eex b/lib/pleroma/web/templates/feed/feed/tag.rss.eex index edcc3e436..86466d367 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.rss.eex @@ -9,7 +9,7 @@ <%= feed_logo() %> 2b90d9 <%= for activity <- @activities do %> - <%= render @view_module, "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/user.atom.eex b/lib/pleroma/web/templates/feed/feed/user.atom.eex index 5c1f0ecbc..97a7535ab 100644 --- a/lib/pleroma/web/templates/feed/feed/user.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/user.atom.eex @@ -12,13 +12,13 @@ <%= logo(@user) %> - <%= render @view_module, "_author.atom", assigns %> + <%= render Phoenix.Controller.view_module(@conn), "_author.atom", assigns %> <%= if last_activity(@activities) do %> <% end %> <%= for activity <- @activities do %> - <%= render @view_module, "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %> + <%= render Phoenix.Controller.view_module(@conn), "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/user.rss.eex b/lib/pleroma/web/templates/feed/feed/user.rss.eex index 6b842a085..a9fee244c 100644 --- a/lib/pleroma/web/templates/feed/feed/user.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/user.rss.eex @@ -7,14 +7,14 @@ <%= logo(@user) %> <%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %> - <%= render @view_module, "_author.rss", assigns %> + <%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %> <%= if last_activity(@activities) do %> <%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %> <% end %> <%= for activity <- @activities do %> - <%= render @view_module, "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %> + <%= render Phoenix.Controller.view_module(@conn), "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/layout/email.html.eex b/lib/pleroma/web/templates/layout/email.html.eex index 087aa4fc0..5858e48b4 100644 --- a/lib/pleroma/web/templates/layout/email.html.eex +++ b/lib/pleroma/web/templates/layout/email.html.eex @@ -5,6 +5,6 @@ <%= @email.subject %> - <%= render @view_module, @view_template, assigns %> + <%= render Phoenix.Controller.view_module(@conn), Phoenix.Controller.view_template(@conn), assigns %> diff --git a/lib/pleroma/web/templates/layout/embed.html.eex b/lib/pleroma/web/templates/layout/embed.html.eex index 8b905f070..1197288e5 100644 --- a/lib/pleroma/web/templates/layout/embed.html.eex +++ b/lib/pleroma/web/templates/layout/embed.html.eex @@ -10,6 +10,6 @@ - <%= render @view_module, @view_template, assigns %> + <%= render Phoenix.Controller.view_module(@conn), Phoenix.Controller.view_template(@conn), assigns %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex index 8b894cd58..98904ad64 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex @@ -2,7 +2,7 @@ <%= form_for @conn, Routes.o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>
- <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> + <%= render Phoenix.Controller.view_module(@conn), "_scopes.html", Map.merge(assigns, %{form: f}) %>
<%= hidden_input f, :client_id, value: @client_id %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index a2f41618e..b3654f3eb 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -21,7 +21,7 @@
<%= if @app do %>

<%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application %{client_name} is requesting access to your account.", client_name: safe_to_string(html_escape(@app.client_name))) %>

- <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> + <%= render Phoenix.Controller.view_module(@conn), "_scopes.html", Map.merge(assigns, %{form: f}) %> <% end %> <%= if @user do %> @@ -63,5 +63,5 @@ <% end %> <%= if Pleroma.Config.oauth_consumer_enabled?() do %> - <%= render @view_module, Pleroma.Web.Auth.WrapperAuthenticator.oauth_consumer_template(), assigns %> + <%= render Phoenix.Controller.view_module(@conn), Pleroma.Web.Auth.WrapperAuthenticator.oauth_consumer_template(), assigns %> <% end %> diff --git a/lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex b/lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex new file mode 100644 index 000000000..d77174967 --- /dev/null +++ b/lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex @@ -0,0 +1,10 @@ +<%= if @error do %> +

<%= Gettext.dpgettext("static_pages", "status interact error", "Error: %{error}", error: @error) %>

+<% else %> +

<%= raw Gettext.dpgettext("static_pages", "status interact header", "Interacting with %{nickname}'s %{status_link}", nickname: safe_to_string(html_escape(@nickname)), status_link: safe_to_string(link(Gettext.dpgettext("static_pages", "status interact header - status link text", "status"), to: @status_link))) %>

+ <%= form_for @conn, Routes.util_path(@conn, :remote_subscribe), [as: "status"], fn f -> %> + <%= hidden_input f, :status_id, value: @status_id %> + <%= text_input f, :profile, placeholder: Gettext.dpgettext("static_pages", "placeholder text for account id", "Your account ID, e.g. lain@quitter.se") %> + <%= submit Gettext.dpgettext("static_pages", "status interact authorization button", "Interact") %> + <% end %> +<% end %> diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 53465b124..d5a24ae6c 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -7,16 +7,26 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do require Logger + alias Pleroma.Activity alias Pleroma.Config alias Pleroma.Emoji alias Pleroma.Healthcheck alias Pleroma.User + alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.CommonAPI alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.WebFinger - plug(Pleroma.Web.ApiSpec.CastAndValidate when action != :remote_subscribe) - plug(Pleroma.Web.Plugs.FederatingPlug when action == :remote_subscribe) + plug( + Pleroma.Web.ApiSpec.CastAndValidate + when action != :remote_subscribe and action != :show_subscribe_form + ) + + plug( + Pleroma.Web.Plugs.FederatingPlug + when action == :remote_subscribe + when action == :show_subscribe_form + ) plug( OAuthScopesPlug, @@ -26,13 +36,24 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do :change_password, :delete_account, :update_notificaton_settings, - :disable_account + :disable_account, + :move_account, + :add_alias, + :delete_alias + ] + ) + + plug( + OAuthScopesPlug, + %{scopes: ["read:accounts"]} + when action in [ + :list_aliases ] ) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TwitterUtilOperation - def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do + def show_subscribe_form(conn, %{"nickname" => nick}) do with %User{} = user <- User.get_cached_by_nickname(nick), avatar = User.avatar_url(user) do conn @@ -42,11 +63,52 @@ def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do render(conn, "subscribe.html", %{ nickname: nick, avatar: nil, - error: "Could not find user" + error: + Pleroma.Web.Gettext.dpgettext( + "static_pages", + "remote follow error message - user not found", + "Could not find user" + ) }) end end + def show_subscribe_form(conn, %{"status_id" => id}) do + with %Activity{} = activity <- Activity.get_by_id(id), + {:ok, ap_id} <- get_ap_id(activity), + %User{} = user <- User.get_cached_by_ap_id(activity.actor), + avatar = User.avatar_url(user) do + conn + |> render("status_interact.html", %{ + status_link: ap_id, + status_id: id, + nickname: user.nickname, + avatar: avatar, + error: false + }) + else + _e -> + render(conn, "status_interact.html", %{ + status_id: id, + avatar: nil, + error: + Pleroma.Web.Gettext.dpgettext( + "static_pages", + "status interact error message - status not found", + "Could not find status" + ) + }) + end + end + + def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do + show_subscribe_form(conn, %{"nickname" => nick}) + end + + def remote_subscribe(conn, %{"status_id" => id, "profile" => _}) do + show_subscribe_form(conn, %{"status_id" => id}) + end + def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile), %User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do @@ -57,7 +119,33 @@ def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profil render(conn, "subscribe.html", %{ nickname: nick, avatar: nil, - error: "Something went wrong." + error: + Pleroma.Web.Gettext.dpgettext( + "static_pages", + "remote follow error message - unknown error", + "Something went wrong." + ) + }) + end + end + + def remote_subscribe(conn, %{"status" => %{"status_id" => id, "profile" => profile}}) do + with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile), + %Activity{} = activity <- Activity.get_by_id(id), + {:ok, ap_id} <- get_ap_id(activity) do + conn + |> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id)) + else + _e -> + render(conn, "status_interact.html", %{ + status_id: id, + avatar: nil, + error: + Pleroma.Web.Gettext.dpgettext( + "static_pages", + "status interact error message - unknown error", + "Something went wrong." + ) }) end end @@ -71,6 +159,15 @@ def remote_interaction(%{body_params: %{ap_id: ap_id, profile: profile}} = conn, end end + defp get_ap_id(activity) do + object = Pleroma.Object.normalize(activity, fetch: false) + + case object do + %{data: %{"id" => ap_id}} -> {:ok, ap_id} + _ -> {:no_ap_id, nil} + end + end + def frontend_configurations(conn, _params) do render(conn, "frontend_configurations.json") end @@ -158,6 +255,91 @@ def disable_account(%{assigns: %{user: user}} = conn, params) do end end + def move_account(%{assigns: %{user: user}, body_params: body_params} = conn, %{}) do + case CommonAPI.Utils.confirm_current_password(user, body_params.password) do + {:ok, user} -> + with {:ok, target_user} <- find_or_fetch_user_by_nickname(body_params.target_account), + {:ok, _user} <- ActivityPub.move(user, target_user) do + json(conn, %{status: "success"}) + else + {:not_found, _} -> + conn + |> put_status(404) + |> json(%{error: "Target account not found."}) + + {:error, error} -> + json(conn, %{error: error}) + end + + {:error, msg} -> + json(conn, %{error: msg}) + end + end + + def add_alias(%{assigns: %{user: user}, body_params: body_params} = conn, _) do + with {:ok, alias_user} <- find_user_by_nickname(body_params.alias), + {:ok, _user} <- user |> User.add_alias(alias_user) do + json(conn, %{status: "success"}) + else + {:not_found, _} -> + conn + |> put_status(404) + |> json(%{error: "Target account does not exist."}) + + {:error, error} -> + json(conn, %{error: error}) + end + end + + def delete_alias(%{assigns: %{user: user}, body_params: body_params} = conn, _) do + with {:ok, alias_user} <- find_user_by_nickname(body_params.alias), + {:ok, _user} <- user |> User.delete_alias(alias_user) do + json(conn, %{status: "success"}) + else + {:error, :no_such_alias} -> + conn + |> put_status(404) + |> json(%{error: "Account has no such alias."}) + + {:error, error} -> + json(conn, %{error: error}) + end + end + + def list_aliases(%{assigns: %{user: user}} = conn, %{}) do + alias_nicks = + user + |> User.alias_users() + |> Enum.map(&User.full_nickname/1) + + json(conn, %{aliases: alias_nicks}) + end + + defp find_user_by_nickname(nickname) do + user = User.get_cached_by_nickname(nickname) + + if user == nil do + {:not_found, nil} + else + {:ok, user} + end + end + + defp find_or_fetch_user_by_nickname(nickname) do + user = User.get_by_nickname(nickname) + + if user != nil and user.local do + {:ok, user} + else + with {:ok, user} <- User.fetch_by_nickname(nickname) do + {:ok, user} + else + _ -> + {:not_found, nil} + end + end + end + def captcha(conn, _params) do json(conn, Pleroma.Captcha.new()) end diff --git a/lib/pleroma/web/twitter_api/views/util_view.ex b/lib/pleroma/web/twitter_api/views/util_view.ex index 69f243097..31b7c0c0c 100644 --- a/lib/pleroma/web/twitter_api/views/util_view.ex +++ b/lib/pleroma/web/twitter_api/views/util_view.ex @@ -4,7 +4,9 @@ defmodule Pleroma.Web.TwitterAPI.UtilView do use Pleroma.Web, :view + import Phoenix.HTML import Phoenix.HTML.Form + import Phoenix.HTML.Link alias Pleroma.Config alias Pleroma.Web.Endpoint alias Pleroma.Web.Gettext diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex index 16c2b7d61..6a55242b0 100644 --- a/lib/pleroma/web/views/streamer_view.ex +++ b/lib/pleroma/web/views/streamer_view.ex @@ -25,6 +25,20 @@ def render("update.json", %Activity{} = activity, %User{} = user) do |> Jason.encode!() end + def render("status_update.json", %Activity{} = activity, %User{} = user) do + %{ + event: "status.update", + payload: + Pleroma.Web.MastodonAPI.StatusView.render( + "show.json", + activity: activity, + for: user + ) + |> Jason.encode!() + } + |> Jason.encode!() + end + def render("notification.json", %Notification{} = notify, %User{} = user) do %{ event: "notification", @@ -51,6 +65,19 @@ def render("update.json", %Activity{} = activity) do |> Jason.encode!() end + def render("status_update.json", %Activity{} = activity) do + %{ + event: "status.update", + payload: + Pleroma.Web.MastodonAPI.StatusView.render( + "show.json", + activity: activity + ) + |> Jason.encode!() + } + |> Jason.encode!() + end + def render("chat_update.json", %{chat_message_reference: cm_ref}) do # Explicitly giving the cmr for the object here, so we don't accidentally # send a later 'last_message' that was inserted between inserting this and diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex index 6cd9962ce..f95dc2458 100644 --- a/lib/pleroma/web/web_finger.ex +++ b/lib/pleroma/web/web_finger.ex @@ -32,7 +32,13 @@ def host_meta do def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do host = Pleroma.Web.Endpoint.host() - regex = ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@#{host}/ + + regex = + if webfinger_domain = Pleroma.Config.get([__MODULE__, :domain]) do + ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@(#{host}|#{webfinger_domain})/ + else + ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@#{host}/ + end with %{"username" => username} <- Regex.named_captures(regex, resource), %User{} = user <- User.get_cached_by_nickname(username) do @@ -63,18 +69,14 @@ defp gather_aliases(%User{} = user) do end def represent_user(user, "JSON") do - {:ok, user} = User.ensure_keys_present(user) - %{ - "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}", + "subject" => "acct:#{user.nickname}@#{domain()}", "aliases" => gather_aliases(user), "links" => gather_links(user) } end def represent_user(user, "XML") do - {:ok, user} = User.ensure_keys_present(user) - aliases = user |> gather_aliases() @@ -88,12 +90,16 @@ def represent_user(user, "XML") do :XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"}, [ - {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"} + {:Subject, "acct:#{user.nickname}@#{domain()}"} ] ++ aliases ++ links } |> XmlBuilder.to_doc() end + defp domain do + Pleroma.Config.get([__MODULE__, :domain]) || Pleroma.Web.Endpoint.host() + end + defp webfinger_from_xml(body) do with {:ok, doc} <- XML.parse_document(body) do subject = XML.string_from_xpath("//Subject", doc) @@ -150,17 +156,15 @@ def get_template_from_xml(body) do end def find_lrdd_template(domain) do - with {:ok, %{status: status, body: body}} when status in 200..299 <- - HTTP.get("http://#{domain}/.well-known/host-meta") do + # WebFinger is restricted to HTTPS - https://tools.ietf.org/html/rfc7033#section-9.1 + meta_url = "https://#{domain}/.well-known/host-meta" + + with {:ok, %{status: status, body: body}} when status in 200..299 <- HTTP.get(meta_url) do get_template_from_xml(body) else - _ -> - with {:ok, %{body: body, status: status}} when status in 200..299 <- - HTTP.get("https://#{domain}/.well-known/host-meta") do - get_template_from_xml(body) - else - e -> {:error, "Can't find LRDD template: #{inspect(e)}"} - end + error -> + Logger.warn("Can't find LRDD template in #{inspect(meta_url)}: #{inspect(error)}") + {:error, :lrdd_not_found} end end @@ -174,7 +178,7 @@ defp get_address_from_domain(domain, encoded_account) when is_binary(domain) do end end - defp get_address_from_domain(_, _), do: nil + defp get_address_from_domain(_, _), do: {:error, :webfinger_no_domain} @spec finger(String.t()) :: {:ok, map()} | {:error, any()} def finger(account) do @@ -191,13 +195,11 @@ def finger(account) do encoded_account = URI.encode("acct:#{account}") with address when is_binary(address) <- get_address_from_domain(domain, encoded_account), - response <- + {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <- HTTP.get( address, [{"accept", "application/xrd+xml,application/jrd+json"}] - ), - {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <- - response do + ) do case List.keyfind(headers, "content-type", 0) do {_, content_type} -> case Plug.Conn.Utils.media_type(content_type) do @@ -215,10 +217,9 @@ def finger(account) do {:error, {:content_type, nil}} end else - e -> - Logger.debug(fn -> "Couldn't finger #{account}" end) - Logger.debug(fn -> inspect(e) end) - {:error, e} + error -> + Logger.debug("Couldn't finger #{account}: #{inspect(error)}") + error end end end diff --git a/lib/pleroma/workers/attachments_cleanup_worker.ex b/lib/pleroma/workers/attachments_cleanup_worker.ex index 0a397eae0..4c1764053 100644 --- a/lib/pleroma/workers/attachments_cleanup_worker.ex +++ b/lib/pleroma/workers/attachments_cleanup_worker.ex @@ -31,6 +31,9 @@ def perform(%Job{ def perform(%Job{args: %{"op" => "cleanup_attachments", "object" => _object}}), do: {:ok, :skip} + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(900) + defp do_clean({object_ids, attachment_urls}) do uploader = Pleroma.Config.get([Pleroma.Upload, :uploader]) diff --git a/lib/pleroma/workers/background_worker.ex b/lib/pleroma/workers/background_worker.ex index 91440cbe6..3805293bc 100644 --- a/lib/pleroma/workers/background_worker.ex +++ b/lib/pleroma/workers/background_worker.ex @@ -43,4 +43,7 @@ def perform(%Job{ def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do Instance.perform(:delete_instance, host) end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/lib/pleroma/workers/backup_worker.ex b/lib/pleroma/workers/backup_worker.ex index 3caef85b7..12ee70f00 100644 --- a/lib/pleroma/workers/backup_worker.ex +++ b/lib/pleroma/workers/backup_worker.ex @@ -30,6 +30,7 @@ def delete(backup) do |> Oban.insert() end + @impl Oban.Worker def perform(%Job{ args: %{"op" => "process", "backup_id" => backup_id, "admin_user_id" => admin_user_id} }) do @@ -37,10 +38,7 @@ def perform(%Job{ backup_id |> Backup.get() |> Backup.process(), {:ok, _job} <- schedule_deletion(backup), :ok <- Backup.remove_outdated(backup), - {:ok, _} <- - backup - |> Pleroma.Emails.UserEmail.backup_is_ready_email(admin_user_id) - |> Pleroma.Emails.Mailer.deliver() do + :ok <- maybe_deliver_email(backup, admin_user_id) do {:ok, backup} end end @@ -51,4 +49,26 @@ def perform(%Job{args: %{"op" => "delete", "backup_id" => backup_id}}) do nil -> :ok end end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(900) + + defp has_email?(user) do + not is_nil(user.email) and user.email != "" + end + + defp maybe_deliver_email(backup, admin_user_id) do + has_mailer = Pleroma.Config.get([Pleroma.Emails.Mailer, :enabled]) + backup = backup |> Pleroma.Repo.preload(:user) + + if has_email?(backup.user) and has_mailer do + backup + |> Pleroma.Emails.UserEmail.backup_is_ready_email(admin_user_id) + |> Pleroma.Emails.Mailer.deliver() + + :ok + else + :ok + end + end end diff --git a/lib/pleroma/workers/mailer_worker.ex b/lib/pleroma/workers/mailer_worker.ex index 81764ba72..940716558 100644 --- a/lib/pleroma/workers/mailer_worker.ex +++ b/lib/pleroma/workers/mailer_worker.ex @@ -12,4 +12,7 @@ def perform(%Job{args: %{"op" => "email", "encoded_email" => encoded_email, "con |> :erlang.binary_to_term() |> Pleroma.Emails.Mailer.deliver(config) end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex index a7841d917..8ce458d48 100644 --- a/lib/pleroma/workers/mute_expire_worker.ex +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -17,4 +17,7 @@ def perform(%Job{ Pleroma.Web.CommonAPI.remove_mute(user_id, activity_id) :ok end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/lib/pleroma/workers/poll_worker.ex b/lib/pleroma/workers/poll_worker.ex index 4c7eab5c1..022d026f8 100644 --- a/lib/pleroma/workers/poll_worker.ex +++ b/lib/pleroma/workers/poll_worker.ex @@ -19,6 +19,9 @@ def perform(%Job{args: %{"op" => "poll_end", "activity_id" => activity_id}}) do end end + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) + defp find_poll_activity(activity_id) do with nil <- Activity.get_by_id(activity_id) do {:error, :poll_activity_not_found} diff --git a/lib/pleroma/workers/publisher_worker.ex b/lib/pleroma/workers/publisher_worker.ex index 528a06bb3..598ae3779 100644 --- a/lib/pleroma/workers/publisher_worker.ex +++ b/lib/pleroma/workers/publisher_worker.ex @@ -22,4 +22,7 @@ def perform(%Job{args: %{"op" => "publish_one", "module" => module_name, "params params = Map.new(params, fn {k, v} -> {String.to_atom(k), v} end) Federator.perform(:publish_one, String.to_atom(module_name), params) end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(10) end diff --git a/lib/pleroma/workers/purge_expired_activity.ex b/lib/pleroma/workers/purge_expired_activity.ex index 0545d3ece..e554684fe 100644 --- a/lib/pleroma/workers/purge_expired_activity.ex +++ b/lib/pleroma/workers/purge_expired_activity.ex @@ -35,6 +35,9 @@ def perform(%Oban.Job{args: %{"activity_id" => id}}) do end end + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) + defp enabled? do with false <- Pleroma.Config.get([__MODULE__, :enabled], false) do {:error, :expired_activities_disabled} diff --git a/lib/pleroma/workers/purge_expired_filter.ex b/lib/pleroma/workers/purge_expired_filter.ex index 933ecb3f6..9114aeb7f 100644 --- a/lib/pleroma/workers/purge_expired_filter.ex +++ b/lib/pleroma/workers/purge_expired_filter.ex @@ -31,6 +31,9 @@ def perform(%Job{args: %{"filter_id" => id}}) do |> Repo.delete() end + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) + @spec get_expiration(pos_integer()) :: Job.t() | nil def get_expiration(id) do from(j in Job, diff --git a/lib/pleroma/workers/purge_expired_token.ex b/lib/pleroma/workers/purge_expired_token.ex index 1d322b6b6..2ccd9e80b 100644 --- a/lib/pleroma/workers/purge_expired_token.ex +++ b/lib/pleroma/workers/purge_expired_token.ex @@ -26,4 +26,7 @@ def perform(%Oban.Job{args: %{"token_id" => id, "mod" => module}}) do |> Pleroma.Repo.get(id) |> Pleroma.Repo.delete() end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/lib/pleroma/workers/receiver_worker.ex b/lib/pleroma/workers/receiver_worker.ex index 268b5f30f..4f513b907 100644 --- a/lib/pleroma/workers/receiver_worker.ex +++ b/lib/pleroma/workers/receiver_worker.ex @@ -9,6 +9,15 @@ defmodule Pleroma.Workers.ReceiverWorker do @impl Oban.Worker def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do - Federator.perform(:incoming_ap_doc, params) + with {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do + {:ok, res} + else + {:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed} + {:error, {:reject, reason}} -> {:cancel, reason} + e -> e + end end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/lib/pleroma/workers/remote_fetcher_worker.ex b/lib/pleroma/workers/remote_fetcher_worker.ex index c3158bbbe..d2a77aa17 100644 --- a/lib/pleroma/workers/remote_fetcher_worker.ex +++ b/lib/pleroma/workers/remote_fetcher_worker.ex @@ -11,4 +11,7 @@ defmodule Pleroma.Workers.RemoteFetcherWorker do def perform(%Job{args: %{"op" => "fetch_remote", "id" => id} = args}) do {:ok, _object} = Fetcher.fetch_object_from_id(id, depth: args["depth"]) end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(10) end diff --git a/lib/pleroma/workers/scheduled_activity_worker.ex b/lib/pleroma/workers/scheduled_activity_worker.ex index 9a17330b6..4df84d00f 100644 --- a/lib/pleroma/workers/scheduled_activity_worker.ex +++ b/lib/pleroma/workers/scheduled_activity_worker.ex @@ -37,6 +37,9 @@ def perform(%Job{args: %{"activity_id" => activity_id}}) do end end + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) + defp find_scheduled_activity(id) do with nil <- Repo.get(ScheduledActivity, id) do {:error, :scheduled_activity_not_found} diff --git a/lib/pleroma/workers/transmogrifier_worker.ex b/lib/pleroma/workers/transmogrifier_worker.ex index ed319c585..1f3f5385e 100644 --- a/lib/pleroma/workers/transmogrifier_worker.ex +++ b/lib/pleroma/workers/transmogrifier_worker.ex @@ -12,4 +12,7 @@ def perform(%Job{args: %{"op" => "user_upgrade", "user_id" => user_id}}) do user = User.get_cached_by_id(user_id) Pleroma.Web.ActivityPub.Transmogrifier.perform(:user_upgrade, user) end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/lib/pleroma/workers/web_pusher_worker.ex b/lib/pleroma/workers/web_pusher_worker.ex index 6447a5edc..67e84b0c9 100644 --- a/lib/pleroma/workers/web_pusher_worker.ex +++ b/lib/pleroma/workers/web_pusher_worker.ex @@ -17,4 +17,7 @@ def perform(%Job{args: %{"op" => "web_push", "notification_id" => notification_i Pleroma.Web.Push.Impl.perform(notification) end + + @impl Oban.Worker + def timeout(_job), do: :timer.seconds(5) end diff --git a/mix.exs b/mix.exs index 6e84fe482..3f8d2c3a7 100644 --- a/mix.exs +++ b/mix.exs @@ -4,8 +4,8 @@ defmodule Pleroma.Mixfile do def project do [ app: :pleroma, - version: version("2.4.52"), - elixir: "~> 1.9", + version: version("2.4.55"), + elixir: "~> 1.11", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix, :gettext] ++ Mix.compilers(), elixirc_options: [warnings_as_errors: warnings_as_errors()], @@ -13,8 +13,7 @@ def project do start_permanent: Mix.env() == :prod, aliases: aliases(), deps: deps(), - test_coverage: [tool: ExCoveralls], - preferred_cli_env: ["coveralls.html": :test], + test_coverage: [tool: :covertool, summary: true], # Docs name: "Pleroma", homepage_url: "https://pleroma.social/", @@ -77,10 +76,10 @@ def application do :logger, :runtime_tools, :comeonin, - :quack, :fast_sanitize, :os_mon, - :ssl + :ssl, + :esshd ], included_applications: [:ex_syslogger] ] @@ -115,15 +114,19 @@ defp oauth_deps do # Type `mix help deps` for examples and options. defp deps do [ - {:phoenix, "~> 1.5.5"}, + {:phoenix, "~> 1.6.0"}, + {:phoenix_ecto, "~> 4.4.0"}, + {:ecto_enum, "~> 1.4"}, + {:postgrex, ">= 0.0.0"}, + {:phoenix_html, "~> 3.1"}, + {:phoenix_live_reload, "~> 1.3.3", only: :dev}, + {:phoenix_live_view, "~> 0.17.1"}, + {:phoenix_live_dashboard, "~> 0.6.2"}, + {:telemetry_metrics, "~> 0.6.1"}, + {:telemetry_poller, "~> 1.0"}, {:tzdata, "~> 1.0.3"}, {:plug_cowboy, "~> 2.3"}, - {:phoenix_pubsub, "~> 2.0"}, - {:phoenix_ecto, "~> 4.0"}, - {:ecto_enum, "~> 1.4"}, - {:ecto_sql, "~> 3.6.2"}, - {:postgrex, ">= 0.15.5"}, - {:oban, "~> 2.3.4"}, + {:oban, "~> 2.13"}, {:gettext, git: "https://github.com/tusooa/gettext.git", ref: "72fb2496b6c5280ed911bdc3756890e7f38a4808", @@ -132,7 +135,6 @@ defp deps do {:trailing_format_plug, "~> 0.0.7"}, {:fast_sanitize, "~> 0.2.0"}, {:html_entities, "~> 0.5", override: true}, - {:phoenix_html, "~> 3.1", override: true}, {:calendar, "~> 1.0"}, {:cachex, "~> 3.2"}, {:poison, "~> 3.0", override: true}, @@ -154,7 +156,7 @@ defp deps do {:cors_plug, "~> 2.0"}, {:web_push_encryption, "~> 0.3.1"}, {:swoosh, "~> 1.0"}, - {:phoenix_swoosh, "~> 0.3"}, + {:phoenix_swoosh, "~> 1.1"}, {:gen_smtp, "~> 0.13"}, {:ex_syslogger, "~> 1.4"}, {:floki, "~> 0.27"}, @@ -162,12 +164,12 @@ defp deps do {:ueberauth, "~> 0.4"}, {:linkify, "~> 0.5.2"}, {:http_signatures, "~> 0.1.1"}, - {:telemetry, "~> 0.3"}, + {:telemetry, "~> 1.0.0", override: true}, {:poolboy, "~> 1.5"}, {:prometheus, "~> 4.6"}, {:prometheus_ex, - git: "https://git.pleroma.social/pleroma/elixir-libraries/prometheus.ex.git", - ref: "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5", + git: "https://github.com/lanodan/prometheus.ex.git", + branch: "fix/elixir-1.14", override: true}, {:prometheus_plugs, "~> 1.1"}, {:prometheus_phoenix, "~> 1.3"}, @@ -177,7 +179,6 @@ defp deps do branch: "no-logging"}, {:prometheus_ecto, "~> 1.4"}, {:recon, "~> 2.5"}, - {:quack, "~> 0.1.1"}, {:joken, "~> 2.0"}, {:benchee, "~> 1.0"}, {:pot, "~> 1.0"}, @@ -196,7 +197,6 @@ defp deps do {:majic, "~> 1.0"}, {:eblurhash, "~> 1.2.2"}, {:open_api_spex, "~> 3.10"}, - {:phoenix_live_dashboard, "~> 0.6.2"}, {:ecto_psql_extras, "~> 0.6"}, # indirect dependency version override @@ -205,13 +205,12 @@ defp deps do ## dev & test {:ex_doc, "~> 0.22", only: :dev, runtime: false}, {:ex_machina, "~> 2.4", only: :test}, - {:credo, "~> 1.4", only: [:dev, :test], runtime: false}, + {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, {:mock, "~> 0.3.5", only: :test}, - # temporary downgrade for excoveralls, hackney until hackney max_connections bug will be fixed - {:excoveralls, "0.12.3", only: :test}, + {:covertool, "~> 2.0", only: :test}, {:hackney, "~> 1.18.0", override: true}, {:mox, "~> 1.0", only: :test}, - {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test} + {:websockex, "~> 0.4.3", only: :test} ] ++ oauth_deps() end diff --git a/mix.lock b/mix.lock index 14e43c703..8f4f17f83 100644 --- a/mix.lock +++ b/mix.lock @@ -1,74 +1,69 @@ %{ "accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"}, "base62": {:hex, :base62, "1.2.2", "85c6627eb609317b70f555294045895ffaaeb1758666ab9ef9ca38865b11e629", [:mix], [{:custom_base, "~> 0.2.1", [hex: :custom_base, repo: "hexpm", optional: false]}], "hexpm", "d41336bda8eaa5be197f1e4592400513ee60518e5b9f4dcf38f4b4dae6f377bb"}, - "base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"}, - "bbcode": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/bbcode.git", "f2d267675e9a7e1ad1ea9beb4cc23382762b66c2", [ref: "v0.2.0"]}, "bbcode_pleroma": {:hex, :bbcode_pleroma, "0.2.0", "d36f5bca6e2f62261c45be30fa9b92725c0655ad45c99025cb1c3e28e25803ef", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "19851074419a5fedb4ef49e1f01b30df504bb5dbb6d6adfc135238063bebd1c3"}, "bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.0", "6cb662d5c1b0a8858801cf20997bd006e7016aa8c52959c9ef80e0f34fb60b7a", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "2c81d61d4f6ed0e5cf7bf27a9109b791ff216a1034b3d541327484f46dd43769"}, "benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "3ad58ae787e9c7c94dd7ceda3b587ec2c64604563e049b2a0e8baafae832addb"}, - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "cachex": {:hex, :cachex, "3.3.0", "6f2ebb8f27491fe39121bd207c78badc499214d76c695658b19d6079beeca5c2", [: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", "d90e5ee1dde14cef33f6b187af4335b88748b72b30c038969176cd4e6ccc31a1"}, "calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 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.10", "b01a007416a0ae4188e70b3b306236021b16c11474038ead7aff79dd75538c23", [:mix], [], "hexpm", "a48314e0cb45682db2ea27b8ebfa11bd6fa0a6e21a65e5772ad83ca136ff2665"}, - "certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"}, + "castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"}, + "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, "comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"}, "concurrent_limiter": {:hex, :concurrent_limiter, "0.1.1", "43ae1dc23edda1ab03dd66febc739c4ff710d047bb4d735754909f9a474ae01c", [:mix], [{:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "53968ff238c0fbb4d7ed76ddb1af0be6f3b2f77909f6796e249e737c505a16eb"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"}, + "covertool": {:hex, :covertool, "2.0.4", "54acff6cddd88d28dea663cd2e1fe20dd32fcf5f5d3aff7d59031ce44ce39efa", [:rebar3], [], "hexpm", "5c9568ba4308fda2082172737c80c31d991ea83961eb10791f06106a870d0cdc"}, "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, - "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"}, + "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, - "credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"}, + "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "crypt": {:git, "https://github.com/msantos/crypt.git", "f75cd55325e33cbea198fb41fe41871392f8fb76", [ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"]}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, - "db_connection": {:hex, :db_connection, "2.4.0", "d04b1b73795dae60cead94189f1b8a51cc9e1f911c234cc23074017c43c031e5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad416c21ad9f61b3103d254a71b63696ecadb6a917b36f563921e0de00d7d7c8"}, + "db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"}, "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "earmark": {:hex, :earmark, "1.4.18", "618c4ff1563450d1832b7fb41dc6755e470f91a6fd4c70f350a58b14f64a7db8", [:mix], [{:earmark_parser, ">= 1.4.17", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "57ac3b6da3958ed09c669a9b159e86377fcccda56bacde8a209fa4dcdef52560"}, "earmark_parser": {:hex, :earmark_parser, "1.4.17", "6f3c7e94170377ba45241d394389e800fb15adc5de51d0a3cd52ae766aafd63f", [:mix], [], "hexpm", "f93ac89c9feca61c165b264b5837bf82344d13bebc634cd575cb711e2e342023"}, "eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"}, - "ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [: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", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"}, + "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_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.4", "5d43fd088d39a158c860b17e8d210669587f63ec89ea122a4654861c8c6e2db4", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.15.7", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "311db02f1b772e3d0dc7f56a05044b5e1499d78ed6abf38885e1ca70059449e5"}, - "ecto_sql": {:hex, :ecto_sql, "3.6.2", "9526b5f691701a5181427634c30655ac33d11e17e4069eff3ae1176c764e0ba3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ec9d7e6f742ea39b63aceaea9ac1d1773d574ea40df5a53ef8afbd9242fdb6b"}, + "ecto_sql": {:hex, :ecto_sql, "3.9.0", "2bb21210a2a13317e098a420a8c1cc58b0c3421ab8e3acfa96417dab7817918c", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [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", "a8f3f720073b8b1ac4c978be25fa7960ed7fd44997420c304a4a2e200b596453"}, "eimp": {:hex, :eimp, "1.0.14", "fc297f0c7e2700457a95a60c7010a5f1dcb768a083b6d53f49cd94ab95a28f22", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "501133f3112079b92d9e22da8b88bf4f0e13d4d67ae9c15c42c30bd25ceb83b6"}, "elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"}, + "esbuild": {:hex, :esbuild, "0.5.0", "d5bb08ff049d7880ee3609ed5c4b864bd2f46445ea40b16b4acead724fb4c4a3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "f183a0b332d963c4cfaf585477695ea59eef9a6f2204fdd0efa00e099694ffe5"}, "esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm", "d73e341e3009d390aa36387dc8862860bf9f874c94d9fd92ade2926376f49981"}, "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"}, - "ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"}, "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.2.0", "07a09de557070320e264893c0acc8a1d2e7ddf80155736e0aed966486d1988e6", [: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", "15175c613371e29e1f88b78ec8a4327389ca1ec5b34489744b175727496b21bd"}, "ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"}, "ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [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", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"}, "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"}, "ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"}, - "excoveralls": {:hex, :excoveralls, "0.12.3", "2142be7cb978a3ae78385487edda6d1aff0e482ffc6123877bb7270a8ffbcfe0", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "568a3e616c264283f5dea5b020783ae40eef3f7ee2163f7a67cbd7b35bcadada"}, "fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"}, "fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "finch": {:hex, :finch, "0.10.0", "8e5e6101ae98e7f1ef830594f774411a2f9cbce4f92d8179502da69fbbff52bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "80324ba22edbdebca6fac05c8517e7457b79dfe101e3bf6b2f7c5c65c93a9077"}, + "finch": {:hex, :finch, "0.10.2", "9ad27d68270d879f73f26604bb2e573d40f29bf0e907064a9a337f90a16a0312", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dd8b11b282072cec2ef30852283949c248bd5d2820c88d8acc89402b81db7550"}, "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"}, "floki": {:hex, :floki, "0.30.1", "75d35526d3a1459920b6e87fdbc2e0b8a3670f965dd0903708d2b267e0904c55", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e9c03524447d1c4cbfccd672d739b8c18453eee377846b119d4fd71b1a176bb8"}, "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"}, - "gen_stage": {:hex, :gen_stage, "0.14.3", "d0c66f1c87faa301c1a85a809a3ee9097a4264b2edf7644bf5c123237ef732bf", [:mix], [], "hexpm"}, - "gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"}, "gettext": {:git, "https://github.com/tusooa/gettext.git", "72fb2496b6c5280ed911bdc3756890e7f38a4808", [ref: "72fb2496b6c5280ed911bdc3756890e7f38a4808"]}, "gun": {:hex, :gun, "2.0.0-rc.2", "7c489a32dedccb77b6e82d1f3c5a7dadfbfa004ec14e322cdb5e579c438632d2", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "6b9d1eae146410d727140dbf8b404b9631302ecc2066d1d12f22097ad7d254fc"}, - "hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"}, + "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, + "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, - "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, "http_signatures": {:hex, :http_signatures, "0.1.1", "ca7ebc1b61542b163644c8c3b1f0e0f41037d35f2395940d3c6c7deceab41fd8", [:mix], [], "hexpm", "cc3b8a007322cc7b624c0c15eec49ee58ac977254ff529a3c482f681465942a3"}, "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"}, "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.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"}, - "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, + "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.3.0", "62a979c46f2c81dcb8ddc9150453b60d3757d1ac393c72bb20fc50a7b0827dc6", [:mix], [{:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "57b263a79c0ec5d536ac02d569c01e6b4de91bd1cb825625fe90eab4feb7bc1e"}, "jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"}, "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, - "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"}, "linkify": {:hex, :linkify, "0.5.2", "fb66be139fdf1656ecb31f78a93592724d1b78d960a1b3598bd661013ea0e3c7", [:mix], [], "hexpm", "8d71ac690218d8952c90cbeb63cb8cc33738bb230d8a56d487d9447f2a5eab86"}, "majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, @@ -78,55 +73,58 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"}, + "mint": {:hex, :mint, "1.4.2", "50330223429a6e1260b2ca5415f69b0ab086141bc76dc2fbf34d7c389a6675b2", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "ce75a5bbcc59b4d7d8d70f8b2fc284b1751ffb35c7b6a6302b5192f8ab4ddd80"}, "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"}, "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.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"}, "mox": {:hex, :mox, "1.0.0", "4b3c7005173f47ff30641ba044eb0fe67287743eec9bd9545e37f3002b0a9f8b", [:mix], [], "hexpm", "201b0a20b7abdaaab083e9cf97884950f8a30a1350a1da403b3145e213c6f4df"}, - "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]}, "nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm", "5c040b8469c1ff1b10093d3186e2e10dbe483cd73d79ec017993fb3985b8a9b3"}, - "nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"}, + "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, - "oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"}, + "oban": {:hex, :oban, "2.13.4", "b4c4f48f4c89cc01036670eefa28aa9c03d09aadd402655475b936983d597006", [: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", "a7d26f82b409e2d7928fbb75a17716e06ad3f783ebe9af260e3dd23abed7f124"}, "open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"}, - "p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"}, - "phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "4.2.1", "13f124cf0a3ce0f1948cf24654c7b9f2347169ff75c1123f44674afee6af3b03", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "478a1bae899cac0a6e02be1deec7e2944b7754c04e7d4107fc5a517f877743c0"}, - "phoenix_html": {:hex, :phoenix_html, "3.1.0", "0b499df05aad27160d697a9362f0e89fa0e24d3c7a9065c2bd9d38b4d1416c09", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0c0a98a2cefa63433657983a2a594c7dee5927e4391e0f1bfd3a151d1def33fc"}, + "phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"}, + "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.6.2", "0769470265eb13af01b5001b29cb935f4710d6adaa1ffc18417a570a337a2f0f", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.3", [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.17.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5bc6c6b38a2ca8b5020b442322fcee6afd5e641637a0b1fb059d4bd89bc58e7b"}, + "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"}, "phoenix_live_view": {:hex, :phoenix_live_view, "0.17.5", "63f52a6f9f6983f04e424586ff897c016ecc5e4f8d1e2c22c2887af1c57215d8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c5586e6a3d4df71b8214c769d4f5eb8ece2b4001711a7ca0f97323c36958b0e3"}, - "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"}, - "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.3", "039435dd975f7e55953525b88f1d596f26c6141412584c16f4db109708a8ee68", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4a540cea32e05356541737033d666ee7fea7700eb2101bf76783adbfe06601cd"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, + "phoenix_swoosh": {:hex, :phoenix_swoosh, "1.1.0", "f8e4780705c9f254cc853f7a40e25f7198ba4d91102bcfad2226669b69766b35", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "aa82f10afd9a4b6080fdf3274dbb9432b25b210d42b4b6b55308f6e59cd87c3d"}, + "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"}, + "phoenix_view": {:hex, :phoenix_view, "2.0.1", "a653e3d9d944aace0a064e4a13ad473ffa68f7bc4ca42dbf83cc1d464f1fb295", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "6c358e2cefc5f341c728914b867c556bbfd239fed9e881bac257d70cb2b8a6f6"}, "plug": {:hex, :plug, "1.10.4", "41eba7d1a2d671faaf531fa867645bd5a3dce0957d8e2a3f398ccff7d2ef017f", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad1e233fe73d2eec56616568d260777b67f53148a999dc2d048f4eb9778fe4a0"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.5.0", "51c998f788c4e68fc9f947a5eba8c215fbb1d63a520f7604134cab0270ea6513", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5b2c8925a5e2587446f33810a58c01e66b3c345652eeec809b76ba007acde71a"}, - "plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, + "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, "plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, - "postgrex": {:hex, :postgrex, "0.15.9", "46f8fe6f25711aeb861c4d0ae09780facfdf3adbd2fb5594ead61504dd489bda", [:mix], [{:connection, "~> 1.0", [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]}], "hexpm", "610719103e4cb2223d4ab78f9f0f3e720320eeca6011415ab4137ddef730adee"}, + "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.1", "81b511b1fa7c3123171c265cb7065a1528cebd7277b0cbc94257c50a8b2e4c17", [:rebar3], [], "hexpm", "ed87f5976531d91528452faa1138a5328db7f9f20d8feaae15f5051f79bcfb6d"}, + "prom_ex": {:hex, :prom_ex, "1.7.1", "39331ee3fe6f9a8587d8208bf9274a253bb80281700e127dd18786cda5e08c37", [:mix], [{:absinthe, ">= 1.6.0", [hex: :absinthe, repo: "hexpm", optional: true]}, {:broadway, ">= 1.0.2", [hex: :broadway, repo: "hexpm", optional: true]}, {:ecto, ">= 3.5.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:finch, "~> 0.10.2", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:oban, ">= 2.4.0", [hex: :oban, repo: "hexpm", optional: true]}, {:phoenix, ">= 1.5.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, ">= 0.14.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, ">= 1.12.1", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, "~> 2.5.1", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.1", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}, {:telemetry_metrics_prometheus_core, "~> 1.0.2", [hex: :telemetry_metrics_prometheus_core, repo: "hexpm", optional: false]}, {:telemetry_poller, "~> 1.0.0", [hex: :telemetry_poller, repo: "hexpm", optional: false]}], "hexpm", "4c978872b88a929833925a0f4d0561824804c671fdd04581e765509ed0a6ed08"}, "prometheus": {:hex, :prometheus, "4.8.0", "1ce1e1002b173c336d61f186b56263346536e76814edd9a142e12aeb2d6c1ad2", [:mix, :rebar3], [], "hexpm", "0fc2e17103073edb3758a46a5d44b006191bf25b73cbaa2b779109de396afcb5"}, "prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"}, - "prometheus_ex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/prometheus.ex.git", "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5", [ref: "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5"]}, + "prometheus_ex": {:git, "https://github.com/lanodan/prometheus.ex.git", "31f7fbe4b71b79ba27efc2a5085746c4011ceb8f", [branch: "fix/elixir-1.14"]}, "prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "c4d1404ac4e9d3d963da601db2a7d8ea31194f0017057fabf0cfb9bf5a6c8c75"}, "prometheus_phx": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/prometheus-phx.git", "9cd8f248c9381ffedc799905050abce194a97514", [branch: "no-logging"]}, "prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"}, - "quack": {:hex, :quack, "0.1.1", "cca7b4da1a233757fdb44b3334fce80c94785b3ad5a602053b7a002b5a8967bf", [:mix], [{:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}, {:tesla, "~> 1.2.0", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "d736bfa7444112eb840027bb887832a0e403a4a3437f48028c3b29a2dbbd2543"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "recon": {:hex, :recon, "2.5.1", "430ffa60685ac1efdfb1fe4c97b8767c92d0d92e6e7c3e8621559ba77598678a", [:mix, :rebar3], [], "hexpm", "5721c6b6d50122d8f68cccac712caa1231f97894bab779eff5ff0f886cb44648"}, "remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8", [ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"]}, "sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "sweet_xml": {:hex, :sweet_xml, "0.7.2", "4729f997286811fabdd8288f8474e0840a76573051062f066c4b597e76f14f9f", [:mix], [], "hexpm", "6894e68a120f454534d99045ea3325f7740ea71260bc315f82e29731d570a6e8"}, - "swoosh": {:hex, :swoosh, "1.3.11", "34f79c57f19892b43bd2168de9ff5de478a721a26328ef59567aad4243e7a77b", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, 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", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "f1e2a048db454f9982b9cf840f75e7399dd48be31ecc2a7dc10012a803b913af"}, + "swoosh": {:hex, :swoosh, "1.8.2", "af9a22ab2c0d20b266f61acca737fa11a121902de9466a39e91bacdce012101c", [: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", "d058ba750eafadb6c09a84a352c14c5d1eeeda6e84945fcc95785b7f3067b7db"}, "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"}, + "telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"}, "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"}, - "tesla": {:hex, :tesla, "1.4.1", "ff855f1cac121e0d16281b49e8f066c4a0d89965f98864515713878cca849ac8", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "95f5de35922c8c4b3945bee7406f66eb680b0955232f78f5fb7e853aa1ce201a"}, + "telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.0.2", "c98b1c580de637bfeac00db41b9fb91fb4c3548ee3d512a8ed7299172312eaf3", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "48351a0d56f80e38c997b44232b1043e0a081670d16766eee920e6254175b730"}, + "telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"}, + "tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"}, "timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"}, "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, "tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"}, @@ -134,5 +132,5 @@ "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, "unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"}, "web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"}, - "websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []}, + "websockex": {:hex, :websockex, "0.4.3", "92b7905769c79c6480c02daacaca2ddd49de936d912976a4d3c923723b647bf0", [:mix], [], "hexpm", "95f2e7072b85a3a4cc385602d42115b73ce0b74a9121d0d6dbbf557645ac53e4"}, } diff --git a/priv/gettext/config_descriptions.pot b/priv/gettext/config_descriptions.pot new file mode 100644 index 000000000..1c3a98d3e --- /dev/null +++ b/priv/gettext/config_descriptions.pot @@ -0,0 +1,6023 @@ +## 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. +msgid "" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :esshd" +msgid "Before enabling this you must add :esshd to mix.exs as one of the extra_applications and generate host keys in your priv dir with ssh-keygen -m PEM -N \"\" -b 2048 -t rsa -f ssh_host_rsa_key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger" +msgid "Logger-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :mime" +msgid "Mime Types settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma" +msgid "Authenticator" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :cors_plug" +msgid "CORS plug config" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :esshd" +msgid "ESSHD" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger" +msgid "Logger" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime" +msgid "Mime Types" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma" +msgid "Pleroma Admin Token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma" +msgid "Pleroma Authenticator" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger-:console" +msgid "Console logger settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger-:ex_syslogger" +msgid "ExSyslogger-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub" +msgid "ActivityPub-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:auth" +msgid "Authentication / authorization settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:connections_pool" +msgid "Advanced settings for `Gun` connections pool" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:email_notifications" +msgid "Email notifications settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:features" +msgid "Customizable features" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:feed" +msgid "Configure feed rendering" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations" +msgid "This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for pleroma_fe are configured. If you want to add your own configuration your settings all fields must be complete." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends" +msgid "Installed frontends management" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:gopher" +msgid "Gopher settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools" +msgid "Advanced settings for `Hackney` connections pools" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http" +msgid "HTTP settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security" +msgid "HTTP security settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance" +msgid "Instance-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instances_favicons" +msgid "Control favicons for instances" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap" +msgid "Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password will be verified by trying to authenticate (bind) to a LDAP server. If a user exists in the LDAP directory but there is no account with the same name yet on the Pleroma instance then a new Pleroma account will be created with the same name as the LDAP user name." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:majic_pool" +msgid "Majic/libmagic configuration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:manifest" +msgid "This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:modules" +msgid "Custom Runtime Modules" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf" +msgid "General MRF settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_activity_expiration" +msgid "Adds automatic expiration to all local activities" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_follow_bot" +msgid "Automatically follows newly discovered accounts." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hashtag" +msgid "Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)\n\nNote: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hellthread" +msgid "Block messages with excessive user mentions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_keyword" +msgid "Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_mention" +msgid "Block messages which mention a specific user" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_normalize_markup" +msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_object_age" +msgid "Rejects or delists posts based on their timestamp deviance from your server's clock." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_rejectnonpublic" +msgid "RejectNonPublic drops posts with non-public visibility settings." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple" +msgid "Simple ingress policies" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_steal_emoji" +msgid "Steals emojis from selected instances when it sees them." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_vocabulary" +msgid "Filter messages which belong to certain activity vocabularies" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:oauth2" +msgid "Configure OAuth 2 provider capabilities" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools" +msgid "Advanced settings for `Gun` workers pools" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:populate_hashtags_table" +msgid "`populate_hashtags_table` background migration settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit" +msgid "Rate limit settings. This is an advanced feature enabled only for :authentication by default." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated" +msgid "Disallow viewing timelines, user profiles and statuses for unauthenticated users." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media" +msgid "If enabled the instance will parse metadata from attached links to generate link previews" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:shout" +msgid "Pleroma shout settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:static_fe" +msgid "Render profiles and posts using server-generated HTML that is viewable without using JavaScript" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:streamer" +msgid "Settings for notifications streamer" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:uri_schemes" +msgid "URI schemes related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome" +msgid "Welcome messages settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:workers" +msgid "Includes custom worker options not interpretable directly by `Oban`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter" +msgid "Limits configuration for background tasks." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban" +msgid "[Oban](https://github.com/sorentwo/oban) asynchronous job processor configuration." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Captcha" +msgid "Captcha-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Kocaptcha is a very simple captcha service with a single API endpoint, the source code is here: https://github.com/koto-bank/kocaptcha. The default endpoint (https://captcha.kotobank.ch) is hosted by the developer." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer" +msgid "Mailer-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "New users admin email digest" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail" +msgid "Email template settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter" +msgid "Configuration for Pleroma's link formatter which parses mentions, hashtags, and URLs." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity" +msgid "Scheduled activities settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload" +msgid "Upload general settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename" +msgid "Filter replaces the filename of the upload" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify" +msgid "Uploads mogrify filter settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local" +msgid "Local uploader-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3" +msgid "S3 uploader-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.User.Backup" +msgid "Account Backup" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http" +msgid "HTTP invalidate settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script" +msgid "Invalidation script settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Metadata" +msgid "Metadata-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Preload" +msgid "Preload-related settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Expired activities settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" +msgid "Prometheus app metrics endpoint configuration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :ex_aws-:s3" +msgid "S3" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:console" +msgid "Console Logger" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:ex_syslogger" +msgid "ExSyslogger" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub" +msgid "ActivityPub" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:assets" +msgid "Assets" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:auth" +msgid "Auth" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:connections_pool" +msgid "Connections pool" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:email_notifications" +msgid "Email notifications" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:emoji" +msgid "Emoji" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:features" +msgid "Features" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:feed" +msgid "Feed" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations" +msgid "Frontend configurations" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends" +msgid "Frontends" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:gopher" +msgid "Gopher" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools" +msgid "Hackney pools" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http" +msgid "HTTP" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security" +msgid "HTTP security" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance" +msgid "Instance" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instances_favicons" +msgid "Instances favicons" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap" +msgid "LDAP" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:majic_pool" +msgid "Majic pool" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:manifest" +msgid "Manifest" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:markup" +msgid "Markup Settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:modules" +msgid "Modules" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf" +msgid "MRF" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_activity_expiration" +msgid "MRF Activity Expiration Policy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_follow_bot" +msgid "MRF FollowBot Policy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hashtag" +msgid "MRF Hashtag" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hellthread" +msgid "MRF Hellthread" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_keyword" +msgid "MRF Keyword" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_mention" +msgid "MRF Mention" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_normalize_markup" +msgid "MRF Normalize Markup" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_object_age" +msgid "MRF Object Age" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_rejectnonpublic" +msgid "MRF Reject Non Public" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple" +msgid "MRF Simple" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_steal_emoji" +msgid "MRF Emojis" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_subchain" +msgid "MRF Subchain" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_vocabulary" +msgid "MRF Vocabulary" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:oauth2" +msgid "OAuth2" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools" +msgid "Pools" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:populate_hashtags_table" +msgid "Populate hashtags table" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit" +msgid "Rate limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated" +msgid "Restrict Unauthenticated" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media" +msgid "Rich media" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:shout" +msgid "Shout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:static_fe" +msgid "Static FE" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:streamer" +msgid "Streamer" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:uri_schemes" +msgid "URI Schemes" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:user" +msgid "User" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:web_cache_ttl" +msgid "Web cache TTL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome" +msgid "Welcome" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:workers" +msgid "Workers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter" +msgid "ConcurrentLimiter" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban" +msgid "Oban" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Captcha" +msgid "Pleroma.Captcha" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Pleroma.Captcha.Kocaptcha" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer" +msgid "Pleroma.Emails.Mailer" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "Pleroma.Emails.NewUsersDigestEmail" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail" +msgid "Pleroma.Emails.UserEmail" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter" +msgid "Linkify" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity" +msgid "Pleroma.ScheduledActivity" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload" +msgid "Pleroma.Upload" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename" +msgid "Pleroma.Upload.Filter.AnonymizeFilename" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.Mogrify" +msgid "Pleroma.Upload.Filter.Mogrify" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local" +msgid "Pleroma.Uploaders.Local" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3" +msgid "Pleroma.Uploaders.S3" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.User" +msgid "Pleroma.User" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.User.Backup" +msgid "Pleroma.User.Backup" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate" +msgid "Pleroma.Web.ApiSpec.CastAndValidate" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http" +msgid "Pleroma.Web.MediaProxy.Invalidation.Http" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script" +msgid "Pleroma.Web.MediaProxy.Invalidation.Script" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Metadata" +msgid "Pleroma.Web.Metadata" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp" +msgid "Pleroma.Web.Plugs.RemoteIp" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Preload" +msgid "Pleroma.Web.Preload" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Pleroma.Workers.PurgeExpiredActivity" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" +msgid "Pleroma.Web.Endpoint.MetricsExporter" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :web_push_encryption-:vapid_details" +msgid "Vapid Details" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :esshd > :enabled" +msgid "Enables SSH" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :esshd > :handler" +msgid "Handler module" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :esshd > :password_authenticator" +msgid "Authenticator module" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :esshd > :port" +msgid "Port to connect" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :esshd > :priv_dir" +msgid "Dir with SSH keys" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :ex_aws-:s3 > :access_key_id" +msgid "S3 access key ID" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :ex_aws-:s3 > :host" +msgid "S3 host" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :ex_aws-:s3 > :region" +msgid "S3 region (for AWS)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :ex_aws-:s3 > :secret_access_key" +msgid "Secret access key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger-:console > :format" +msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger-:console > :level" +msgid "Log level" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger-:ex_syslogger > :format" +msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :logger-:ex_syslogger > :level" +msgid "Log level" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :blockers_visible" +msgid "Whether a user can see someone who has blocked them" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Following handshake timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :note_replies_output_limit" +msgid "The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :outgoing_blocks" +msgid "Whether to federate blocks to other instances" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :sign_object_fetches" +msgid "Sign object fetches with HTTP signatures" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :unfollow_blocked" +msgid "Whether blocks result in people getting unfollowed" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:assets > :default_mascot" +msgid "This will be used as the default mascot on MastoFE. Default: `:pleroma_fox_tan`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:assets > :default_user_avatar" +msgid "URL of the default user avatar" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:assets > :mascots" +msgid "Keyword of mascots, each element must contain both an URL and a mime_type key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "OAuth admin scope requirement toggle. If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes). If disabled and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:auth > :oauth_consumer_strategies" +msgid "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable. Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\" (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to `lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex`." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:connections_pool > :connect_timeout" +msgid "Timeout while `gun` will wait until connection is up. Default: 5000ms." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Number of attempts to acquire the connection from the pool if it is overloaded. Default: 5" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Timeout to acquire a connection from pool. The total max time is this value multiplied by the number of retries. Default: 250ms." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:connections_pool > :max_connections" +msgid "Maximum number of connections in the pool. Default: 250 connections." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Multiplier for the number of idle connection to be reclaimed if the pool is full. For example if the pool maxes out at 250 connections and this setting is set to 0.3, the pool will reclaim at most 75 idle connections if it's overloaded. Default: 0.1" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:email_notifications > :digest" +msgid "emails of \"what you've missed\" for users who have been inactive for a while" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:email_notifications > :digest > :active" +msgid "Globally enable or disable digest emails" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Minimum user inactivity threshold" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:email_notifications > :digest > :interval" +msgid "Minimum interval between digest emails to one user" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +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 "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:emoji > :groups" +msgid "Emojis are ordered in groups (tags). This is an array of key-value pairs where the key is the group name and the value is the location or array of locations. * can be used as a wildcard." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:emoji > :pack_extensions" +msgid "A list of file extensions for emojis, when no emoji.txt for a pack is present" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:emoji > :shortcode_globs" +msgid "Location of custom emoji files. * can be used as a wildcard." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:features > :improved_hashtag_timeline" +msgid "Setting to force toggle / force disable improved hashtags timeline. `:enabled` forces hashtags to be fetched from `hashtags` table for hashtags timeline. `:disabled` forces object-embedded hashtags to be used (slower). Keep it `:auto` for automatic behaviour (it is auto-set to `:enabled` [unless overridden] when HashtagsTableMigrator completes)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:feed > :post_title" +msgid "Configure title rendering" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:feed > :post_title > :max_length" +msgid "Maximum number of characters before truncating title" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:feed > :post_title > :omission" +msgid "Replacement which will be used after truncating string" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Settings for Pleroma FE" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "When disabled, auto-hide the subject field if it's empty" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "URL of the background, unless viewing a user profile with a background that is set" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "When a message has a subject (aka Content Warning), collapse it by default" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Enables green text on lines prefixed with the > character" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hides filtered statuses from timelines" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hides muted statuses from timelines" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide notices statistics (repeats, favorites, ...)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hides instance name from PleromaFE banner" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide profile statistics (posts, posts per day, followers, followings, ...)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "URL of the logo, defaults to Pleroma's logo" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Allows you to adjust vertical margins between logo boundary and navbar borders. The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. If you want a colorful logo you must disable logoMask." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Limit scope selection to Direct, User default, and Scope of post replying to. Also prevents replying to a DM with a public post from PleromaFE." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "URL of the image to use for hiding NSFW media attachments in the timeline" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Default post formatting option" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Relative URL which indicates where to redirect when a user is logged in" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Relative URL which indicates where to redirect when a user isn't logged in" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Copy the scope (private/unlisted/public) in replies to posts by default" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Enables panel displaying functionality of the instance on the About page" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Whether to show the instance's custom panel" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Change alignment of sidebar and panels to the right" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Allows changing the default behaviour of subject lines in replies.\n `email`: copy and preprend re:, as in email,\n `masto`: copy verbatim, as in Mastodon,\n `noop`: don't copy the subject." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Which theme to use. Available themes are defined in styles.json" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :admin" +msgid "Admin frontend" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :admin > name" +msgid "Name of the installed frontend. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :admin > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available" +msgid "A map containing available frontends and parameters for their installation." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available > build_dir" +msgid "The directory inside the zip file " +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available > build_url" +msgid "Either an url to a zip file containing the frontend or a template to build it by inserting the `ref`. The string `${ref}` will be replaced by the configured `ref`." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available > custom-http-headers" +msgid "The custom HTTP headers for the frontend" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available > git" +msgid "URL of the git repository of the frontend" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available > name" +msgid "Name of the frontend." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :available > ref" +msgid "Reference of the frontend to be used." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :primary" +msgid "Primary frontend, the one that is served for all pages by default" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :primary > name" +msgid "Name of the installed frontend. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:frontends > :primary > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:gopher > :dstport" +msgid "Port advertised in URLs (optional, defaults to port)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:gopher > :enabled" +msgid "Enables the gopher interface" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:gopher > :ip" +msgid "IP address to bind to" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:gopher > :port" +msgid "Port to bind to" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :media" +msgid "Settings for media pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http > :adapter" +msgid "Adapter specific options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL options for HTTP adapter" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "List of TLS version to use" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http > :user_agent" +msgid "What user agent to use. Must be a string or an atom `:default`. Default value is `:default`." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security > :ct_max_age" +msgid "The maximum age for the Expect-CT header if sent" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security > :enabled" +msgid "Whether the managed content security policy is enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security > :referrer_policy" +msgid "The referrer policy to use, either \"same-origin\" or \"no-referrer\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security > :report_uri" +msgid "Adds the specified URL to report-uri and report-to group in CSP header" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security > :sts" +msgid "Whether to additionally send a Strict-Transport-Security header" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:http_security > :sts_max_age" +msgid "The maximum age for the Strict-Transport-Security header if sent" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :account_activation_required" +msgid "Require users to confirm their emails before signing in" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :account_approval_required" +msgid "Require users to be manually approved by an admin before signing in" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :account_field_name_length" +msgid "An account field name maximum length. Default: 512." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :account_field_value_length" +msgid "An account field value maximum length. Default: 2048." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :allow_relay" +msgid "Permits remote instances to subscribe to all public posts of your instance. (Important!) This may increase the visibility of your instance." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :allowed_post_formats" +msgid "MIME-type list of formats allowed to be posted (transformed into HTML)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :attachment_links" +msgid "Enable to automatically add attachment link text to statuses" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :autofollowed_nicknames" +msgid "Set to nicknames of (local) users that every new user should automatically follow" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :autofollowing_nicknames" +msgid "Set to nicknames of (local) users that automatically follows every newly registered user" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :avatar_upload_limit" +msgid "File size limit of user's profile avatars" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :background_upload_limit" +msgid "File size limit of user's profile backgrounds" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :banner_upload_limit" +msgid "File size limit of user's profile banners" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :birthday_required" +msgid "Require users to enter their birthday." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :cleanup_attachments" +msgid "Enable to remove associated attachments when status is removed.\nThis will not affect duplicates and attachments without status.\nEnabling this will increase load to database when deleting statuses on larger instances.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :description" +msgid "The instance's description. It can be seen in nodeinfo and `/api/v1/instance`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :email" +msgid "Email used to reach an Administrator/Moderator of the instance" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :extended_nickname_format" +msgid "Enable to use extended local nicknames format (allows underscores/dashes). This will break federation with older software for theses nicknames." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :external_user_synchronization" +msgid "Enabling following/followers counters synchronization for external users" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :federating" +msgid "Enable federation with other instances" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Max. depth of reply-to and reply activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Timeout (in days) of each external federation target being unreachable prior to pausing federating to it" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :healthcheck" +msgid "If enabled, system data will be shown on `/api/pleroma/healthcheck`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :instance_thumbnail" +msgid "The instance thumbnail can be any image that represents your instance and is used by some apps or services when they display information about your instance." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :invites_enabled" +msgid "Enable user invitations for admins (depends on `registrations_open` being disabled)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :limit" +msgid "Posts character limit (CW/Subject included in the counter)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :limit_to_local_content" +msgid "Limit unauthenticated users to search for local statutes and users only. Default: `:unauthenticated`." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :max_account_fields" +msgid "The maximum number of custom fields in the user profile. Default: 10." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :max_endorsed_users" +msgid "The maximum number of recommended accounts. 0 will disable the feature." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :max_media_attachments" +msgid "Maximum number of post media attachments" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :max_pinned_statuses" +msgid "The maximum number of pinned statuses. 0 will disable the feature." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :max_remote_account_fields" +msgid "The maximum number of custom fields in the remote user profile. Default: 20." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :max_report_comment_size" +msgid "The maximum size of the report comment. Default: 1000." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi-factor authentication settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "MFA backup codes settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Determines the length of backup one-time pass-codes, in characters. Defaults to 16 characters." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number of backup codes to generate." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp" +msgid "TOTP settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Determines the length of a one-time pass-code, in characters. Defaults to 6 characters." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "A period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :name" +msgid "Name of the instance" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :notify_email" +msgid "Envelope FROM address for mail sent via Pleroma" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :poll_limits" +msgid "A map with poll limits for local polls" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Maximum expiration time (in seconds)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Maximum number of characters per option" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_options" +msgid "Maximum number of options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Minimum expiration time (in seconds)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :privileged_staff" +msgid "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :profile_directory" +msgid "Enable profile directory." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :public" +msgid "Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note: when setting to `false`, please also check `:restrict_unauthenticated` setting." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :quarantined_instances" +msgid "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :registration_reason_length" +msgid "Maximum registration reason length. Default: 500." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :registrations_open" +msgid "Enable registrations for anyone. Invitations require this setting to be disabled." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :remote_limit" +msgid "Hard character limit beyond which remote posts will be dropped" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :remote_post_retention_days" +msgid "The default amount of days to retain remote posts when pruning the database" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :safe_dm_mentions" +msgid "If enabled, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\"). Default: disabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :show_reactions" +msgid "Let favourites and emoji reactions be viewed through the API." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :skip_thread_containment" +msgid "Skip filtering out broken threads. Default: enabled." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :static_dir" +msgid "Instance static directory" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :upload_limit" +msgid "File size limit of uploads (except for avatar, background, banner)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :user_bio_length" +msgid "A user bio maximum length. Default: 5000." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :user_name_length" +msgid "A user name maximum length. Default: 100." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instances_favicons > :enabled" +msgid "Allow/disallow displaying and getting instances favicons" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :base" +msgid "LDAP base, e.g. \"dc=example,dc=com\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :enabled" +msgid "Enables LDAP authentication" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :host" +msgid "LDAP server hostname" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :port" +msgid "LDAP port, e.g. 389 or 636" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :ssl" +msgid "Enable to use SSL, usually implies the port 636" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :sslopts" +msgid "Additional SSL options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :sslopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :tls" +msgid "Enable to use STARTTLS, usually implies the port 389" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :tlsopts" +msgid "Additional TLS options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :tlsopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:ldap > :uid" +msgid "LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:majic_pool > :size" +msgid "Number of majic workers to start." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:manifest > :background_color" +msgid "Describe the background color of the app" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:manifest > :icons" +msgid "Describe the icons of the app" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:manifest > :theme_color" +msgid "Describe the theme color of the app" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:markup > :scrub_policy" +msgid "Module names are shortened (removed leading `Pleroma.HTML.` part), but on adding custom module you need to use full name." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_preview_proxy > :enabled" +msgid "Enables proxying of remote media preview to the instance's proxy. Requires enabled media proxy." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_preview_proxy > :image_quality" +msgid "Quality of the output. Ranges from 0 (min quality) to 100 (max quality)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length (in bytes) to perform preview. Media smaller in size will be served without thumbnailing." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Max height of preview thumbnail for images (video preview always has original dimensions)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Max width of preview thumbnail for images (video preview always has original dimensions)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :base_url" +msgid "The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :enabled" +msgid "Enables proxying of remote media via the instance's proxy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enables media cache object invalidation." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Module which will be used to purge objects from the cache." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts" +msgid "Internal Pleroma.ReverseProxy settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Maximum file size (in bytes) allowed through the Pleroma MediaProxy cache." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Timeout (in milliseconds) of GET request to the remote URI." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirects the client to the origin server upon encountering HTTP errors.\n\nNote that files larger than Max Body Length will trigger an error. (e.g., Peertube videos)\n\n\n**WARNING:** This setting will allow larger files to be accessed, but exposes the\n\nIP addresses of your users to the other servers, bypassing the MediaProxy.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:media_proxy > :whitelist" +msgid "List of hosts with scheme to bypass the MediaProxy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:modules > :runtime_dir" +msgid "A path to custom Elixir modules (such as MRF policies)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf > :policies" +msgid "A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf > :transparency" +msgid "Make the content of your Message Rewrite Facility settings public (via nodeinfo)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf > :transparency_exclusions" +msgid "Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. You can also provide a reason for excluding these instance names. The instances and reasons won't be publicly disclosed." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_activity_expiration > :days" +msgid "Default global expiration time for all local activities (in days)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "The name of the bot account to use for following newly discovered users." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hashtag > :reject" +msgid "A list of hashtags which result in message being rejected." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hashtag > :sensitive" +msgid "A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Number of mentioned users after which the message gets removed from timelines anddisables notifications. Set to 0 to disable." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Number of mentioned users after which the messaged gets rejected. Set to 0 to disable." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid " A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_keyword > :reject" +msgid " A list of patterns which result in message being rejected.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_keyword > :replace" +msgid " **Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n\n **Replacement**: a string. Leaving the field empty is permitted.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_mention > :actors" +msgid "A list of actors for which any post mentioning them will be dropped" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_object_age > :threshold" +msgid "Required age (in seconds) of a post before actions are taken." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Whether to allow direct messages" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Whether to allow followers-only posts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :accept" +msgid "List of instances to only accept activities from (except deletes) and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :avatar_removal" +msgid "List of instances to strip avatars from and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :banner_removal" +msgid "List of instances to strip banners from and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "List of instances to remove from the Federated (aka The Whole Known Network) Timeline and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :followers_only" +msgid "Force posts from the given instances to be visible by followers only and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :media_nsfw" +msgid "List of instances to tag all media as NSFW (sensitive) from and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :media_removal" +msgid "List of instances to strip media attachments from and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :reject" +msgid "List of instances to reject activities from (except deletes) and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :reject_deletes" +msgid "List of instances to reject deletions from and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_simple > :report_removal" +msgid "List of instances to reject reports from and the reason for doing so" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_steal_emoji > :hosts" +msgid "List of hosts to steal emojis from" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid " A list of patterns or matches to reject shortcodes with.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "File size limit (in bytes), checked before an emoji is saved to the disk" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_subchain > :match_actor" +msgid "Matches a series of regular expressions against the actor field" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_vocabulary > :accept" +msgid "A list of ActivityStreams terms to accept. If empty, all supported messages are accepted." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_vocabulary > :reject" +msgid "A list of ActivityStreams terms to reject. If empty, no messages are rejected." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Enable a background job to clean expired OAuth tokens. Default: disabled." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Keeps old refresh token or generate new refresh token when to obtain an access token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:oauth2 > :token_expires_in" +msgid "The lifetime in seconds of the access token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :default" +msgid "Settings for default pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :default > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :default > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :default > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :federation > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :federation > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :federation > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :media" +msgid "Settings for media pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :media > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :media > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :media > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :upload > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :upload > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:pools > :upload > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if hashtags transfer failed for all records." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :app_account_creation" +msgid "For registering user accounts from the same IP address" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :authentication" +msgid "For authentication create / password check / user existence check requests" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :relation_id_action" +msgid "For actions on relation with a specific user (follow, unfollow)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :relations_actions" +msgid "For actions on relationships with all users (follow, unfollow)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :search" +msgid "For the search requests (account & status search etc.)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :status_id_action" +msgid "For fav / unfav or reblog / unreblog actions on the same status by the same user" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :statuses_actions" +msgid "For create / delete / fav / unfav / reblog / unreblog actions on any statuses" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rate_limit > :timeline" +msgid "For requests to timelines (each timeline has it's own limiter)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities" +msgid "Settings for statuses." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Disallow view local statuses." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Disallow view remote statuses." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Settings for user profiles." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Disallow view local user profiles." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Disallow view remote user profiles." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Settings for public and federated timelines." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Disallow view federated timeline." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Disallow view public timeline." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media > :enabled" +msgid "Enables RichMedia parsing of URLs" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media > :failure_backoff" +msgid "Amount of milliseconds after request failure, during which the request will not be retried." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media > :ignore_hosts" +msgid "List of hosts which will be ignored by the metadata parser" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media > :ignore_tld" +msgid "List TLDs (top-level domains) which will ignore for parse metadata" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media > :parsers" +msgid "List of Rich Media parsers. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parsers.` part), but on adding custom module you need to use full name." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:rich_media > :ttl_setters" +msgid "List of rich media TTL setters. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parser.` part), but on adding custom module you need to use full name." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:shout > :enabled" +msgid "Enables the backend Shoutbox chat feature." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:shout > :limit" +msgid "Shout message character limit." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:static_fe > :enabled" +msgid "Enables the rendering of static HTML. Default: disabled." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:streamer > :overflow_workers" +msgid "Maximum number of workers created if pool is empty" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:streamer > :workers" +msgid "Number of workers to send notifications" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:uri_schemes > :valid_schemes" +msgid "List of the scheme part that is considered valid to be an URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub routes (except question activities). Default: `nil` (no expiration)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub routes (question activities). Default: `30_000` (30 seconds)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enables sending a chat message to newly registered users" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :chat_message > :message" +msgid "A message that will be sent to newly registered users as a chat message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome chat message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enables sending a direct message to newly registered users" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :direct_message > :message" +msgid "A message that will be sent to newly registered users" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :email > :enabled" +msgid "Enables sending an email to newly registered users" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :email > :html" +msgid "HTML content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :email > :sender" +msgid "Email address and/or nickname that will be used to send the welcome email." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :email > :subject" +msgid "Subject of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:welcome > :email > :text" +msgid "Text content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:workers > :retries" +msgid "Max retry attempts for failed jobs, per `Oban` queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Concurrent limits configuration for MediaProxyWarmingPolicy." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Concurrent limits configuration for getting RichMedia for activities." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :crontab" +msgid "Settings for cron background jobs" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :log" +msgid "Logs verbose mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues" +msgid "Background jobs queues (keys: queues, values: max numbers of concurrent jobs)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachment deletion queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :background" +msgid "Background queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :backup" +msgid "Backup queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :federator_incoming" +msgid "Incoming federation queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Outgoing federation queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :mailer" +msgid "Email sender queue, see Pleroma.Emails.Mailer" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities queue, see Pleroma.ScheduledActivities" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Oban > :queues > :web_push" +msgid "Web push notifications queue" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Captcha > :enabled" +msgid "Whether the captcha should be shown on registration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Captcha > :method" +msgid "The method/service to use for captcha" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "The time in seconds for which the captcha is valid" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "The kocaptcha endpoint to use" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "One of the mail adapters listed in [Swoosh documentation](https://hexdocs.pm/swoosh/Swoosh.html#module-adapters)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "SMTP AUTH enforcement mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "SMTP AUTH password" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "SMTP port" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Hostname or IP address" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "SMTP temporary (4xx) error retries" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use Implicit SSL/TLS. e.g. port 465" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "Explicit TLS (STARTTLS) enforcement mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "SMTP AUTH username" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enables new users admin digest email when `true`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "A path to a custom logo. Set it to `nil` to use the default Pleroma logo." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "A map with color settings for email templates." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :class" +msgid "Specify the class to be added to the generated link. Disable to clear." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :extra" +msgid "Link URLs with rarely used schemes (magnet, ipfs, irc, etc.)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :new_window" +msgid "Link URLs will open in a new window/tab." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :rel" +msgid "Override the rel attribute. Disable to clear." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip the scheme prefix." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :truncate" +msgid "Set to a number to truncate URLs longer than the number. Truncated URLs will end in `...`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Set to false to disable TLD validation for URLs/emails. Can be set to :no_scheme to validate TLDs only for URLs without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "The number of scheduled activities a user is allowed to create in a single day. Default: 25." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Whether scheduled activities are sent to the job queue to be executed" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "The number of scheduled activities a user is allowed to create in total. Default: 300." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL for the uploads. Required if you use a CDN or host attachments under a different domain." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Set max length of a filename to display. 0 = no limit. Default: 30" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload > :filters" +msgid "List of filter modules for uploads. Module names are shortened (removed leading `Pleroma.Upload.Filter.` part), but on adding custom module you need to use full name." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload > :link_name" +msgid "If enabled, a name parameter will be added to the URL of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy requests to the remote uploader.\n\nUseful if media upload endpoint is not internet accessible.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload > :uploader" +msgid "Module which will be used for uploads" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text to replace filenames in links. If no setting, {random}.extension will be used. You can get the original filename extension by using {extension}, for example custom-file-name.{extension}." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "List of actions for the mogrify command. It's possible to add self-written settings as string. For example `auto-orient, strip, {\"resize\", \"3840x1080>\"}` value will be parsed into valid list of the settings." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Path where user's uploads will be saved" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "S3 bucket" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "S3 bucket namespace" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc. For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in Upload base_url." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.User > :email_blacklist" +msgid "List of email domains users may not register with." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "List of nicknames users may not register with." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit user to export not more often than once per N days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Remove backup achives after N days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Enables strict input validation (useful in development, not recommended in production)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "HTTP headers of request" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "HTTP method of request. Default: :purge" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Request options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Path to executable script which will purge cached items." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "Optional URL format preprocessing. Only required for Apache's htcacheclean." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "List of metadata providers to enable" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "When enabled NSFW attachments will be shown in previews" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enable/disable the plug. Default: disabled." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid " A list of strings naming the HTTP headers to use when deriving the true client IP. Default: `[\"x-forwarded-for\"]`.\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "A list of upstream proxy IP subnets in CIDR notation from which we will parse the content of `headers`. Defaults to `[]`. IPv4 entries without a bitmask will be assumed to be /32 and IPv6 /128." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid " A list of reserved IP subnets in CIDR notation which should be ignored if found in `headers`. Defaults to `[\"127.0.0.0/8\", \"::1/128\", \"fc00::/7\", \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"]`\n" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Web.Preload > :providers" +msgid "List of preload providers to enable" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enables expired activities addition & deletion" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Minimum lifetime for ephemeral activity (in seconds)" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Enables HTTP Basic Auth for app metrics endpoint." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "[Pleroma extension] Enables app metrics endpoint." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "App metrics endpoint output format." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "Restrict access of app metrics endpoint to the specified IP addresses." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "App metrics endpoint URI path." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :web_push_encryption-:vapid_details > :private_key" +msgid "VAPID private key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :web_push_encryption-:vapid_details > :public_key" +msgid "VAPID public key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :web_push_encryption-:vapid_details > :subject" +msgid "A mailto link for the administrative contact. It's best if this email is not a personal email address, but rather a group email to the instance moderation team." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :cors_plug > :credentials" +msgid "Credentials" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :cors_plug > :expose" +msgid "Expose" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :cors_plug > :headers" +msgid "Headers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :cors_plug > :max_age" +msgid "Max age" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :cors_plug > :methods" +msgid "Methods" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :esshd > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :esshd > :handler" +msgid "Handler" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :esshd > :password_authenticator" +msgid "Password authenticator" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :esshd > :port" +msgid "Port" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :esshd > :priv_dir" +msgid "Priv dir" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :ex_aws-:s3 > :access_key_id" +msgid "Access key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :ex_aws-:s3 > :host" +msgid "Host" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :ex_aws-:s3 > :region" +msgid "Region" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :ex_aws-:s3 > :secret_access_key" +msgid "Secret access key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger > :backends" +msgid "Backends" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:console > :format" +msgid "Format" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:console > :level" +msgid "Level" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:console > :metadata" +msgid "Metadata" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:ex_syslogger > :format" +msgid "Format" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:ex_syslogger > :ident" +msgid "Ident" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:ex_syslogger > :level" +msgid "Level" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :logger-:ex_syslogger > :metadata" +msgid "Metadata" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime > :types" +msgid "Types" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime > :types > application/activity+json" +msgid "\"application/activity+json\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime > :types > application/jrd+json" +msgid "\"application/jrd+json\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime > :types > application/ld+json" +msgid "\"application/ld+json\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime > :types > application/xml" +msgid "\"application/xml\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :mime > :types > application/xrd+xml" +msgid "\"application/xrd+xml\"" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma > Pleroma.Web.Auth.Authenticator" +msgid "Pleroma.Web.Auth.Authenticator" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :blockers_visible" +msgid "Blockers visible" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Follow handshake timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :note_replies_output_limit" +msgid "Note replies output limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :outgoing_blocks" +msgid "Outgoing blocks" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :sign_object_fetches" +msgid "Sign object fetches" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :unfollow_blocked" +msgid "Unfollow blocked" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:assets > :default_mascot" +msgid "Default mascot" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:assets > :default_user_avatar" +msgid "Default user avatar" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:assets > :mascots" +msgid "Mascots" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:auth > :auth_template" +msgid "Auth template" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "Enforce OAuth admin scope usage" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:auth > :oauth_consumer_strategies" +msgid "OAuth consumer strategies" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer template" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:connections_pool > :connect_timeout" +msgid "Connect timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Connection acquisition retries" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Connection acquisition wait" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:connections_pool > :max_connections" +msgid "Max connections" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Reclaim multiplier" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:email_notifications > :digest" +msgid "Digest" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:email_notifications > :digest > :active" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Inactivity threshold" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:email_notifications > :digest > :interval" +msgid "Interval" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:email_notifications > :digest > :schedule" +msgid "Schedule" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:emoji > :default_manifest" +msgid "Default manifest" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:emoji > :groups" +msgid "Groups" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:emoji > :pack_extensions" +msgid "Pack extensions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:emoji > :shared_pack_cache_seconds_per_file" +msgid "Shared pack cache s/file" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:emoji > :shortcode_globs" +msgid "Shortcode globs" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:features > :improved_hashtag_timeline" +msgid "Improved hashtag timeline" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:feed > :post_title" +msgid "Post title" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:feed > :post_title > :max_length" +msgid "Max length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:feed > :post_title > :omission" +msgid "Omission" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Pleroma FE" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "Always show subject input" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "Background" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "Collapse message with subject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Greentext" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hide Filtered Statuses" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hide Muted Posts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide post stats" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hide Sitename" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide user stats" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "Logo" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Logo margin" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "Logo mask" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Minimal scopes mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "NSFW Censor Image" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Post Content Type" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Redirect root login" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Redirect root no login" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Scope copy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Show instance features panel" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Show instance specific panel" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Sidebar on Right" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Subject line behavior" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Theme" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :admin" +msgid "Admin" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :admin > name" +msgid "Name" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :admin > ref" +msgid "Reference" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available" +msgid "Available" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available > build_dir" +msgid "Build directory" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available > build_url" +msgid "Build URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available > custom-http-headers" +msgid "Custom HTTP headers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available > git" +msgid "Git Repository URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available > name" +msgid "Name" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :available > ref" +msgid "Reference" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :primary" +msgid "Primary" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :primary > name" +msgid "Name" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:frontends > :primary > ref" +msgid "Reference" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:gopher > :dstport" +msgid "Dstport" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:gopher > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:gopher > :ip" +msgid "IP" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:gopher > :port" +msgid "Port" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :federation" +msgid "Federation" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Max connections" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :media" +msgid "Media" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Max connections" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :upload" +msgid "Upload" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Max connections" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http > :adapter" +msgid "Adapter" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL Options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "Versions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http > :send_user_agent" +msgid "Send user agent" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http > :user_agent" +msgid "User agent" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security > :ct_max_age" +msgid "CT max age" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security > :referrer_policy" +msgid "Referrer policy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security > :report_uri" +msgid "Report URI" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security > :sts" +msgid "STS" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:http_security > :sts_max_age" +msgid "STS max age" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :account_activation_required" +msgid "Account activation required" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :account_approval_required" +msgid "Account approval required" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :account_field_name_length" +msgid "Account field name length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :account_field_value_length" +msgid "Account field value length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :allow_relay" +msgid "Allow relay" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :allowed_post_formats" +msgid "Allowed post formats" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :attachment_links" +msgid "Attachment links" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :autofollowed_nicknames" +msgid "Autofollowed nicknames" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :autofollowing_nicknames" +msgid "Autofollowing nicknames" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :avatar_upload_limit" +msgid "Avatar upload limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :background_upload_limit" +msgid "Background upload limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :banner_upload_limit" +msgid "Banner upload limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :birthday_min_age" +msgid "Birthday min age" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :birthday_required" +msgid "Birthday required" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :cleanup_attachments" +msgid "Cleanup attachments" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :description" +msgid "Description" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :email" +msgid "Admin Email Address" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :extended_nickname_format" +msgid "Extended nickname format" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :external_user_synchronization" +msgid "External user synchronization" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :federating" +msgid "Federating" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Fed. incoming replies max depth" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Fed. reachability timeout days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :healthcheck" +msgid "Healthcheck" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :instance_thumbnail" +msgid "Instance thumbnail" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :invites_enabled" +msgid "Invites enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :limit" +msgid "Limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :limit_to_local_content" +msgid "Limit to local content" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :max_account_fields" +msgid "Max account fields" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :max_endorsed_users" +msgid "Max endorsed users" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :max_media_attachments" +msgid "Max media attachments" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :max_pinned_statuses" +msgid "Max pinned statuses" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :max_remote_account_fields" +msgid "Max remote account fields" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :max_report_comment_size" +msgid "Max report comment size" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi factor authentication" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "Backup codes" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp" +msgid "TOTP settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Digits" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "Period" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :name" +msgid "Name" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :notify_email" +msgid "Sender Email Address" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :poll_limits" +msgid "Poll limits" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Max expiration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Max option chars" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_options" +msgid "Max options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Min expiration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :privileged_staff" +msgid "Privileged staff" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :profile_directory" +msgid "Profile directory" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :public" +msgid "Public" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :quarantined_instances" +msgid "Quarantined instances" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :registration_reason_length" +msgid "Registration reason length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :registrations_open" +msgid "Registrations open" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :remote_limit" +msgid "Remote limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :remote_post_retention_days" +msgid "Remote post retention days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :safe_dm_mentions" +msgid "Safe DM mentions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :show_reactions" +msgid "Show reactions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :skip_thread_containment" +msgid "Skip thread containment" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :static_dir" +msgid "Static dir" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :upload_limit" +msgid "Upload limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :user_bio_length" +msgid "User bio length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :user_name_length" +msgid "User name length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instances_favicons > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :base" +msgid "Base" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :host" +msgid "Host" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :port" +msgid "Port" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :ssl" +msgid "SSL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :sslopts" +msgid "SSL options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :sslopts > :verify" +msgid "Verify" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :tls" +msgid "TLS" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :tlsopts" +msgid "TLS options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :tlsopts > :verify" +msgid "Verify" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:ldap > :uid" +msgid "UID" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:majic_pool > :size" +msgid "Size" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:manifest > :background_color" +msgid "Background color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:manifest > :icons" +msgid "Icons" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:manifest > :theme_color" +msgid "Theme color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:markup > :allow_fonts" +msgid "Allow fonts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:markup > :allow_headings" +msgid "Allow headings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:markup > :allow_inline_images" +msgid "Allow inline images" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:markup > :allow_tables" +msgid "Allow tables" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_preview_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_preview_proxy > :image_quality" +msgid "Image quality" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Thumbnail max height" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Thumbnail max width" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :base_url" +msgid "Base URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :invalidation" +msgid "Invalidation" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Provider" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts" +msgid "Advanced MediaProxy Options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Max body length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Max read duration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirect on failure" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:media_proxy > :whitelist" +msgid "Whitelist" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:modules > :runtime_dir" +msgid "Runtime dir" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf > :policies" +msgid "Policies" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf > :transparency" +msgid "MRF transparency" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf > :transparency_exclusions" +msgid "MRF transparency exclusions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_activity_expiration > :days" +msgid "Days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "Follower nickname" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hashtag > :reject" +msgid "Reject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hashtag > :sensitive" +msgid "Sensitive" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Delist threshold" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Reject threshold" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_keyword > :reject" +msgid "Reject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_keyword > :replace" +msgid "Replace" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_mention > :actors" +msgid "Actors" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_normalize_markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_object_age > :actions" +msgid "Actions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_object_age > :threshold" +msgid "Threshold" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Allow direct" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Allow followers-only" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :accept" +msgid "Accept" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :avatar_removal" +msgid "Avatar removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :banner_removal" +msgid "Banner removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :followers_only" +msgid "Followers only" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :media_nsfw" +msgid "Media NSFW" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :media_removal" +msgid "Media removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :reject" +msgid "Reject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :reject_deletes" +msgid "Reject deletes" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_simple > :report_removal" +msgid "Report removal" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_steal_emoji > :hosts" +msgid "Hosts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid "Rejected shortcodes" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "Size limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_subchain > :match_actor" +msgid "Match actor" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_vocabulary > :accept" +msgid "Accept" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:mrf_vocabulary > :reject" +msgid "Reject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Clean expired tokens" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Issue new refresh token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:oauth2 > :token_expires_in" +msgid "Token expires in" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :default" +msgid "Default" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :default > :max_waiting" +msgid "Max waiting" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :default > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :default > :size" +msgid "Size" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :federation" +msgid "Federation" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :federation > :max_waiting" +msgid "Max waiting" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :federation > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :federation > :size" +msgid "Size" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :media" +msgid "Media" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :media > :max_waiting" +msgid "Max waiting" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :media > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :media > :size" +msgid "Size" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :upload" +msgid "Upload" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :upload > :max_waiting" +msgid "Max waiting" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :upload > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:pools > :upload > :size" +msgid "Size" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :app_account_creation" +msgid "App account creation" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :authentication" +msgid "Authentication" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :relation_id_action" +msgid "Relation ID action" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :relations_actions" +msgid "Relations actions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :search" +msgid "Search" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :status_id_action" +msgid "Status ID action" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :statuses_actions" +msgid "Statuses actions" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rate_limit > :timeline" +msgid "Timeline" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities" +msgid "Activities" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Local" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Remote" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Profiles" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Local" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Remote" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Timelines" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Federated" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Local" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media > :failure_backoff" +msgid "Failure backoff" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media > :ignore_hosts" +msgid "Ignore hosts" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media > :ignore_tld" +msgid "Ignore TLD" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media > :parsers" +msgid "Parsers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:rich_media > :ttl_setters" +msgid "TTL setters" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:shout > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:shout > :limit" +msgid "Limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:static_fe > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:streamer > :overflow_workers" +msgid "Overflow workers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:streamer > :workers" +msgid "Workers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:uri_schemes > :valid_schemes" +msgid "Valid schemes" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:user > :deny_follow_blocked" +msgid "Deny follow blocked" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub question" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :chat_message" +msgid "Chat message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :chat_message > :message" +msgid "Message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :direct_message" +msgid "Direct message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :direct_message > :message" +msgid "Message" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :email" +msgid "Email" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :email > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :email > :html" +msgid "Html" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :email > :sender" +msgid "Sender" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :email > :subject" +msgid "Subject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:welcome > :email > :text" +msgid "Text" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:workers > :retries" +msgid "Retries" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Pleroma.Web.RichMedia.Helpers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :crontab" +msgid "Crontab" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :log" +msgid "Log" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues" +msgid "Queues" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachments cleanup" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :background" +msgid "Background" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :backup" +msgid "Backup" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :federator_incoming" +msgid "Federator incoming" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Federator outgoing" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :mailer" +msgid "Mailer" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Oban > :queues > :web_push" +msgid "Web push" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Captcha > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Captcha > :method" +msgid "Method" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "Seconds valid" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "Endpoint" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "Adapter" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :enabled" +msgid "Mailer Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:access_key" +msgid "AWS Access Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:region" +msgid "AWS Region" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:secret" +msgid "AWS Secret Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Dyn-:api_key" +msgid "Dyn API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Gmail-:access_token" +msgid "GMail API Access Token" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:api_key" +msgid "Mailgun API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:domain" +msgid "Domain" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:api_key" +msgid "MailJet Public API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:secret" +msgid "MailJet Private API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mandrill-:api_key" +msgid "Mandrill API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Postmark-:api_key" +msgid "Postmark API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "AUTH Mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "Password" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "Port" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Relay" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "Retries" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use SSL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "STARTTLS Mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "Username" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendgrid-:api_key" +msgid "SendGrid API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_args" +msgid "Cmd args" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_path" +msgid "Cmd path" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:qmail" +msgid "Qmail compat mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:api_key" +msgid "SocketLabs API Key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:server_id" +msgid "Server ID" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:api_key" +msgid "SparkPost API key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:endpoint" +msgid "Endpoint" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "Logo" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "Styling" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :background_color" +msgid "Background color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :content_background_color" +msgid "Content background color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :header_color" +msgid "Header color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :link_color" +msgid "Link color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_color" +msgid "Text color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_muted_color" +msgid "Text muted color" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :class" +msgid "Class" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :extra" +msgid "Extra" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :new_window" +msgid "New window" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :rel" +msgid "Rel" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip prefix" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :truncate" +msgid "Truncate" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Validate tld" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "Daily user limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "Total user limit" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Filename display max length" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload > :filters" +msgid "Filters" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload > :link_name" +msgid "Link name" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy remote" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload > :uploader" +msgid "Uploader" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "Args" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Uploads" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "Bucket" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "Bucket namespace" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Streaming enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "Truncated namespace" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.User > :email_blacklist" +msgid "Email blacklist" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "Restricted nicknames" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Purge after days" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Strict" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "Headers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "Method" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Options" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options > :params" +msgid "Params" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Script path" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "URL Format" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "Providers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "Unfurl NSFW" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid "Headers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "Proxies" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid "Reserved" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Web.Preload > :providers" +msgid "Providers" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Min lifetime" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Auth" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "Enabled" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "Format" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "IP Whitelist" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "Path" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :web_push_encryption-:vapid_details > :private_key" +msgid "Private key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :web_push_encryption-:vapid_details > :public_key" +msgid "Public key" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :web_push_encryption-:vapid_details > :subject" +msgid "Subject" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:activitypub > :authorized_fetch_mode" +msgid "Require HTTP signatures for AP fetches" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :short_description" +msgid "Shorter version of instance description. It can be seen on `/api/v1/instance`" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:activitypub > :authorized_fetch_mode" +msgid "Authorized fetch mode" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :short_description" +msgid "Short description" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:delete_context_objects" +msgid "`delete_context_objects` background migration settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:delete_context_objects > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if context object deletion failed for all records." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:delete_context_objects > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :birthday_min_age" +msgid "Minimum required age (in days) for users to create account. Only used if birthday is required." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:delete_context_objects" +msgid "Delete context objects" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:delete_context_objects > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:delete_context_objects > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :report_strip_status" +msgid "Strip associated statuses in reports to ids when closed/resolved, otherwise keep a copy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_object_age > :actions" +msgid "A list of actions to apply to the post. `:delist` removes the post from public timelines; `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines, additionally for followers-only it degrades to a direct message; `:reject` rejects the message entirely" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :report_strip_status" +msgid "Report strip status" +msgstr "" diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index fed111ccb..10a62d2a8 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -10,175 +10,175 @@ msgid "" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:122 msgid "%{name} - %{count} is not a multiple of %{multiple}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:131 msgid "%{name} - %{value} is larger than exclusive maximum %{max}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:140 msgid "%{name} - %{value} is larger than inclusive maximum %{max}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:149 msgid "%{name} - %{value} is smaller than exclusive minimum %{min}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:158 msgid "%{name} - %{value} is smaller than inclusive minimum %{min}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:102 msgid "%{name} - Array items must be unique." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:114 msgid "%{name} - Array length %{length} is larger than maxItems: %{}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:106 msgid "%{name} - Array length %{length} is smaller than minItems: %{min}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:166 msgid "%{name} - Invalid %{type}. Got: %{value}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:174 msgid "%{name} - Invalid format. Expected %{format}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:51 msgid "%{name} - Invalid schema.type. Got: %{type}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:178 msgid "%{name} - Invalid value for enum." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:95 msgid "%{name} - String length is larger than maxLength: %{length}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:88 msgid "%{name} - String length is smaller than minLength: %{length}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:63 msgid "%{name} - null value where %{type} expected." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:60 msgid "%{name} - null value." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:182 msgid "Failed to cast to any schema in %{polymorphic_type}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:71 msgid "Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:84 msgid "Failed to cast value to one of: %{failed_schemas}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:78 msgid "Failed to cast value using any of: %{failed_schemas}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:212 msgid "Invalid value for header: %{name}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:204 msgid "Missing field: %{name}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:208 msgid "Missing header: %{name}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:196 msgid "No value provided for required discriminator `%{field}`." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:216 msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:224 msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 msgid "Oops" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:188 msgid "Unexpected field: %{name}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:200 msgid "Unknown schema: %{name}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:192 msgid "Value used as discriminator for `%{field}` matches no schemas." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/embed/show.html.eex:43 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 msgid "announces" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/embed/show.html.eex:44 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:38 msgid "likes" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/embed/show.html.eex:42 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:36 msgid "replies" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/embed/show.html.eex:27 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:22 msgid "sensitive media" diff --git a/priv/gettext/errors.pot b/priv/gettext/errors.pot index 7644fc230..19a0039ca 100644 --- a/priv/gettext/errors.pot +++ b/priv/gettext/errors.pot @@ -89,475 +89,516 @@ msgstr "" msgid "must be equal to %{number}" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:523 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:574 msgid "Account not found" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:316 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:332 msgid "Already voted" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:402 msgid "Bad request" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/controller_helper.ex:97 #: lib/pleroma/web/controller_helper.ex:103 msgid "Can't display this activity" msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:324 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:337 msgid "Can't find user" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:80 msgid "Can't get favorites" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api/utils.ex:482 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api/utils.ex:457 msgid "Cannot post an empty status without attachments" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api/utils.ex:441 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api/utils.ex:445 msgid "Comment must be up to %{max_size} characters" msgstr "" -#, elixir-format -#: lib/pleroma/config_db.ex:200 +#, elixir-autogen, elixir-format +#: lib/pleroma/config_db.ex:199 msgid "Config with params %{params} not found" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:167 lib/pleroma/web/common_api.ex:171 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:183 +#: lib/pleroma/web/common_api.ex:187 msgid "Could not delete" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:217 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:233 msgid "Could not favorite" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:254 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:270 msgid "Could not unfavorite" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:202 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:218 msgid "Could not unrepeat" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:530 lib/pleroma/web/common_api.ex:539 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:581 +#: lib/pleroma/web/common_api.ex:590 msgid "Could not update state" msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:205 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:207 msgid "Error." msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:99 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:105 msgid "Invalid CAPTCHA" msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:144 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:146 #: lib/pleroma/web/o_auth/o_auth_controller.ex:631 msgid "Invalid credentials" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/ensure_authenticated_plug.ex:42 msgid "Invalid credentials." msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:337 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:353 msgid "Invalid indices" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:29 msgid "Invalid parameters" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api/utils.ex:349 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api/utils.ex:353 msgid "Invalid password." msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:254 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:267 msgid "Invalid request" msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:102 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:108 msgid "Kocaptcha service unavailable" msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:140 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:142 msgid "Missing parameters" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api/utils.ex:477 -msgid "No such conversation" -msgstr "" - -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:171 -#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:197 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:239 +#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:197 +#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:239 msgid "No such permission_group" msgstr "" -#, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:504 -#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11 lib/pleroma/web/feed/tag_controller.ex:16 -#: lib/pleroma/web/feed/user_controller.ex:69 lib/pleroma/web/o_status/o_status_controller.ex:132 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:502 +#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11 +#: lib/pleroma/web/feed/tag_controller.ex:16 +#: lib/pleroma/web/feed/user_controller.ex:69 +#: lib/pleroma/web/o_status/o_status_controller.ex:132 #: lib/pleroma/web/plugs/uploaded_media.ex:84 msgid "Not found" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:308 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:324 msgid "Poll's author can't vote" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:502 #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 -#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51 -#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:52 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:326 +#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39 +#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51 +#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:52 +#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:382 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 msgid "Record not found" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:35 -#: lib/pleroma/web/feed/user_controller.ex:78 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:42 +#: lib/pleroma/web/feed/user_controller.ex:78 +#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:42 #: lib/pleroma/web/o_status/o_status_controller.ex:138 msgid "Something went wrong" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/common_api/activity_draft.ex:143 msgid "The message visibility must be direct" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api/utils.ex:492 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api/utils.ex:467 msgid "The status is over the character limit" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex:36 msgid "This resource requires authentication." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/rate_limiter.ex:208 msgid "Throttled" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:338 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:354 msgid "Too many choices" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:268 msgid "You can't revoke your own admin status." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:243 #: lib/pleroma/web/o_auth/o_auth_controller.ex:333 msgid "Your account is currently disabled" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:205 #: lib/pleroma/web/o_auth/o_auth_controller.ex:356 msgid "Your login is missing a confirmed e-mail address" msgstr "" -#, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:392 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390 msgid "can't read inbox of %{nickname} as %{as_nickname}" msgstr "" -#, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:491 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:489 msgid "can't update outbox of %{nickname} as %{as_nickname}" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:475 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:526 msgid "conversation is already muted" msgstr "" -#, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:510 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:508 msgid "error" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:34 msgid "mascots can only be images" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:63 msgid "not found" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:437 msgid "Bad OAuth request." msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:108 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:114 msgid "CAPTCHA already used" msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:105 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:111 msgid "CAPTCHA expired" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/uploaded_media.ex:57 msgid "Failed" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:453 msgid "Failed to authenticate: %{message}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:484 msgid "Failed to set up user account." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/o_auth_scopes_plug.ex:37 msgid "Insufficient permissions: %{permissions}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/uploaded_media.ex:111 msgid "Internal Error" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/fallback_controller.ex:22 #: lib/pleroma/web/o_auth/fallback_controller.ex:29 msgid "Invalid Username/Password" msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:111 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:117 msgid "Invalid answer data" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33 msgid "Nodeinfo schema version not handled" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:194 msgid "This action is outside the authorized scopes" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/fallback_controller.ex:14 msgid "Unknown error, please check the details and try again." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:136 #: lib/pleroma/web/o_auth/o_auth_controller.ex:180 msgid "Unlisted redirect_uri." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:433 msgid "Unsupported OAuth provider: %{provider}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/uploaders/uploader.ex:74 msgid "Uploader callback timeout" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/uploader_controller.ex:23 msgid "bad request" msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:96 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:102 msgid "CAPTCHA Error" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:266 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:282 msgid "Could not add reaction emoji" msgstr "" -#, elixir-format -#: lib/pleroma/web/common_api.ex:277 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api.ex:293 msgid "Could not remove reaction emoji" msgstr "" -#, elixir-format -#: lib/pleroma/web/twitter_api/twitter_api.ex:122 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/twitter_api.ex:128 msgid "Invalid CAPTCHA (Missing parameter: %{name})" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:96 msgid "List not found" msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:151 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:153 msgid "Missing parameter: %{name}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:232 #: lib/pleroma/web/o_auth/o_auth_controller.ex:346 msgid "Password reset is required" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/tests/auth_test_controller.ex:9 -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/chat_controller.ex:6 lib/pleroma/web/admin_api/controllers/config_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:6 lib/pleroma/web/admin_api/controllers/frontend_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/instance_controller.ex:6 lib/pleroma/web/admin_api/controllers/instance_document_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/invite_controller.ex:6 lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex:6 lib/pleroma/web/admin_api/controllers/relay_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/report_controller.ex:6 lib/pleroma/web/admin_api/controllers/status_controller.ex:6 -#: lib/pleroma/web/admin_api/controllers/user_controller.ex:6 lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/embed_controller.ex:6 -#: lib/pleroma/web/fallback/redirect_controller.ex:6 lib/pleroma/web/feed/tag_controller.ex:6 -#: lib/pleroma/web/feed/user_controller.ex:6 lib/pleroma/web/mailer/subscription_controller.ex:6 -#: lib/pleroma/web/manifest_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/app_controller.ex:11 lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/directory_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14 lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/report_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7 lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6 -#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6 lib/pleroma/web/media_proxy/media_proxy_controller.ex:6 -#: lib/pleroma/web/mongoose_im/mongoose_im_controller.ex:6 lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6 -#: lib/pleroma/web/o_auth/fallback_controller.ex:6 lib/pleroma/web/o_auth/mfa_controller.ex:10 -#: lib/pleroma/web/o_auth/o_auth_controller.ex:6 lib/pleroma/web/o_status/o_status_controller.ex:6 -#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/app_controller.ex:6 -#: lib/pleroma/web/pleroma_api/controllers/backup_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/chat_controller.ex:5 -#: lib/pleroma/web/pleroma_api/controllers/conversation_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex:6 -#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex:6 -#: lib/pleroma/web/pleroma_api/controllers/instances_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 -#: lib/pleroma/web/pleroma_api/controllers/notification_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/report_controller.ex:6 +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/announcement_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/chat_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/config_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/frontend_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/instance_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/instance_document_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/invite_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/o_auth_app_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/relay_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/report_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/status_controller.ex:6 +#: lib/pleroma/web/admin_api/controllers/user_controller.ex:6 +#: lib/pleroma/web/controller_helper.ex:6 +#: lib/pleroma/web/embed_controller.ex:6 +#: lib/pleroma/web/fallback/redirect_controller.ex:6 +#: lib/pleroma/web/feed/tag_controller.ex:6 +#: lib/pleroma/web/feed/user_controller.ex:6 +#: lib/pleroma/web/mailer/subscription_controller.ex:6 +#: lib/pleroma/web/manifest_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/announcement_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/app_controller.ex:11 +#: lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/directory_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14 +#: lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/report_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7 +#: lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6 +#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6 +#: lib/pleroma/web/media_proxy/media_proxy_controller.ex:6 +#: lib/pleroma/web/mongoose_im/mongoose_im_controller.ex:6 +#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6 +#: lib/pleroma/web/o_auth/fallback_controller.ex:6 +#: lib/pleroma/web/o_auth/mfa_controller.ex:10 +#: lib/pleroma/web/o_auth/o_auth_controller.ex:6 +#: lib/pleroma/web/o_status/o_status_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/app_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/backup_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/chat_controller.ex:5 +#: lib/pleroma/web/pleroma_api/controllers/conversation_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/emoji_file_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/instances_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/notification_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/report_controller.ex:6 #: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6 -#: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex:6 -#: lib/pleroma/web/static_fe/static_fe_controller.ex:6 lib/pleroma/web/twitter_api/controller.ex:6 -#: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6 -#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:6 lib/pleroma/web/uploader_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/settings_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 +#: lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex:6 +#: lib/pleroma/web/static_fe/static_fe_controller.ex:6 +#: lib/pleroma/web/twitter_api/controller.ex:6 +#: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 +#: lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6 +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:6 +#: lib/pleroma/web/uploader_controller.ex:6 #: lib/pleroma/web/web_finger/web_finger_controller.ex:6 msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/ensure_authenticated_plug.ex:32 msgid "Two-factor authentication enabled, you must use a access token." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 msgid "Web push subscription is disabled on this Pleroma instance" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:234 msgid "You can't revoke your own admin/moderator status." msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:129 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:131 msgid "authorization required for timeline view" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24 msgid "Access denied" msgstr "" -#, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:321 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334 msgid "This API requires an authenticated user" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex:26 #: lib/pleroma/web/plugs/user_is_admin_plug.ex:21 msgid "User is not an admin." msgstr "" #, elixir-format -#: lib/pleroma/user/backup.ex:75 +#: lib/pleroma/user/backup.ex:73 msgid "Last export was less than a day ago" msgid_plural "Last export was less than %{days} days ago" msgstr[0] "" msgstr[1] "" -#, elixir-format -#: lib/pleroma/user/backup.ex:93 -msgid "Backups require enabled email" -msgstr "" - -#, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:423 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:421 msgid "Character limit (%{limit} characters) exceeded, contains %{length} characters" msgstr "" -#, elixir-format -#: lib/pleroma/user/backup.ex:98 -msgid "Email is required" -msgstr "" - -#, elixir-format -#: lib/pleroma/web/common_api/utils.ex:507 +#, elixir-autogen, elixir-format +#: lib/pleroma/web/common_api/utils.ex:482 msgid "Too many attachments" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex:33 #: lib/pleroma/web/plugs/user_is_staff_plug.ex:20 msgid "User is not a staff member." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:366 msgid "Your account is awaiting approval." msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:258 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:261 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:264 +msgid "File is too large" +msgstr "" diff --git a/priv/gettext/fr/LC_MESSAGES/config_descriptions.po b/priv/gettext/fr/LC_MESSAGES/config_descriptions.po new file mode 100644 index 000000000..e43db68aa --- /dev/null +++ b/priv/gettext/fr/LC_MESSAGES/config_descriptions.po @@ -0,0 +1,6011 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-22 02:09+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Translate Toolkit 3.7.2\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/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd" +msgid "Before enabling this you must add :esshd to mix.exs as one of the extra_applications and generate host keys in your priv dir with ssh-keygen -m PEM -N \"\" -b 2048 -t rsa -f ssh_host_rsa_key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger" +msgid "Logger-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :mime" +msgid "Mime Types settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma" +msgid "Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack" +msgid "Quack-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug" +msgid "CORS plug config" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd" +msgid "ESSHD" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger" +msgid "Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime" +msgid "Mime Types" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma" +msgid "Pleroma Admin Token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma" +msgid "Pleroma Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack" +msgid "Quack Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:console" +msgid "Console logger settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger" +msgid "ExSyslogger-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub" +msgid "ActivityPub-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth" +msgid "Authentication / authorization settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool" +msgid "Advanced settings for `Gun` connections pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications" +msgid "Email notifications settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:features" +msgid "Customizable features" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed" +msgid "Configure feed rendering" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations" +msgid "This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for pleroma_fe are configured. If you want to add your own configuration your settings all fields must be complete." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends" +msgid "Installed frontends management" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher" +msgid "Gopher settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools" +msgid "Advanced settings for `Hackney` connections pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http" +msgid "HTTP settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security" +msgid "HTTP security settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance" +msgid "Instance-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instances_favicons" +msgid "Control favicons for instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap" +msgid "Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password will be verified by trying to authenticate (bind) to a LDAP server. If a user exists in the LDAP directory but there is no account with the same name yet on the Pleroma instance then a new Pleroma account will be created with the same name as the LDAP user name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:majic_pool" +msgid "Majic/libmagic configuration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:modules" +msgid "Custom Runtime Modules" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf" +msgid "General MRF settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_activity_expiration" +msgid "Adds automatic expiration to all local activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_follow_bot" +msgid "Automatically follows newly discovered accounts." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag" +msgid "Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)\n\nNote: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread" +msgid "Block messages with excessive user mentions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword" +msgid "Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_mention" +msgid "Block messages which mention a specific user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_normalize_markup" +msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age" +msgid "Rejects or delists posts based on their timestamp deviance from your server's clock." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic" +msgid "RejectNonPublic drops posts with non-public visibility settings." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple" +msgid "Simple ingress policies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji" +msgid "Steals emojis from selected instances when it sees them." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary" +msgid "Filter messages which belong to certain activity vocabularies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2" +msgid "Configure OAuth 2 provider capabilities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools" +msgid "Advanced settings for `Gun` workers pools" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit" +msgid "Rate limit settings. This is an advanced feature enabled only for :authentication by default." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated" +msgid "Disallow viewing timelines, user profiles and statuses for unauthenticated users." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media" +msgid "If enabled the instance will parse metadata from attached links to generate link previews" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout" +msgid "Pleroma shout settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:static_fe" +msgid "Render profiles and posts using server-generated HTML that is viewable without using JavaScript" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer" +msgid "Settings for notifications streamer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:uri_schemes" +msgid "URI schemes related settings" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome" +msgid "Welcome messages settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:workers" +msgid "Includes custom worker options not interpretable directly by `Oban`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter" +msgid "Limits configuration for background tasks." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban" +msgid "[Oban](https://github.com/sorentwo/oban) asynchronous job processor configuration." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha" +msgid "Captcha-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Kocaptcha is a very simple captcha service with a single API endpoint, the source code is here: https://github.com/koto-bank/kocaptcha. The default endpoint (https://captcha.kotobank.ch) is hosted by the developer." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer" +msgid "Mailer-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "New users admin email digest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail" +msgid "Email template settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter" +msgid "Configuration for Pleroma's link formatter which parses mentions, hashtags, and URLs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity" +msgid "Scheduled activities settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload" +msgid "Upload general settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename" +msgid "Filter replaces the filename of the upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify" +msgid "Uploads mogrify filter settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local" +msgid "Local uploader-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3" +msgid "S3 uploader-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup" +msgid "Account Backup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http" +msgid "HTTP invalidate settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script" +msgid "Invalidation script settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata" +msgid "Metadata-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Preload" +msgid "Preload-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Expired activities settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" +msgid "Prometheus app metrics endpoint configuration" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3" +msgid "S3" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console" +msgid "Console Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger" +msgid "ExSyslogger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub" +msgid "ActivityPub" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets" +msgid "Assets" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth" +msgid "Auth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool" +msgid "Connections pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications" +msgid "Email notifications" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji" +msgid "Emoji" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:features" +msgid "Features" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed" +msgid "Feed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations" +msgid "Frontend configurations" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends" +msgid "Frontends" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher" +msgid "Gopher" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools" +msgid "Hackney pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http" +msgid "HTTP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security" +msgid "HTTP security" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance" +msgid "Instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instances_favicons" +msgid "Instances favicons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap" +msgid "LDAP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:majic_pool" +msgid "Majic pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest" +msgid "Manifest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup" +msgid "Markup Settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:modules" +msgid "Modules" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf" +msgid "MRF" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_activity_expiration" +msgid "MRF Activity Expiration Policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_follow_bot" +msgid "MRF FollowBot Policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag" +msgid "MRF Hashtag" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread" +msgid "MRF Hellthread" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword" +msgid "MRF Keyword" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_mention" +msgid "MRF Mention" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_normalize_markup" +msgid "MRF Normalize Markup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age" +msgid "MRF Object Age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic" +msgid "MRF Reject Non Public" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple" +msgid "MRF Simple" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji" +msgid "MRF Emojis" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_subchain" +msgid "MRF Subchain" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary" +msgid "MRF Vocabulary" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2" +msgid "OAuth2" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools" +msgid "Pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table" +msgid "Populate hashtags table" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit" +msgid "Rate limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated" +msgid "Restrict Unauthenticated" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media" +msgid "Rich media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout" +msgid "Shout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:static_fe" +msgid "Static FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer" +msgid "Streamer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:uri_schemes" +msgid "URI Schemes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:user" +msgid "User" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl" +msgid "Web cache TTL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome" +msgid "Welcome" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:workers" +msgid "Workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter" +msgid "ConcurrentLimiter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban" +msgid "Oban" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha" +msgid "Pleroma.Captcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Pleroma.Captcha.Kocaptcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer" +msgid "Pleroma.Emails.Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "Pleroma.Emails.NewUsersDigestEmail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail" +msgid "Pleroma.Emails.UserEmail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter" +msgid "Linkify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity" +msgid "Pleroma.ScheduledActivity" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload" +msgid "Pleroma.Upload" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local" +msgid "Pleroma.Uploaders.Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3" +msgid "Pleroma.Uploaders.S3" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User" +msgid "Pleroma.User" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup" +msgid "Pleroma.User.Backup" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata" +msgid "Pleroma.Web.Metadata" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Preload" +msgid "Pleroma.Web.Preload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Pleroma.Workers.PurgeExpiredActivity" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details" +msgid "Vapid Details" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :enabled" +msgid "Enables SSH" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :handler" +msgid "Handler module" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :password_authenticator" +msgid "Authenticator module" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :port" +msgid "Port to connect" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :priv_dir" +msgid "Dir with SSH keys" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :access_key_id" +msgid "S3 access key ID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :host" +msgid "S3 host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :region" +msgid "S3 region (for AWS)" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:console > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger > :format" +msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :blockers_visible" +msgid "Whether a user can see someone who has blocked them" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Following handshake timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :note_replies_output_limit" +msgid "The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :outgoing_blocks" +msgid "Whether to federate blocks to other instances" +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :unfollow_blocked" +msgid "Whether blocks result in people getting unfollowed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:assets > :default_user_avatar" +msgid "URL of the default user avatar" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "OAuth admin scope requirement toggle. If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes). If disabled and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :oauth_consumer_strategies" +msgid "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable. Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\" (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to `lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Number of attempts to acquire the connection from the pool if it is overloaded. Default: 5" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Timeout to acquire a connection from pool. The total max time is this value multiplied by the number of retries. Default: 250ms." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Multiplier for the number of idle connection to be reclaimed if the pool is full. For example if the pool maxes out at 250 connections and this setting is set to 0.3, the pool will reclaim at most 75 idle connections if it's overloaded. Default: 0.1" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest" +msgid "emails of \"what you've missed\" for users who have been inactive for a while" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :active" +msgid "Globally enable or disable digest emails" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Minimum user inactivity threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :interval" +msgid "Minimum interval between digest emails to one user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:emoji > :groups" +msgid "Emojis are ordered in groups (tags). This is an array of key-value pairs where the key is the group name and the value is the location or array of locations. * can be used as a wildcard." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:emoji > :pack_extensions" +msgid "A list of file extensions for emojis, when no emoji.txt for a pack is present" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:features > :improved_hashtag_timeline" +msgid "Setting to force toggle / force disable improved hashtags timeline. `:enabled` forces hashtags to be fetched from `hashtags` table for hashtags timeline. `:disabled` forces object-embedded hashtags to be used (slower). Keep it `:auto` for automatic behaviour (it is auto-set to `:enabled` [unless overridden] when HashtagsTableMigrator completes)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title" +msgid "Configure title rendering" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title > :max_length" +msgid "Maximum number of characters before truncating title" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title > :omission" +msgid "Replacement which will be used after truncating string" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Settings for Pleroma FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "When disabled, auto-hide the subject field if it's empty" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "URL of the background, unless viewing a user profile with a background that is set" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "When a message has a subject (aka Content Warning), collapse it by default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Enables green text on lines prefixed with the > character" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hides filtered statuses from timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hides muted statuses from timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide notices statistics (repeats, favorites, ...)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hides instance name from PleromaFE banner" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide profile statistics (posts, posts per day, followers, followings, ...)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "URL of the logo, defaults to Pleroma's logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Allows you to adjust vertical margins between logo boundary and navbar borders. The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. If you want a colorful logo you must disable logoMask." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Limit scope selection to Direct, User default, and Scope of post replying to. Also prevents replying to a DM with a public post from PleromaFE." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "URL of the image to use for hiding NSFW media attachments in the timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Default post formatting option" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Relative URL which indicates where to redirect when a user is logged in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Relative URL which indicates where to redirect when a user isn't logged in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Copy the scope (private/unlisted/public) in replies to posts by default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Enables panel displaying functionality of the instance on the About page" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Whether to show the instance's custom panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Change alignment of sidebar and panels to the right" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Allows changing the default behaviour of subject lines in replies.\n `email`: copy and preprend re:, as in email,\n `masto`: copy verbatim, as in Mastodon,\n `noop`: don't copy the subject." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Which theme to use. Available themes are defined in styles.json" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :admin" +msgid "Admin frontend" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :admin > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available" +msgid "A map containing available frontends and parameters for their installation." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > build_dir" +msgid "The directory inside the zip file " +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > build_url" +msgid "Either an url to a zip file containing the frontend or a template to build it by inserting the `ref`. The string `${ref}` will be replaced by the configured `ref`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > custom-http-headers" +msgid "The custom HTTP headers for the frontend" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > name" +msgid "Name of the frontend." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > ref" +msgid "Reference of the frontend to be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :primary > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :dstport" +msgid "Port advertised in URLs (optional, defaults to port)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :enabled" +msgid "Enables the gopher interface" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :ip" +msgid "IP address to bind to" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :port" +msgid "Port to bind to" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media" +msgid "Settings for media pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter" +msgid "Adapter specific options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL options for HTTP adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "List of TLS version to use" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :user_agent" +msgid "What user agent to use. Must be a string or an atom `:default`. Default value is `:default`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :ct_max_age" +msgid "The maximum age for the Expect-CT header if sent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :enabled" +msgid "Whether the managed content security policy is enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :referrer_policy" +msgid "The referrer policy to use, either \"same-origin\" or \"no-referrer\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :report_uri" +msgid "Adds the specified URL to report-uri and report-to group in CSP header" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :sts" +msgid "Whether to additionally send a Strict-Transport-Security header" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :sts_max_age" +msgid "The maximum age for the Strict-Transport-Security header if sent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_activation_required" +msgid "Require users to confirm their emails before signing in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_approval_required" +msgid "Require users to be manually approved by an admin before signing in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_field_name_length" +msgid "An account field name maximum length. Default: 512." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_field_value_length" +msgid "An account field value maximum length. Default: 2048." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :allow_relay" +msgid "Permits remote instances to subscribe to all public posts of your instance. (Important!) This may increase the visibility of your instance." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :allowed_post_formats" +msgid "MIME-type list of formats allowed to be posted (transformed into HTML)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :attachment_links" +msgid "Enable to automatically add attachment link text to statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :autofollowed_nicknames" +msgid "Set to nicknames of (local) users that every new user should automatically follow" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :autofollowing_nicknames" +msgid "Set to nicknames of (local) users that automatically follows every newly registered user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :avatar_upload_limit" +msgid "File size limit of user's profile avatars" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :background_upload_limit" +msgid "File size limit of user's profile backgrounds" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :banner_upload_limit" +msgid "File size limit of user's profile banners" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :birthday_min_age" +msgid "Minimum required age for users to create account. Only used if birthday is required." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :birthday_required" +msgid "Require users to enter their birthday." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :cleanup_attachments" +msgid "Enable to remove associated attachments when status is removed.\nThis will not affect duplicates and attachments without status.\nEnabling this will increase load to database when deleting statuses on larger instances.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :description" +msgid "The instance's description. It can be seen in nodeinfo and `/api/v1/instance`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :email" +msgid "Email used to reach an Administrator/Moderator of the instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :extended_nickname_format" +msgid "Enable to use extended local nicknames format (allows underscores/dashes). This will break federation with older software for theses nicknames." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :external_user_synchronization" +msgid "Enabling following/followers counters synchronization for external users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federating" +msgid "Enable federation with other instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Max. depth of reply-to and reply activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Timeout (in days) of each external federation target being unreachable prior to pausing federating to it" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :healthcheck" +msgid "If enabled, system data will be shown on `/api/pleroma/healthcheck`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :instance_thumbnail" +msgid "The instance thumbnail can be any image that represents your instance and is used by some apps or services when they display information about your instance." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :limit" +msgid "Posts character limit (CW/Subject included in the counter)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :limit_to_local_content" +msgid "Limit unauthenticated users to search for local statutes and users only. Default: `:unauthenticated`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_account_fields" +msgid "The maximum number of custom fields in the user profile. Default: 10." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_endorsed_users" +msgid "The maximum number of recommended accounts. 0 will disable the feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_media_attachments" +msgid "Maximum number of post media attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_pinned_statuses" +msgid "The maximum number of pinned statuses. 0 will disable the feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_remote_account_fields" +msgid "The maximum number of custom fields in the remote user profile. Default: 20." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_report_comment_size" +msgid "The maximum size of the report comment. Default: 1000." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi-factor authentication settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "MFA backup codes settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Determines the length of backup one-time pass-codes, in characters. Defaults to 16 characters." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number of backup codes to generate." +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Determines the length of a one-time pass-code, in characters. Defaults to 6 characters." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "A period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :name" +msgid "Name of the instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :notify_email" +msgid "Envelope FROM address for mail sent via Pleroma" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits" +msgid "A map with poll limits for local polls" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Maximum expiration time (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Maximum number of characters per option" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_options" +msgid "Maximum number of options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Minimum expiration time (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :privileged_staff" +msgid "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :profile_directory" +msgid "Enable profile directory." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :public" +msgid "Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note: when setting to `false`, please also check `:restrict_unauthenticated` setting." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :quarantined_instances" +msgid "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :registration_reason_length" +msgid "Maximum registration reason length. Default: 500." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :registrations_open" +msgid "Enable registrations for anyone. Invitations require this setting to be disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :remote_limit" +msgid "Hard character limit beyond which remote posts will be dropped" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :remote_post_retention_days" +msgid "The default amount of days to retain remote posts when pruning the database" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :safe_dm_mentions" +msgid "If enabled, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\"). Default: disabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :show_reactions" +msgid "Let favourites and emoji reactions be viewed through the API." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :skip_thread_containment" +msgid "Skip filtering out broken threads. Default: enabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :static_dir" +msgid "Instance static directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :upload_limit" +msgid "File size limit of uploads (except for avatar, background, banner)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :user_bio_length" +msgid "A user bio maximum length. Default: 5000." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :user_name_length" +msgid "A user name maximum length. Default: 100." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instances_favicons > :enabled" +msgid "Allow/disallow displaying and getting instances favicons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :base" +msgid "LDAP base, e.g. \"dc=example,dc=com\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :enabled" +msgid "Enables LDAP authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :host" +msgid "LDAP server hostname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :port" +msgid "LDAP port, e.g. 389 or 636" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :ssl" +msgid "Enable to use SSL, usually implies the port 636" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts" +msgid "Additional SSL options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tls" +msgid "Enable to use STARTTLS, usually implies the port 389" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts" +msgid "Additional TLS options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :uid" +msgid "LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:majic_pool > :size" +msgid "Number of majic workers to start." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :background_color" +msgid "Describe the background color of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :icons" +msgid "Describe the icons of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :theme_color" +msgid "Describe the theme color of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:markup > :scrub_policy" +msgid "Module names are shortened (removed leading `Pleroma.HTML.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :enabled" +msgid "Enables proxying of remote media preview to the instance's proxy. Requires enabled media proxy." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :image_quality" +msgid "Quality of the output. Ranges from 0 (min quality) to 100 (max quality)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length (in bytes) to perform preview. Media smaller in size will be served without thumbnailing." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Max height of preview thumbnail for images (video preview always has original dimensions)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Max width of preview thumbnail for images (video preview always has original dimensions)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :base_url" +msgid "The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :enabled" +msgid "Enables proxying of remote media via the instance's proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enables media cache object invalidation." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Module which will be used to purge objects from the cache." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts" +msgid "Internal Pleroma.ReverseProxy settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Maximum file size (in bytes) allowed through the Pleroma MediaProxy cache." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Timeout (in milliseconds) of GET request to the remote URI." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirects the client to the origin server upon encountering HTTP errors.\n\nNote that files larger than Max Body Length will trigger an error. (e.g., Peertube videos)\n\n\n**WARNING:** This setting will allow larger files to be accessed, but exposes the\n\nIP addresses of your users to the other servers, bypassing the MediaProxy.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :whitelist" +msgid "List of hosts with scheme to bypass the MediaProxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:modules > :runtime_dir" +msgid "A path to custom Elixir modules (such as MRF policies)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :policies" +msgid "A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :transparency" +msgid "Make the content of your Message Rewrite Facility settings public (via nodeinfo)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :transparency_exclusions" +msgid "Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. You can also provide a reason for excluding these instance names. The instances and reasons won't be publicly disclosed." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_activity_expiration > :days" +msgid "Default global expiration time for all local activities (in days)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "The name of the bot account to use for following newly discovered users." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :reject" +msgid "A list of hashtags which result in message being rejected." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :sensitive" +msgid "A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Number of mentioned users after which the message gets removed from timelines anddisables notifications. Set to 0 to disable." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Number of mentioned users after which the messaged gets rejected. Set to 0 to disable." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid " A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :reject" +msgid " A list of patterns which result in message being rejected.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :replace" +msgid " **Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n\n **Replacement**: a string. Leaving the field empty is permitted.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_mention > :actors" +msgid "A list of actors for which any post mentioning them will be dropped" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age > :actions" +msgid "A list of actions to apply to the post. `:delist` removes the post from public timelines; `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; `:reject` rejects the message entirely" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age > :threshold" +msgid "Required age (in seconds) of a post before actions are taken." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Whether to allow direct messages" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Whether to allow followers-only posts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :accept" +msgid "List of instances to only accept activities from (except deletes) and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :avatar_removal" +msgid "List of instances to strip avatars from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :banner_removal" +msgid "List of instances to strip banners from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "List of instances to remove from the Federated (aka The Whole Known Network) Timeline and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :followers_only" +msgid "Force posts from the given instances to be visible by followers only and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :media_nsfw" +msgid "List of instances to tag all media as NSFW (sensitive) from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :media_removal" +msgid "List of instances to strip media attachments from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :reject" +msgid "List of instances to reject activities from (except deletes) and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :reject_deletes" +msgid "List of instances to reject deletions from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :report_removal" +msgid "List of instances to reject reports from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :hosts" +msgid "List of hosts to steal emojis from" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid " A list of patterns or matches to reject shortcodes with.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "File size limit (in bytes), checked before an emoji is saved to the disk" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_subchain > :match_actor" +msgid "Matches a series of regular expressions against the actor field" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary > :accept" +msgid "A list of ActivityStreams terms to accept. If empty, all supported messages are accepted." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary > :reject" +msgid "A list of ActivityStreams terms to reject. If empty, no messages are rejected." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Enable a background job to clean expired OAuth tokens. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Keeps old refresh token or generate new refresh token when to obtain an access token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :token_expires_in" +msgid "The lifetime in seconds of the access token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default" +msgid "Settings for default pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media" +msgid "Settings for media pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if hashtags transfer failed for all records." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :app_account_creation" +msgid "For registering user accounts from the same IP address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :authentication" +msgid "For authentication create / password check / user existence check requests" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :relation_id_action" +msgid "For actions on relation with a specific user (follow, unfollow)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :relations_actions" +msgid "For actions on relationships with all users (follow, unfollow)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :search" +msgid "For the search requests (account & status search etc.)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :status_id_action" +msgid "For fav / unfav or reblog / unreblog actions on the same status by the same user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :statuses_actions" +msgid "For create / delete / fav / unfav / reblog / unreblog actions on any statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :timeline" +msgid "For requests to timelines (each timeline has it's own limiter)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities" +msgid "Settings for statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Disallow view local statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Disallow view remote statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Settings for user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Disallow view local user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Disallow view remote user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Settings for public and federated timelines." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Disallow view federated timeline." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Disallow view public timeline." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :enabled" +msgid "Enables RichMedia parsing of URLs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :failure_backoff" +msgid "Amount of milliseconds after request failure, during which the request will not be retried." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ignore_hosts" +msgid "List of hosts which will be ignored by the metadata parser" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ignore_tld" +msgid "List TLDs (top-level domains) which will ignore for parse metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :parsers" +msgid "List of Rich Media parsers. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parsers.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ttl_setters" +msgid "List of rich media TTL setters. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parser.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout > :enabled" +msgid "Enables the backend Shoutbox chat feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout > :limit" +msgid "Shout message character limit." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:static_fe > :enabled" +msgid "Enables the rendering of static HTML. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer > :overflow_workers" +msgid "Maximum number of workers created if pool is empty" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer > :workers" +msgid "Number of workers to send notifications" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:uri_schemes > :valid_schemes" +msgid "List of the scheme part that is considered valid to be an URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub routes (except question activities). Default: `nil` (no expiration)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub routes (question activities). Default: `30_000` (30 seconds)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enables sending a chat message to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :message" +msgid "A message that will be sent to newly registered users as a chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enables sending a direct message to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :message" +msgid "A message that will be sent to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :enabled" +msgid "Enables sending an email to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :html" +msgid "HTML content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :sender" +msgid "Email address and/or nickname that will be used to send the welcome email." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :subject" +msgid "Subject of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :text" +msgid "Text content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:workers > :retries" +msgid "Max retry attempts for failed jobs, per `Oban` queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Concurrent limits configuration for MediaProxyWarmingPolicy." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Concurrent limits configuration for getting RichMedia for activities." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :crontab" +msgid "Settings for cron background jobs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :log" +msgid "Logs verbose mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues" +msgid "Background jobs queues (keys: queues, values: max numbers of concurrent jobs)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachment deletion queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :background" +msgid "Background queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :backup" +msgid "Backup queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :federator_incoming" +msgid "Incoming federation queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Outgoing federation queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :mailer" +msgid "Email sender queue, see Pleroma.Emails.Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities queue, see Pleroma.ScheduledActivities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :web_push" +msgid "Web push notifications queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :enabled" +msgid "Whether the captcha should be shown on registration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :method" +msgid "The method/service to use for captcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "The time in seconds for which the captcha is valid" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "The kocaptcha endpoint to use" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "One of the mail adapters listed in [Swoosh documentation](https://hexdocs.pm/swoosh/Swoosh.html#module-adapters)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "SMTP AUTH enforcement mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "SMTP AUTH password" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "SMTP port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Hostname or IP address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "SMTP temporary (4xx) error retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use Implicit SSL/TLS. e.g. port 465" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "Explicit TLS (STARTTLS) enforcement mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "SMTP AUTH username" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enables new users admin digest email when `true`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "A path to a custom logo. Set it to `nil` to use the default Pleroma logo." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "A map with color settings for email templates." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :class" +msgid "Specify the class to be added to the generated link. Disable to clear." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :extra" +msgid "Link URLs with rarely used schemes (magnet, ipfs, irc, etc.)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :new_window" +msgid "Link URLs will open in a new window/tab." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :rel" +msgid "Override the rel attribute. Disable to clear." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip the scheme prefix." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :truncate" +msgid "Set to a number to truncate URLs longer than the number. Truncated URLs will end in `...`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Set to false to disable TLD validation for URLs/emails. Can be set to :no_scheme to validate TLDs only for URLs without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "The number of scheduled activities a user is allowed to create in a single day. Default: 25." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Whether scheduled activities are sent to the job queue to be executed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "The number of scheduled activities a user is allowed to create in total. Default: 300." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL for the uploads. Required if you use a CDN or host attachments under a different domain." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Set max length of a filename to display. 0 = no limit. Default: 30" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :filters" +msgid "List of filter modules for uploads. Module names are shortened (removed leading `Pleroma.Upload.Filter.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :link_name" +msgid "If enabled, a name parameter will be added to the URL of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy requests to the remote uploader.\n\nUseful if media upload endpoint is not internet accessible.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :uploader" +msgid "Module which will be used for uploads" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text to replace filenames in links. If no setting, {random}.extension will be used. You can get the original filename extension by using {extension}, for example custom-file-name.{extension}." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "List of actions for the mogrify command. It's possible to add self-written settings as string. For example `auto-orient, strip, {\"resize\", \"3840x1080>\"}` value will be parsed into valid list of the settings." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Path where user's uploads will be saved" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "S3 bucket" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "S3 bucket namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc. For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in Upload base_url." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User > :email_blacklist" +msgid "List of email domains users may not register with." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "List of nicknames users may not register with." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit user to export not more often than once per N days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Remove backup achives after N days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Enables strict input validation (useful in development, not recommended in production)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "HTTP headers of request" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "HTTP method of request. Default: :purge" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Request options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Path to executable script which will purge cached items." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "Optional URL format preprocessing. Only required for Apache's htcacheclean." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "List of metadata providers to enable" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "When enabled NSFW attachments will be shown in previews" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enable/disable the plug. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid " A list of strings naming the HTTP headers to use when deriving the true client IP. Default: `[\"x-forwarded-for\"]`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "A list of upstream proxy IP subnets in CIDR notation from which we will parse the content of `headers`. Defaults to `[]`. IPv4 entries without a bitmask will be assumed to be /32 and IPv6 /128." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid " A list of reserved IP subnets in CIDR notation which should be ignored if found in `headers`. Defaults to `[\"127.0.0.0/8\", \"::1/128\", \"fc00::/7\", \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"]`\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Preload > :providers" +msgid "List of preload providers to enable" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enables expired activities addition & deletion" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Minimum lifetime for ephemeral activity (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Enables HTTP Basic Auth for app metrics endpoint." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "[Pleroma extension] Enables app metrics endpoint." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "App metrics endpoint output format." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "Restrict access of app metrics endpoint to the specified IP addresses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "App metrics endpoint URI path." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :meta" +msgid "Configure which metadata you want to report on" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :webhook_url" +msgid "Configure the Slack incoming webhook" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :private_key" +msgid "VAPID private key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :public_key" +msgid "VAPID public key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :subject" +msgid "A mailto link for the administrative contact. It's best if this email is not a personal email address, but rather a group email to the instance moderation team." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :credentials" +msgid "Credentials" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :expose" +msgid "Expose" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :max_age" +msgid "Max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :methods" +msgid "Methods" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :handler" +msgid "Handler" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :password_authenticator" +msgid "Password authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :priv_dir" +msgid "Priv dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :access_key_id" +msgid "Access key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :host" +msgid "Host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :region" +msgid "Region" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :secret_access_key" +msgid "Secret access key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger > :backends" +msgid "Backends" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :metadata" +msgid "Metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :ident" +msgid "Ident" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :metadata" +msgid "Metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types" +msgid "Types" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/activity+json" +msgid "\"application/activity+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/jrd+json" +msgid "\"application/jrd+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/ld+json" +msgid "\"application/ld+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/xml" +msgid "\"application/xml\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/xrd+xml" +msgid "\"application/xrd+xml\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma > Pleroma.Web.Auth.Authenticator" +msgid "Pleroma.Web.Auth.Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :blockers_visible" +msgid "Blockers visible" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Follow handshake timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :note_replies_output_limit" +msgid "Note replies output limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :outgoing_blocks" +msgid "Outgoing blocks" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :sign_object_fetches" +msgid "Sign object fetches" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :unfollow_blocked" +msgid "Unfollow blocked" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :default_mascot" +msgid "Default mascot" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :default_user_avatar" +msgid "Default user avatar" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :mascots" +msgid "Mascots" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :auth_template" +msgid "Auth template" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "Enforce OAuth admin scope usage" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :oauth_consumer_strategies" +msgid "OAuth consumer strategies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer template" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connect_timeout" +msgid "Connect timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Connection acquisition retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Connection acquisition wait" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Reclaim multiplier" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest" +msgid "Digest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :active" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Inactivity threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :interval" +msgid "Interval" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :schedule" +msgid "Schedule" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :default_manifest" +msgid "Default manifest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :groups" +msgid "Groups" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :pack_extensions" +msgid "Pack extensions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :shared_pack_cache_seconds_per_file" +msgid "Shared pack cache s/file" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :shortcode_globs" +msgid "Shortcode globs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:features > :improved_hashtag_timeline" +msgid "Improved hashtag timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title" +msgid "Post title" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title > :max_length" +msgid "Max length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title > :omission" +msgid "Omission" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Pleroma FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "Always show subject input" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "Background" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "Collapse message with subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Greentext" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hide Filtered Statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hide Muted Posts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide post stats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hide Sitename" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide user stats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "Logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Logo margin" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "Logo mask" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Minimal scopes mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "NSFW Censor Image" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Post Content Type" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Redirect root login" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Redirect root no login" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Scope copy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Show instance features panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Show instance specific panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Sidebar on Right" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Subject line behavior" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Theme" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin" +msgid "Admin" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available" +msgid "Available" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > build_dir" +msgid "Build directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > build_url" +msgid "Build URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > custom-http-headers" +msgid "Custom HTTP headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > git" +msgid "Git Repository URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary" +msgid "Primary" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :dstport" +msgid "Dstport" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :ip" +msgid "IP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation" +msgid "Federation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media" +msgid "Media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload" +msgid "Upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter" +msgid "Adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "Versions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :send_user_agent" +msgid "Send user agent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :user_agent" +msgid "User agent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :ct_max_age" +msgid "CT max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :referrer_policy" +msgid "Referrer policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :report_uri" +msgid "Report URI" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :sts" +msgid "STS" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :sts_max_age" +msgid "STS max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_activation_required" +msgid "Account activation required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_approval_required" +msgid "Account approval required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_field_name_length" +msgid "Account field name length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_field_value_length" +msgid "Account field value length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :allow_relay" +msgid "Allow relay" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :allowed_post_formats" +msgid "Allowed post formats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :attachment_links" +msgid "Attachment links" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :autofollowed_nicknames" +msgid "Autofollowed nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :autofollowing_nicknames" +msgid "Autofollowing nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :avatar_upload_limit" +msgid "Avatar upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :background_upload_limit" +msgid "Background upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :banner_upload_limit" +msgid "Banner upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :birthday_min_age" +msgid "Birthday min age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :birthday_required" +msgid "Birthday required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :cleanup_attachments" +msgid "Cleanup attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :description" +msgid "Description" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :email" +msgid "Admin Email Address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :extended_nickname_format" +msgid "Extended nickname format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :external_user_synchronization" +msgid "External user synchronization" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federating" +msgid "Federating" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Fed. incoming replies max depth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Fed. reachability timeout days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :healthcheck" +msgid "Healthcheck" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :instance_thumbnail" +msgid "Instance thumbnail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :invites_enabled" +msgid "Invites enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :limit" +msgid "Limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :limit_to_local_content" +msgid "Limit to local content" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_account_fields" +msgid "Max account fields" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_endorsed_users" +msgid "Max endorsed users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_media_attachments" +msgid "Max media attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_pinned_statuses" +msgid "Max pinned statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_remote_account_fields" +msgid "Max remote account fields" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_report_comment_size" +msgid "Max report comment size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi factor authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "Backup codes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp" +msgid "TOTP settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Digits" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "Period" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :notify_email" +msgid "Sender Email Address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits" +msgid "Poll limits" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Max expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Max option chars" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_options" +msgid "Max options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Min expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :privileged_staff" +msgid "Privileged staff" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :profile_directory" +msgid "Profile directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :public" +msgid "Public" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :quarantined_instances" +msgid "Quarantined instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :registration_reason_length" +msgid "Registration reason length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :registrations_open" +msgid "Registrations open" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :remote_limit" +msgid "Remote limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :remote_post_retention_days" +msgid "Remote post retention days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :safe_dm_mentions" +msgid "Safe DM mentions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :show_reactions" +msgid "Show reactions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :skip_thread_containment" +msgid "Skip thread containment" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :static_dir" +msgid "Static dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :upload_limit" +msgid "Upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :user_bio_length" +msgid "User bio length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :user_name_length" +msgid "User name length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instances_favicons > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :base" +msgid "Base" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :host" +msgid "Host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :ssl" +msgid "SSL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts" +msgid "SSL options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts > :verify" +msgid "Verify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tls" +msgid "TLS" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts" +msgid "TLS options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts > :verify" +msgid "Verify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :uid" +msgid "UID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:majic_pool > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :background_color" +msgid "Background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :icons" +msgid "Icons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :theme_color" +msgid "Theme color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_fonts" +msgid "Allow fonts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_headings" +msgid "Allow headings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_inline_images" +msgid "Allow inline images" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_tables" +msgid "Allow tables" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :image_quality" +msgid "Image quality" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Thumbnail max height" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Thumbnail max width" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :base_url" +msgid "Base URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation" +msgid "Invalidation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Provider" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts" +msgid "Advanced MediaProxy Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Max body length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Max read duration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirect on failure" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :whitelist" +msgid "Whitelist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:modules > :runtime_dir" +msgid "Runtime dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :policies" +msgid "Policies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :transparency" +msgid "MRF transparency" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :transparency_exclusions" +msgid "MRF transparency exclusions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_activity_expiration > :days" +msgid "Days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "Follower nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :sensitive" +msgid "Sensitive" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Delist threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Reject threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :replace" +msgid "Replace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_mention > :actors" +msgid "Actors" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_normalize_markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age > :actions" +msgid "Actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age > :threshold" +msgid "Threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Allow direct" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Allow followers-only" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :accept" +msgid "Accept" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :avatar_removal" +msgid "Avatar removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :banner_removal" +msgid "Banner removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :followers_only" +msgid "Followers only" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :media_nsfw" +msgid "Media NSFW" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :media_removal" +msgid "Media removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :reject_deletes" +msgid "Reject deletes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :report_removal" +msgid "Report removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :hosts" +msgid "Hosts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid "Rejected shortcodes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "Size limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_subchain > :match_actor" +msgid "Match actor" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary > :accept" +msgid "Accept" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Clean expired tokens" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Issue new refresh token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :token_expires_in" +msgid "Token expires in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default" +msgid "Default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation" +msgid "Federation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media" +msgid "Media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload" +msgid "Upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :app_account_creation" +msgid "App account creation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :authentication" +msgid "Authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :relation_id_action" +msgid "Relation ID action" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :relations_actions" +msgid "Relations actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :search" +msgid "Search" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :status_id_action" +msgid "Status ID action" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :statuses_actions" +msgid "Statuses actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :timeline" +msgid "Timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities" +msgid "Activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Profiles" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Federated" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :failure_backoff" +msgid "Failure backoff" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ignore_hosts" +msgid "Ignore hosts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ignore_tld" +msgid "Ignore TLD" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :parsers" +msgid "Parsers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ttl_setters" +msgid "TTL setters" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout > :limit" +msgid "Limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:static_fe > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer > :overflow_workers" +msgid "Overflow workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer > :workers" +msgid "Workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:uri_schemes > :valid_schemes" +msgid "Valid schemes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:user > :deny_follow_blocked" +msgid "Deny follow blocked" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub question" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message" +msgid "Chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :message" +msgid "Message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message" +msgid "Direct message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :message" +msgid "Message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email" +msgid "Email" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :html" +msgid "Html" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :sender" +msgid "Sender" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :subject" +msgid "Subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :text" +msgid "Text" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:workers > :retries" +msgid "Retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Pleroma.Web.RichMedia.Helpers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :crontab" +msgid "Crontab" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :log" +msgid "Log" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues" +msgid "Queues" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachments cleanup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :background" +msgid "Background" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :backup" +msgid "Backup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :federator_incoming" +msgid "Federator incoming" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Federator outgoing" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :mailer" +msgid "Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :web_push" +msgid "Web push" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :method" +msgid "Method" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "Seconds valid" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "Endpoint" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "Adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :enabled" +msgid "Mailer Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:access_key" +msgid "AWS Access Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:region" +msgid "AWS Region" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:secret" +msgid "AWS Secret Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Dyn-:api_key" +msgid "Dyn API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Gmail-:access_token" +msgid "GMail API Access Token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:api_key" +msgid "Mailgun API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:domain" +msgid "Domain" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:api_key" +msgid "MailJet Public API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:secret" +msgid "MailJet Private API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mandrill-:api_key" +msgid "Mandrill API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Postmark-:api_key" +msgid "Postmark API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "AUTH Mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "Password" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Relay" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "Retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use SSL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "STARTTLS Mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "Username" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendgrid-:api_key" +msgid "SendGrid API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_args" +msgid "Cmd args" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_path" +msgid "Cmd path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:qmail" +msgid "Qmail compat mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:api_key" +msgid "SocketLabs API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:server_id" +msgid "Server ID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:api_key" +msgid "SparkPost API key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:endpoint" +msgid "Endpoint" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "Logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "Styling" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :background_color" +msgid "Background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :content_background_color" +msgid "Content background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :header_color" +msgid "Header color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :link_color" +msgid "Link color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_color" +msgid "Text color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_muted_color" +msgid "Text muted color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :class" +msgid "Class" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :extra" +msgid "Extra" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :new_window" +msgid "New window" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :rel" +msgid "Rel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip prefix" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :truncate" +msgid "Truncate" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Validate tld" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "Daily user limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "Total user limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Filename display max length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :filters" +msgid "Filters" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :link_name" +msgid "Link name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :uploader" +msgid "Uploader" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "Args" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Uploads" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "Bucket" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "Bucket namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Streaming enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "Truncated namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User > :email_blacklist" +msgid "Email blacklist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "Restricted nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Purge after days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Strict" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "Method" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options > :params" +msgid "Params" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Script path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "URL Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "Providers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "Unfurl NSFW" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "Proxies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid "Reserved" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Preload > :providers" +msgid "Providers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Min lifetime" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Auth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "IP Whitelist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "Path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :meta" +msgid "Meta" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :webhook_url" +msgid "Webhook URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :private_key" +msgid "Private key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :public_key" +msgid "Public key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :subject" +msgid "Subject" +msgstr "" diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po new file mode 100644 index 000000000..36112e754 --- /dev/null +++ b/priv/gettext/fr/LC_MESSAGES/default.po @@ -0,0 +1,212 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-21 23:42+0300\n" +"PO-Revision-Date: 2022-07-22 19:00+0000\n" +"Last-Translator: Haelwenn \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\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 as no +## effect: edit them in PO (.po) files instead. +#: lib/pleroma/web/api_spec/render_error.ex:122 +#, elixir-autogen, elixir-format +msgid "%{name} - %{count} is not a multiple of %{multiple}." +msgstr "%{name} - %{count} n'est pas un multiple de %{multiple}." + +#: lib/pleroma/web/api_spec/render_error.ex:131 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than exclusive maximum %{max}." +msgstr "%{name} - %{value} est plus large que %{max}." + +#: lib/pleroma/web/api_spec/render_error.ex:140 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than inclusive maximum %{max}." +msgstr "%{name} - %{value} est plus large que %{max}." + +#: lib/pleroma/web/api_spec/render_error.ex:149 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than exclusive minimum %{min}." +msgstr "%{name} - %{value} est plus petit que %{min}." + +#: lib/pleroma/web/api_spec/render_error.ex:158 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than inclusive minimum %{min}." +msgstr "%{name} - %{value} est plus petit que %{min}." + +#: lib/pleroma/web/api_spec/render_error.ex:102 +#, elixir-autogen, elixir-format +msgid "%{name} - Array items must be unique." +msgstr "%{name} - Les objects de la liste doivent être uniques." + +#: lib/pleroma/web/api_spec/render_error.ex:114 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is larger than maxItems: %{}." +msgstr "" +"%{name} - La longueur %{length} de la liste est supérieure à maxItems : %{}." + +#: lib/pleroma/web/api_spec/render_error.ex:106 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is smaller than minItems: %{min}." +msgstr "" +"%{name} - La longueur %{length} de la liste est inférieure à minItems : " +"%{min}." + +#: lib/pleroma/web/api_spec/render_error.ex:166 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid %{type}. Got: %{value}." +msgstr "%{name} - %{type} invalide. Reçu : %{value}." + +#: lib/pleroma/web/api_spec/render_error.ex:174 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid format. Expected %{format}." +msgstr "%{name} - Format invalide. Format voulu : %{format}." + +#: lib/pleroma/web/api_spec/render_error.ex:51 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid schema.type. Got: %{type}." +msgstr "%{name} - schema.type invalide. Reçu : %{type}." + +#: lib/pleroma/web/api_spec/render_error.ex:178 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid value for enum." +msgstr "%{name} - valeur invalide pour enum." + +#: lib/pleroma/web/api_spec/render_error.ex:95 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is larger than maxLength: %{length}." +msgstr "" +"%{name} - Longueur de chaine de caractères supérieure à maxLength : " +"%{length}." + +#: lib/pleroma/web/api_spec/render_error.ex:88 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is smaller than minLength: %{length}." +msgstr "" +"%{name} - Longueur de chaine de caractères inférieure à minLength : " +"%{length}." + +#: lib/pleroma/web/api_spec/render_error.ex:63 +#, elixir-autogen, elixir-format +msgid "%{name} - null value where %{type} expected." +msgstr "%{name} - valeur nulle quand %{type} est requis." + +#: lib/pleroma/web/api_spec/render_error.ex:60 +#, elixir-autogen, elixir-format +msgid "%{name} - null value." +msgstr "%{name} - valeur nulle." + +#: lib/pleroma/web/api_spec/render_error.ex:182 +#, elixir-autogen, elixir-format +msgid "Failed to cast to any schema in %{polymorphic_type}" +msgstr "Échec de transformation du schéma en %{polymorphic_type}" + +#: lib/pleroma/web/api_spec/render_error.ex:71 +#, elixir-autogen, elixir-format +msgid "Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed." +msgstr "" +"Échec de transformation de la valeur en %{invalid_schema}. La valeur doit " +"être transformable dans un des schémas `allOf` listés." + +#: lib/pleroma/web/api_spec/render_error.ex:84 +#, elixir-autogen, elixir-format +msgid "Failed to cast value to one of: %{failed_schemas}." +msgstr "Échec de transformation de la valeur en un des : %{failed_schemas}." + +#: lib/pleroma/web/api_spec/render_error.ex:78 +#, elixir-autogen, elixir-format +msgid "Failed to cast value using any of: %{failed_schemas}." +msgstr "Échec de transformation de la valeur en un des : %{failed_schemas}." + +#: lib/pleroma/web/api_spec/render_error.ex:212 +#, elixir-autogen, elixir-format +msgid "Invalid value for header: %{name}." +msgstr "Valeur invalide pour l'en-tête : %{name}." + +#: lib/pleroma/web/api_spec/render_error.ex:204 +#, elixir-autogen, elixir-format +msgid "Missing field: %{name}." +msgstr "Champ manquant : %{name}." + +#: lib/pleroma/web/api_spec/render_error.ex:208 +#, elixir-autogen, elixir-format +msgid "Missing header: %{name}." +msgstr "En-tête manquant : %{name}." + +#: lib/pleroma/web/api_spec/render_error.ex:196 +#, elixir-autogen, elixir-format +msgid "No value provided for required discriminator `%{field}`." +msgstr "Aucune valeur fournie pour le discriminant `%{field}`." + +#: lib/pleroma/web/api_spec/render_error.ex:216 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." +msgstr "" +"Le nombre de propriétés, %{property_count} est supérieur à maxProperties : " +"%{max_properties}." + +#: lib/pleroma/web/api_spec/render_error.ex:224 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" +msgstr "" +"Le nombre de propriétés, %{property_count} est inférieur à minProperties : " +"%{min_properties}" + +#: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 +#, elixir-autogen, elixir-format +msgid "Oops" +msgstr "Oups" + +#: lib/pleroma/web/api_spec/render_error.ex:188 +#, elixir-autogen, elixir-format +msgid "Unexpected field: %{name}." +msgstr "Champ inconnu : %{name}." + +#: lib/pleroma/web/api_spec/render_error.ex:200 +#, elixir-autogen, elixir-format +msgid "Unknown schema: %{name}." +msgstr "Schéma inconnu : %{name}." + +#: lib/pleroma/web/api_spec/render_error.ex:192 +#, elixir-autogen, elixir-format +msgid "Value used as discriminator for `%{field}` matches no schemas." +msgstr "" +"Valeur utilisée en discriminant de `%{field}` ne correspond à aucun schémas." + +#: lib/pleroma/web/templates/embed/show.html.eex:43 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 +#, elixir-autogen, elixir-format +msgid "announces" +msgstr "annonces" + +#: lib/pleroma/web/templates/embed/show.html.eex:44 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:38 +#, elixir-autogen, elixir-format +msgid "likes" +msgstr "favoris" + +#: lib/pleroma/web/templates/embed/show.html.eex:42 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:36 +#, elixir-autogen, elixir-format +msgid "replies" +msgstr "réponses" + +#: lib/pleroma/web/templates/embed/show.html.eex:27 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:22 +#, elixir-autogen, elixir-format +msgid "sensitive media" +msgstr "contenu sensible" diff --git a/priv/gettext/fr/LC_MESSAGES/posix_errors.po b/priv/gettext/fr/LC_MESSAGES/posix_errors.po new file mode 100644 index 000000000..ba8169dda --- /dev/null +++ b/priv/gettext/fr/LC_MESSAGES/posix_errors.po @@ -0,0 +1,165 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-22 02:09+0300\n" +"PO-Revision-Date: 2022-07-21 23:35+0000\n" +"Last-Translator: Haelwenn \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\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 as no +## effect: edit them in PO (`.po`) files instead. +msgid "eperm" +msgstr "Opération non permise" + +msgid "eacces" +msgstr "Permission refusée" + +msgid "eagain" +msgstr "Ressource temporairement indisponible" + +msgid "ebadf" +msgstr "Mauvais descripteur de fichier" + +msgid "ebadmsg" +msgstr "Mauvais message" + +msgid "ebusy" +msgstr "Périphérique ou ressource occupée" + +msgid "edeadlk" +msgstr "Interblocage des ressources évité" + +msgid "edeadlock" +msgstr "Interblocage des ressources évité" + +msgid "edquot" +msgstr "Quota disque dépassé" + +msgid "eexist" +msgstr "Fichier existant" + +msgid "efault" +msgstr "Mauvaise addresse" + +msgid "efbig" +msgstr "Fichier trop gros" + +msgid "eftype" +msgstr "Type ou format de fichier inapproprié" + +msgid "eintr" +msgstr "Appel système interrompu" + +msgid "einval" +msgstr "Argument invalide" + +msgid "eio" +msgstr "Erreur entrée/sortie" + +msgid "eisdir" +msgstr "Opération non-permise sur un répertoire" + +msgid "eloop" +msgstr "Trop de niveau de liens symboliques" + +msgid "emfile" +msgstr "Trop de fichiers ouverts" + +msgid "emlink" +msgstr "Trop de liens" + +msgid "emultihop" +msgstr "Multi-saut essayé" + +msgid "enametoolong" +msgstr "Nom de fichier trop long" + +msgid "enfile" +msgstr "Trop de fichier ouvert dans le système" + +msgid "enobufs" +msgstr "Pas d'espace tampon disponible" + +msgid "enodev" +msgstr "Périphérique inexistant" + +msgid "enolck" +msgstr "Pas de verrous disponibles" + +msgid "enolink" +msgstr "Lien rompus" + +msgid "enoent" +msgstr "Fichier ou dossier non trouvé" + +msgid "enomem" +msgstr "Échec d'allocation mémoire" + +msgid "enospc" +msgstr "Plus de place disponible sur le périphérique" + +msgid "enosr" +msgstr "Plus de flux disponibles" + +msgid "enostr" +msgstr "Périphérique qui n'est pas un flux" + +msgid "enosys" +msgstr "Fonction non implémentée" + +msgid "enotblk" +msgstr "Périphérique bloc requis" + +msgid "enotdir" +msgstr "Pas un répertoire" + +msgid "enotsup" +msgstr "Opération non supportée" + +msgid "enxio" +msgstr "Addresse de périphérique inconnue" + +msgid "eopnotsupp" +msgstr "Opération non supportée" + +msgid "eoverflow" +msgstr "Valeur trop grande pour le type de donnée definit" + +msgid "epipe" +msgstr "Tuyaux rompu" + +msgid "erange" +msgstr "Valeur numérique hors de l'interval" + +msgid "erofs" +msgstr "Système de fichier en lecture-seule" + +msgid "espipe" +msgstr "Déplacement interdit" + +msgid "esrch" +msgstr "Processus inexistant" + +msgid "estale" +msgstr "Descripteur de fichier bouché" + +msgid "etxtbsy" +msgstr "Fichier texte occupé" + +msgid "exdev" +msgstr "Lien inter-périphérique invalide" diff --git a/priv/gettext/fr/LC_MESSAGES/static_pages.po b/priv/gettext/fr/LC_MESSAGES/static_pages.po new file mode 100644 index 000000000..afcaac826 --- /dev/null +++ b/priv/gettext/fr/LC_MESSAGES/static_pages.po @@ -0,0 +1,564 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-21 23:03+0300\n" +"PO-Revision-Date: 2022-07-21 20:44+0000\n" +"Last-Translator: Haelwenn \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\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 as no +## effect: edit them in PO (.po) files instead. +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button" +msgid "Authorize" +msgstr "Autoriser" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "remote follow error" +msgid "Error fetching user" +msgstr "Erreur de requête au compte" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow header" +msgid "Remote follow" +msgstr "Suivit distant" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for auth code entry" +msgid "Authentication code" +msgstr "Code d'Authentification" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:10 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for password entry" +msgid "Password" +msgstr "Mot de passe" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for username entry" +msgid "Username" +msgstr "Nom d'utilisateur·rice" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:13 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button for login" +msgid "Authorize" +msgstr "Autoriser" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button for mfa" +msgid "Authorize" +msgstr "Autoriser" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "remote follow error" +msgid "Error following account" +msgstr "Erreur de suivi du compte" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow header, need login" +msgid "Log in to follow" +msgstr "Authentification pour le suivit" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow mfa header" +msgid "Two-factor authentication" +msgstr "Authentification à deux facteurs" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow success" +msgid "Account followed!" +msgstr "Utilisateur·rice suivi·e !" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:7 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for account id" +msgid "Your account ID, e.g. lain@quitter.se" +msgstr "Votre identifiant, ex. lain@quitter.se" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button for following with a remote account" +msgid "Follow" +msgstr "Suivre" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "remote follow error" +msgid "Error: %{error}" +msgstr "Erreur : %{error}" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow header" +msgid "Remotely follow %{nickname}" +msgstr "Suivre %{nickname} à distance" + +#: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "password reset button" +msgid "Reset" +msgstr "Changer" + +#: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "password reset failed homepage link" +msgid "Homepage" +msgstr "Page d'accueil" + +#: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "password reset failed message" +msgid "Password reset failed" +msgstr "Échec de changement du mot de passe" + +#: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "password reset form confirm password prompt" +msgid "Confirmation" +msgstr "Confirmation" + +#: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "password reset form password prompt" +msgid "Password" +msgstr "Mot de passe" + +#: lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "password reset invalid token message" +msgid "Invalid Token" +msgstr "Jeton invalide" + +#: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "password reset successful homepage link" +msgid "Homepage" +msgstr "Page d'accueil" + +#: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "password reset successful message" +msgid "Password changed!" +msgstr "Mot de passe changé !" + +#: lib/pleroma/web/templates/feed/feed/tag.atom.eex:15 +#: lib/pleroma/web/templates/feed/feed/tag.rss.eex:7 +#, elixir-autogen, elixir-format +msgctxt "tag feed description" +msgid "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse." +msgstr "" +"Ceci sont des messages publics lié à #%{tag}. Vous pouvez intéragir avec si " +"vous avez un compte sur le Fediverse." + +#: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "oauth authorization exists page title" +msgid "Authorization exists" +msgstr "Autorisation existante" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:32 +#, elixir-autogen, elixir-format +msgctxt "oauth authorize approve button" +msgid "Approve" +msgstr "Approuver" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:30 +#, elixir-autogen, elixir-format +msgctxt "oauth authorize cancel button" +msgid "Cancel" +msgstr "Annuler" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:23 +#, elixir-autogen, elixir-format +msgctxt "oauth authorize message" +msgid "Application %{client_name} is requesting access to your account." +msgstr "" +"L'application %{client_name} demande un accès à votre " +"compte." + +#: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "oauth authorized page title" +msgid "Successfully authorized" +msgstr "Autorisé avec succès" + +#: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "oauth external provider page title" +msgid "Sign in with external provider" +msgstr "Authentication externe" + +#: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:13 +#, elixir-autogen, elixir-format +msgctxt "oauth external provider sign in button" +msgid "Sign in with %{strategy}" +msgstr "Authentification avec %{strategy}" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:54 +#, elixir-autogen, elixir-format +msgctxt "oauth login button" +msgid "Log In" +msgstr "Authentification" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:51 +#, elixir-autogen, elixir-format +msgctxt "oauth login password prompt" +msgid "Password" +msgstr "Mot de passe" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:47 +#, elixir-autogen, elixir-format +msgctxt "oauth login username prompt" +msgid "Username" +msgstr "Nom d'utilisateur·rice" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:39 +#, elixir-autogen, elixir-format +msgctxt "oauth register nickname prompt" +msgid "Pleroma Handle" +msgstr "Pseudo Pleroma" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:37 +#, elixir-autogen, elixir-format +msgctxt "oauth register nickname unchangeable warning" +msgid "Choose carefully! You won't be able to change this later. You will be able to change your display name, though." +msgstr "" +"Faites attention ! Vous ne pourrez plus le changer plus tard. Mais, vous " +"pourrez changer votre Nom." + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:18 +#, elixir-autogen, elixir-format +msgctxt "oauth register page email prompt" +msgid "Email" +msgstr "Courriel" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:10 +#, elixir-autogen, elixir-format +msgctxt "oauth register page fill form prompt" +msgid "If you'd like to register a new account, please provide the details below." +msgstr "Si vous voulez créer un compte, veuillez fournir les détails suivants." + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:35 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login button" +msgid "Proceed as existing user" +msgstr "Continuer avec un compte existant" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:31 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login password prompt" +msgid "Password" +msgstr "Mot de passe" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:24 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login prompt" +msgid "Alternatively, sign in to connect to existing account." +msgstr "Alternativement, s'authentifier avec un compte existant." + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:27 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login username prompt" +msgid "Name or email" +msgstr "Nom ou courriel" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:14 +#, elixir-autogen, elixir-format +msgctxt "oauth register page nickname prompt" +msgid "Nickname" +msgstr "Pseudonyme" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:22 +#, elixir-autogen, elixir-format +msgctxt "oauth register page register button" +msgid "Proceed as new user" +msgstr "Continuer avec un nouveau compte" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "oauth register page title" +msgid "Registration Details" +msgstr "Détails d'inscriptions" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:36 +#, elixir-autogen, elixir-format +msgctxt "oauth register page title" +msgid "This is the first time you visit! Please enter your Pleroma handle." +msgstr "Ceci est votre première visite ! Veuillez entrer votre pseudo." + +#: lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "oauth scopes message" +msgid "The following permissions will be granted" +msgstr "Les permissions suivantes seront données" + +#: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:2 +#: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "oauth token code message" +msgid "Token code is
%{token}" +msgstr "Le jeton est
%{token}" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "mfa auth code prompt" +msgid "Authentication code" +msgstr "Code d'authentification" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "mfa auth page title" +msgid "Two-factor authentication" +msgstr "Authentification à double-facteurs" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:23 +#, elixir-autogen, elixir-format +msgctxt "mfa auth page use recovery code link" +msgid "Enter a two-factor recovery code" +msgstr "Entrer un code de récupération de l'authentification à double-facteur" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:20 +#, elixir-autogen, elixir-format +msgctxt "mfa auth verify code button" +msgid "Verify" +msgstr "Vérifier" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "mfa recover page title" +msgid "Two-factor recovery" +msgstr "Récupération du double-facteur" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "mfa recover recovery code prompt" +msgid "Recovery code" +msgstr "Code de récupération" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:23 +#, elixir-autogen, elixir-format +msgctxt "mfa recover use 2fa code link" +msgid "Enter a two-factor code" +msgstr "Entrer un code double-facteur" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:20 +#, elixir-autogen, elixir-format +msgctxt "mfa recover verify recovery code button" +msgid "Verify" +msgstr "Vérifier" + +#: lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "static fe profile page remote follow button" +msgid "Remote follow" +msgstr "Suivit distant" + +#: lib/pleroma/web/templates/email/digest.html.eex:163 +#, elixir-autogen, elixir-format +msgctxt "digest email header line" +msgid "Hey %{nickname}, here is what you've missed!" +msgstr "Salut %{nickname}, voici ce que tu as manqué·e !" + +#: lib/pleroma/web/templates/email/digest.html.eex:544 +#, elixir-autogen, elixir-format +msgctxt "digest email receiver address" +msgid "The email address you are subscribed as is %{email}. " +msgstr "" +"L'adresse que vous avez enregistré est %{email}. " + +#: lib/pleroma/web/templates/email/digest.html.eex:538 +#, elixir-autogen, elixir-format +msgctxt "digest email sending reason" +msgid "You have received this email because you have signed up to receive digest emails from %{instance} Pleroma instance." +msgstr "" +"Vous recevez ce courriel parce-que vous avez autorisé les messages-résumés " +"de l'instance pleroma, %{instance}." + +#: lib/pleroma/web/templates/email/digest.html.eex:547 +#, elixir-autogen, elixir-format +msgctxt "digest email unsubscribe action" +msgid "To unsubscribe, please go %{here}." +msgstr "Pour vous désinscrire, aller %{here}." + +#: lib/pleroma/web/templates/email/digest.html.eex:547 +#, elixir-autogen, elixir-format +msgctxt "digest email unsubscribe action link text" +msgid "here" +msgstr "ici" + +#: lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "mailer unsubscribe failed message" +msgid "UNSUBSCRIBE FAILURE" +msgstr "ÉCHEC DE DÉSINSCRIPTION" + +#: lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "mailer unsubscribe successful message" +msgid "UNSUBSCRIBE SUCCESSFUL" +msgstr "SUCCÈS DE LA DÉSINSCRIPTION" + +#: lib/pleroma/web/templates/email/digest.html.eex:385 +#, elixir-format +msgctxt "new followers count header" +msgid "%{count} New Follower" +msgid_plural "%{count} New Followers" +msgstr[0] "%{count} nouveau suivit" +msgstr[1] "%{count} nouveaux suivits" + +#: lib/pleroma/emails/user_email.ex:356 +#, elixir-autogen, elixir-format +msgctxt "account archive email body - self-requested" +msgid "

You requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" +msgstr "" +"

Vous avez demandé une sauvegarde complète de votre compte Pleroma. Le " +"téléchargement est prêt :

\n" +"

%{download_url}

\n" + +#: lib/pleroma/emails/user_email.ex:384 +#, elixir-autogen, elixir-format +msgctxt "account archive email subject" +msgid "Your account archive is ready" +msgstr "La sauvegarde de votre compte est prête" + +#: lib/pleroma/emails/user_email.ex:188 +#, elixir-autogen, elixir-format +msgctxt "approval pending email body" +msgid "

Awaiting Approval

\n

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

\n" +msgstr "" +"

En attente d'approbation

\n" +"

Votre compte sur %{instance_name} est en revue par l'équipe. Vous " +"recevrez un autre courriel quand le compte sera approuvé.

\n" + +#: lib/pleroma/emails/user_email.ex:202 +#, elixir-autogen, elixir-format +msgctxt "approval pending email subject" +msgid "Your account is awaiting approval" +msgstr "Votre compte est en attente d'approbation" + +#: lib/pleroma/emails/user_email.ex:158 +#, elixir-autogen, elixir-format +msgctxt "confirmation email body" +msgid "

Thank you for registering on %{instance_name}

\n

Email confirmation is required to activate the account.

\n

Please click the following link to activate your account.

\n" +msgstr "" +"

Merci de votre inscription à %{instance_name}

\n" +"

Une confirmation du courriel est requise.

\n" +"

Veuillez cliquer sur pour activer votre " +"compte.

\n" + +#: lib/pleroma/emails/user_email.ex:174 +#, elixir-autogen, elixir-format +msgctxt "confirmation email subject" +msgid "%{instance_name} account confirmation" +msgstr "confirmation du compte %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:310 +#, elixir-autogen, elixir-format +msgctxt "digest email subject" +msgid "Your digest from %{instance_name}" +msgstr "Votre résumé de %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:81 +#, elixir-autogen, elixir-format +msgctxt "password reset email body" +msgid "

Reset your password at %{instance_name}

\n

Someone has requested password change for your account at %{instance_name}.

\n

If it was you, visit the following link to proceed: reset password.

\n

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

\n" +msgstr "" +"

Changement de mot de passe à %{instance_name}

\n" +"

Une requête de changement de mot de passe pour votre compte à " +"%{instance_name} à été reçue.

\n" +"

Si c'était vous, veuillez suivre le lien suivant pour continuer : changer de mot de passe.

\n" +"

Si ça n'était pas vous, rien à craindre, vos données sont sécurisés et " +"votre mot de passe n'a pas été changé.

\n" + +#: lib/pleroma/emails/user_email.ex:98 +#, elixir-autogen, elixir-format +msgctxt "password reset email subject" +msgid "Password reset" +msgstr "Changement de mot de passe" + +#: lib/pleroma/emails/user_email.ex:215 +#, elixir-autogen, elixir-format +msgctxt "successful registration email body" +msgid "

Hello @%{nickname},

\n

Your account at %{instance_name} has been registered successfully.

\n

No further action is required to activate your account.

\n" +msgstr "" +"

Bonjour @%{nickname},

\n" +"

Votre compte %{instance_name} à été enregistré avec succès.

\n" +"

Aucune action suivante est requise.

\n" + +#: lib/pleroma/emails/user_email.ex:231 +#, elixir-autogen, elixir-format +msgctxt "successful registration email subject" +msgid "Account registered on %{instance_name}" +msgstr "Compte enregistré sur %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:119 +#, elixir-autogen, elixir-format +msgctxt "user invitation email body" +msgid "

You are invited to %{instance_name}

\n

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

\n

Click the following link to register: accept invitation.

\n" +msgstr "" +"

Vous avez été invité à %{instance_name}

\n" +"

%{inviter_name} vous invite à rejoindre %{instance_name}, une instance de " +"Pleroma, réseau social fédéré.

\n" +"

Cliquer le lien suivant pour vous enregistrer : accepter l'invitation.

\n" + +#: lib/pleroma/emails/user_email.ex:136 +#, elixir-autogen, elixir-format +msgctxt "user invitation email subject" +msgid "Invitation to %{instance_name}" +msgstr "Invitation à %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:53 +#, elixir-autogen, elixir-format +msgctxt "welcome email html body" +msgid "Welcome to %{instance_name}!" +msgstr "Bienvenu·e à %{instance_name} !" + +#: lib/pleroma/emails/user_email.ex:41 +#, elixir-autogen, elixir-format +msgctxt "welcome email subject" +msgid "Welcome to %{instance_name}!" +msgstr "Bienvenu·e à %{instance_name} !" + +#: lib/pleroma/emails/user_email.ex:65 +#, elixir-autogen, elixir-format +msgctxt "welcome email text body" +msgid "Welcome to %{instance_name}!" +msgstr "Bienvenu·e à %{instance_name} !" + +#: lib/pleroma/emails/user_email.ex:368 +#, elixir-autogen, elixir-format +msgctxt "account archive email body - admin requested" +msgid "

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" +msgstr "" +"

L'Admin de @%{admin_nickname} à demandé une sauvegarde complète de votre " +"compte Pleroma. Le téléchargement est prêt:

\n" +"

%{download_url}

\n" diff --git a/priv/gettext/ko/LC_MESSAGES/default.po b/priv/gettext/ko/LC_MESSAGES/default.po new file mode 100644 index 000000000..55b695d6b --- /dev/null +++ b/priv/gettext/ko/LC_MESSAGES/default.po @@ -0,0 +1,197 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-12-01 19:17+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Translate Toolkit 3.7.2\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 as no +## effect: edit them in PO (.po) files instead. + +#: lib/pleroma/web/api_spec/render_error.ex:122 +#, elixir-autogen, elixir-format +msgid "%{name} - %{count} is not a multiple of %{multiple}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:131 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than exclusive maximum %{max}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:140 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than inclusive maximum %{max}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:149 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than exclusive minimum %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:158 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than inclusive minimum %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:102 +#, elixir-autogen, elixir-format +msgid "%{name} - Array items must be unique." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:114 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is larger than maxItems: %{}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:106 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is smaller than minItems: %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:166 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid %{type}. Got: %{value}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:174 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid format. Expected %{format}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:51 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid schema.type. Got: %{type}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:178 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid value for enum." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:95 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is larger than maxLength: %{length}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:88 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is smaller than minLength: %{length}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:63 +#, elixir-autogen, elixir-format +msgid "%{name} - null value where %{type} expected." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:60 +#, elixir-autogen, elixir-format +msgid "%{name} - null value." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:182 +#, elixir-autogen, elixir-format +msgid "Failed to cast to any schema in %{polymorphic_type}" +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:71 +#, elixir-autogen, elixir-format +msgid "Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:84 +#, elixir-autogen, elixir-format +msgid "Failed to cast value to one of: %{failed_schemas}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:78 +#, elixir-autogen, elixir-format +msgid "Failed to cast value using any of: %{failed_schemas}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:212 +#, elixir-autogen, elixir-format +msgid "Invalid value for header: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:204 +#, elixir-autogen, elixir-format +msgid "Missing field: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:208 +#, elixir-autogen, elixir-format +msgid "Missing header: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:196 +#, elixir-autogen, elixir-format +msgid "No value provided for required discriminator `%{field}`." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:216 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:224 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" +msgstr "" + +#: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 +#, elixir-autogen, elixir-format +msgid "Oops" +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:188 +#, elixir-autogen, elixir-format +msgid "Unexpected field: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:200 +#, elixir-autogen, elixir-format +msgid "Unknown schema: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:192 +#, elixir-autogen, elixir-format +msgid "Value used as discriminator for `%{field}` matches no schemas." +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:43 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 +#, elixir-autogen, elixir-format +msgid "announces" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:44 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:38 +#, elixir-autogen, elixir-format +msgid "likes" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:42 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:36 +#, elixir-autogen, elixir-format +msgid "replies" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:27 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:22 +#, elixir-autogen, elixir-format +msgid "sensitive media" +msgstr "" diff --git a/priv/gettext/nl/LC_MESSAGES/errors.po b/priv/gettext/nl/LC_MESSAGES/errors.po index cfcb05fe6..ce1d794cf 100644 --- a/priv/gettext/nl/LC_MESSAGES/errors.po +++ b/priv/gettext/nl/LC_MESSAGES/errors.po @@ -3,16 +3,16 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-05-15 09:37+0000\n" -"PO-Revision-Date: 2020-06-02 07:36+0000\n" +"PO-Revision-Date: 2022-08-14 11:04+0000\n" "Last-Translator: Fristi \n" -"Language-Team: Dutch \n" +"Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.0.4\n" +"X-Generator: Weblate 4.13.1\n" ## This file is a PO Template file. ## @@ -118,7 +118,7 @@ msgstr "Al gestemd" #: lib/pleroma/web/oauth/oauth_controller.ex:360 #, elixir-format msgid "Bad request" -msgstr "Bad request" +msgstr "Ongeldig request" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:425 #, elixir-format @@ -155,7 +155,7 @@ msgstr "Object kan niet geliked worden" #: lib/pleroma/web/common_api/utils.ex:556 #, elixir-format msgid "Cannot post an empty status without attachments" -msgstr "Status kan niet geplaatst worden zonder tekst of bijlagen" +msgstr "Bericht kan niet geplaatst worden zonder tekst of bijlagen" #: lib/pleroma/web/common_api/utils.ex:504 #, elixir-format @@ -165,122 +165,122 @@ msgstr "Opmerking dient maximaal %{max_size} karakters te bevatten" #: lib/pleroma/config/config_db.ex:222 #, elixir-format msgid "Config with params %{params} not found" -msgstr "" +msgstr "Instelling met parameters %{params} kon niet gevonden worden" #: lib/pleroma/web/common_api/common_api.ex:95 #, elixir-format msgid "Could not delete" -msgstr "" +msgstr "Verwijderen mislukt" #: lib/pleroma/web/common_api/common_api.ex:141 #, elixir-format msgid "Could not favorite" -msgstr "" +msgstr "Favoriet maken mislukt" #: lib/pleroma/web/common_api/common_api.ex:370 #, elixir-format msgid "Could not pin" -msgstr "" +msgstr "Vastmaken mislukt" #: lib/pleroma/web/common_api/common_api.ex:112 #, elixir-format msgid "Could not repeat" -msgstr "" +msgstr "Herhalen mislukt" #: lib/pleroma/web/common_api/common_api.ex:188 #, elixir-format msgid "Could not unfavorite" -msgstr "" +msgstr "Favoriet ongedaan maken mislukt" #: lib/pleroma/web/common_api/common_api.ex:380 #, elixir-format msgid "Could not unpin" -msgstr "" +msgstr "Vastmaken ongedaan maken mislukt" #: lib/pleroma/web/common_api/common_api.ex:126 #, elixir-format msgid "Could not unrepeat" -msgstr "" +msgstr "Herhalen ongedaan maken mislukt" #: lib/pleroma/web/common_api/common_api.ex:428 #: lib/pleroma/web/common_api/common_api.ex:437 #, elixir-format msgid "Could not update state" -msgstr "" +msgstr "Status bijwerken mislukt" #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:202 #, elixir-format msgid "Error." -msgstr "" +msgstr "Fout." #: lib/pleroma/web/twitter_api/twitter_api.ex:106 #, elixir-format msgid "Invalid CAPTCHA" -msgstr "" +msgstr "Ongeldige CAPTCHA" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:117 #: lib/pleroma/web/oauth/oauth_controller.ex:569 #, elixir-format msgid "Invalid credentials" -msgstr "" +msgstr "Ongeldige inloggegevens" #: lib/pleroma/plugs/ensure_authenticated_plug.ex:38 #, elixir-format msgid "Invalid credentials." -msgstr "" +msgstr "Ongeldige inloggegevens." #: lib/pleroma/web/common_api/common_api.ex:265 #, elixir-format msgid "Invalid indices" -msgstr "" +msgstr "Ongeldige indexen" #: lib/pleroma/web/admin_api/admin_api_controller.ex:1147 #, elixir-format msgid "Invalid parameters" -msgstr "" +msgstr "Ongeldige parameters" #: lib/pleroma/web/common_api/utils.ex:411 #, elixir-format msgid "Invalid password." -msgstr "" +msgstr "Ongeldig wachtwoord." #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:187 #, elixir-format msgid "Invalid request" -msgstr "" +msgstr "Ongeldig request" #: lib/pleroma/web/twitter_api/twitter_api.ex:109 #, elixir-format msgid "Kocaptcha service unavailable" -msgstr "" +msgstr "Kocaptcha service niet beschikbaar" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:113 #, elixir-format msgid "Missing parameters" -msgstr "" +msgstr "Ontbrekende parameters" #: lib/pleroma/web/common_api/utils.ex:540 #, elixir-format msgid "No such conversation" -msgstr "" +msgstr "Gesprek niet gevonden" #: lib/pleroma/web/admin_api/admin_api_controller.ex:439 #: lib/pleroma/web/admin_api/admin_api_controller.ex:465 lib/pleroma/web/admin_api/admin_api_controller.ex:507 #, elixir-format msgid "No such permission_group" -msgstr "" +msgstr "Permission_group niet gevonden" #: lib/pleroma/plugs/uploaded_media.ex:74 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:485 lib/pleroma/web/admin_api/admin_api_controller.ex:1135 #: lib/pleroma/web/feed/user_controller.ex:73 lib/pleroma/web/ostatus/ostatus_controller.ex:143 #, elixir-format msgid "Not found" -msgstr "" +msgstr "Niet gevonden" #: lib/pleroma/web/common_api/common_api.ex:241 #, elixir-format msgid "Poll's author can't vote" -msgstr "" +msgstr "De peiling-auteur kan niet stemmen" #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49 @@ -288,215 +288,215 @@ msgstr "" #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 #, elixir-format msgid "Record not found" -msgstr "" +msgstr "Record niet gevonden" #: lib/pleroma/web/admin_api/admin_api_controller.ex:1153 #: lib/pleroma/web/feed/user_controller.ex:79 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:32 #: lib/pleroma/web/ostatus/ostatus_controller.ex:149 #, elixir-format msgid "Something went wrong" -msgstr "" +msgstr "Er is iets misgegaan" #: lib/pleroma/web/common_api/activity_draft.ex:107 #, elixir-format msgid "The message visibility must be direct" -msgstr "" +msgstr "De zichtbaarheid van het bericht dient privé te zijn" #: lib/pleroma/web/common_api/utils.ex:566 #, elixir-format msgid "The status is over the character limit" -msgstr "" +msgstr "Het bericht is langer dan het karakter-limiet" #: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31 #, elixir-format msgid "This resource requires authentication." -msgstr "" +msgstr "Deze gegevens vereisen authenticatie." #: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206 #, elixir-format msgid "Throttled" -msgstr "" +msgstr "Geremd" #: lib/pleroma/web/common_api/common_api.ex:266 #, elixir-format msgid "Too many choices" -msgstr "" +msgstr "Teveel keuzes" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:442 #, elixir-format msgid "Unhandled activity type" -msgstr "" +msgstr "Niet-ondersteund activiteits-type" #: lib/pleroma/web/admin_api/admin_api_controller.ex:536 #, elixir-format msgid "You can't revoke your own admin status." -msgstr "" +msgstr "Je kan je eigen beheerdersrechten niet intrekken." #: lib/pleroma/web/oauth/oauth_controller.ex:218 #: lib/pleroma/web/oauth/oauth_controller.ex:309 #, elixir-format msgid "Your account is currently disabled" -msgstr "" +msgstr "Je account is momenteel uitgeschakeld" #: lib/pleroma/web/oauth/oauth_controller.ex:180 #: lib/pleroma/web/oauth/oauth_controller.ex:332 #, elixir-format msgid "Your login is missing a confirmed e-mail address" -msgstr "" +msgstr "Je login bevat geen bevestigd e-mailadres" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:389 #, elixir-format msgid "can't read inbox of %{nickname} as %{as_nickname}" -msgstr "" +msgstr "kan de inbox van %{nickname} niet lezen als %{as_nickname}" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:472 #, elixir-format msgid "can't update outbox of %{nickname} as %{as_nickname}" -msgstr "" +msgstr "kan de outbox van %{nickname} niet bijwerken als %{as_nickname}" #: lib/pleroma/web/common_api/common_api.ex:388 #, elixir-format msgid "conversation is already muted" -msgstr "" +msgstr "gesprek is al genegeerd" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:316 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:491 #, elixir-format msgid "error" -msgstr "" +msgstr "fout" #: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:29 #, elixir-format msgid "mascots can only be images" -msgstr "" +msgstr "mascottes kunnen alleen afbeeldingen zijn" #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:60 #, elixir-format msgid "not found" -msgstr "" +msgstr "niet gevonden" #: lib/pleroma/web/oauth/oauth_controller.ex:395 #, elixir-format msgid "Bad OAuth request." -msgstr "" +msgstr "Ongeldig OAuth request." #: lib/pleroma/web/twitter_api/twitter_api.ex:115 #, elixir-format msgid "CAPTCHA already used" -msgstr "" +msgstr "CAPTCHA is al gebruikt" #: lib/pleroma/web/twitter_api/twitter_api.ex:112 #, elixir-format msgid "CAPTCHA expired" -msgstr "" +msgstr "CAPTCHA is verlopen" #: lib/pleroma/plugs/uploaded_media.ex:55 #, elixir-format msgid "Failed" -msgstr "" +msgstr "Mislukt" #: lib/pleroma/web/oauth/oauth_controller.ex:411 #, elixir-format msgid "Failed to authenticate: %{message}." -msgstr "" +msgstr "Authenticatie mislukt: %{message}." #: lib/pleroma/web/oauth/oauth_controller.ex:442 #, elixir-format msgid "Failed to set up user account." -msgstr "" +msgstr "Aanmaken van gebruikersaccount is mislukt." #: lib/pleroma/plugs/oauth_scopes_plug.ex:38 #, elixir-format msgid "Insufficient permissions: %{permissions}." -msgstr "" +msgstr "Niet voldoende rechten: %{permissions}." #: lib/pleroma/plugs/uploaded_media.ex:94 #, elixir-format msgid "Internal Error" -msgstr "" +msgstr "Interne Fout" #: lib/pleroma/web/oauth/fallback_controller.ex:22 #: lib/pleroma/web/oauth/fallback_controller.ex:29 #, elixir-format msgid "Invalid Username/Password" -msgstr "" +msgstr "Ongeldige Gebruikersnaam/Wachtwoord" #: lib/pleroma/web/twitter_api/twitter_api.ex:118 #, elixir-format msgid "Invalid answer data" -msgstr "" +msgstr "Ongeldig antwoord" #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:128 #, elixir-format msgid "Nodeinfo schema version not handled" -msgstr "" +msgstr "Nodeinfo schema wordt niet ondersteund" #: lib/pleroma/web/oauth/oauth_controller.ex:169 #, elixir-format msgid "This action is outside the authorized scopes" -msgstr "" +msgstr "Deze actie bevindt zich buiten de gemachtigde scopes" #: lib/pleroma/web/oauth/fallback_controller.ex:14 #, elixir-format msgid "Unknown error, please check the details and try again." -msgstr "" +msgstr "Onbekende fout, controleer a.u.b. de details en probeer het opnieuw." #: lib/pleroma/web/oauth/oauth_controller.ex:116 #: lib/pleroma/web/oauth/oauth_controller.ex:155 #, elixir-format msgid "Unlisted redirect_uri." -msgstr "" +msgstr "Niet-vermelde redirect_uri." #: lib/pleroma/web/oauth/oauth_controller.ex:391 #, elixir-format msgid "Unsupported OAuth provider: %{provider}." -msgstr "" +msgstr "Niet ondersteunde OAuth provider: %{provider}." #: lib/pleroma/uploaders/uploader.ex:72 #, elixir-format msgid "Uploader callback timeout" -msgstr "" +msgstr "Uploader terugkoppeling timeout" #: lib/pleroma/web/uploader_controller.ex:23 #, elixir-format msgid "bad request" -msgstr "" +msgstr "ongeldig request" #: lib/pleroma/web/twitter_api/twitter_api.ex:103 #, elixir-format msgid "CAPTCHA Error" -msgstr "" +msgstr "CAPTCHA Fout" #: lib/pleroma/web/common_api/common_api.ex:200 #, elixir-format msgid "Could not add reaction emoji" -msgstr "" +msgstr "Reactie-emoji toevoegen mislukt" #: lib/pleroma/web/common_api/common_api.ex:211 #, elixir-format msgid "Could not remove reaction emoji" -msgstr "" +msgstr "Reactie-emoji verwijderen mislukt" #: lib/pleroma/web/twitter_api/twitter_api.ex:129 #, elixir-format msgid "Invalid CAPTCHA (Missing parameter: %{name})" -msgstr "" +msgstr "Ongeldige CAPTCHA (Ontbrekende parameter: %{name})" #: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92 #, elixir-format msgid "List not found" -msgstr "" +msgstr "Lijst niet gevonden" #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:124 #, elixir-format msgid "Missing parameter: %{name}" -msgstr "" +msgstr "Ontbrekende parameter: %{name}" #: lib/pleroma/web/oauth/oauth_controller.ex:207 #: lib/pleroma/web/oauth/oauth_controller.ex:322 #, elixir-format msgid "Password reset is required" -msgstr "" +msgstr "Wachtwoordherstel is vereist" #: lib/pleroma/tests/auth_test_controller.ex:9 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/admin_api_controller.ex:6 @@ -528,53 +528,63 @@ msgstr "" #, elixir-format msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped." msgstr "" +"Schending van beveiliging: OAuth scope-controle is niet uitgevoerd en niet " +"expliciet overgeslagen." #: lib/pleroma/plugs/ensure_authenticated_plug.ex:28 #, elixir-format msgid "Two-factor authentication enabled, you must use a access token." msgstr "" +"Tweefactor authenticatie is ingeschakeld, een toegangssleutel is verplicht." #: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:210 #, elixir-format msgid "Unexpected error occurred while adding file to pack." msgstr "" +"Er is een onverwachte fout opgetreden tijdens het toevoegen van het bestand." #: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:138 #, elixir-format msgid "Unexpected error occurred while creating pack." msgstr "" +"Er is een onverwachte fout opgetreden tijdens het aanmaken van het pakket." #: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:278 #, elixir-format msgid "Unexpected error occurred while removing file from pack." msgstr "" +"Er is een onverwachte fout opgetreden tijdens het verwijderen van het " +"bestand." #: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:250 #, elixir-format msgid "Unexpected error occurred while updating file in pack." msgstr "" +"Er is een onverwachte fout opgetreden tijdens het bijwerken van het bestand." #: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:179 #, elixir-format msgid "Unexpected error occurred while updating pack metadata." msgstr "" +"Er is een onverwachte fout opgetreden tijdens het bijwerken van de pakket-" +"metadata." #: lib/pleroma/plugs/user_is_admin_plug.ex:21 #, elixir-format msgid "User is not an admin." -msgstr "" +msgstr "Gebruiker is niet een beheerder." #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 #, elixir-format msgid "Web push subscription is disabled on this Pleroma instance" -msgstr "" +msgstr "Web push abbonement is uitgeschakeld op deze Pleroma instantie" #: lib/pleroma/web/admin_api/admin_api_controller.ex:502 #, elixir-format msgid "You can't revoke your own admin/moderator status." -msgstr "" +msgstr "Je kan je eigen beheerders- of moderatorrechten niet intrekken." #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:105 #, elixir-format msgid "authorization required for timeline view" -msgstr "" +msgstr "machtiging is vereist voor de tijdlijn weergave" diff --git a/priv/gettext/nl/LC_MESSAGES/posix_errors.po b/priv/gettext/nl/LC_MESSAGES/posix_errors.po new file mode 100644 index 000000000..cdb1f532f --- /dev/null +++ b/priv/gettext/nl/LC_MESSAGES/posix_errors.po @@ -0,0 +1,165 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-08-13 13:32+0300\n" +"PO-Revision-Date: 2022-08-14 11:04+0000\n" +"Last-Translator: Fristi \n" +"Language-Team: Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\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 as no +## effect: edit them in PO (`.po`) files instead. +msgid "eperm" +msgstr "Uitvoering niet toegestaan" + +msgid "eacces" +msgstr "Toegang geweigerd" + +msgid "eagain" +msgstr "Resource tijdelijk niet beschikbaar" + +msgid "ebadf" +msgstr "Ongeldige file descriptor" + +msgid "ebadmsg" +msgstr "Ongeldig bericht" + +msgid "ebusy" +msgstr "Apparaat of resource bezet" + +msgid "edeadlk" +msgstr "Resource deadlock vermeden" + +msgid "edeadlock" +msgstr "Resource deadlock vermeden" + +msgid "edquot" +msgstr "Schijf-quota overschreden" + +msgid "eexist" +msgstr "Bestand bestaat" + +msgid "efault" +msgstr "Ongeldig adres" + +msgid "efbig" +msgstr "Bestand is te groot" + +msgid "eftype" +msgstr "Ongepast bestands-type of formaat" + +msgid "eintr" +msgstr "Onderbroken systeem aanroep" + +msgid "einval" +msgstr "Ongeldig argument" + +msgid "eio" +msgstr "Input/output fout" + +msgid "eisdir" +msgstr "Illegale bewerking op een directory" + +msgid "eloop" +msgstr "Te veel niveau's van symbolische koppelingen" + +msgid "emfile" +msgstr "Te veel geopende bestanden" + +msgid "emlink" +msgstr "Te veel koppelingen" + +msgid "emultihop" +msgstr "Multihop geprobeerd" + +msgid "enametoolong" +msgstr "Bestandsnaam is te lang" + +msgid "enfile" +msgstr "Te veel geopende bestanden in systeem" + +msgid "enobufs" +msgstr "Geen buffer-ruimte beschikbaar" + +msgid "enodev" +msgstr "Apparaat bestaat niet" + +msgid "enolck" +msgstr "Geen sloten beschikbaar" + +msgid "enolink" +msgstr "Koppeling is ongedaan gemaakt" + +msgid "enoent" +msgstr "Bestand of directory bestaat niet" + +msgid "enomem" +msgstr "Geheugen kon niet toegewezen worden" + +msgid "enospc" +msgstr "Geen ruimte over op apparaat" + +msgid "enosr" +msgstr "" + +msgid "enostr" +msgstr "" + +msgid "enosys" +msgstr "" + +msgid "enotblk" +msgstr "" + +msgid "enotdir" +msgstr "" + +msgid "enotsup" +msgstr "" + +msgid "enxio" +msgstr "" + +msgid "eopnotsupp" +msgstr "" + +msgid "eoverflow" +msgstr "" + +msgid "epipe" +msgstr "" + +msgid "erange" +msgstr "" + +msgid "erofs" +msgstr "" + +msgid "espipe" +msgstr "" + +msgid "esrch" +msgstr "" + +msgid "estale" +msgstr "" + +msgid "etxtbsy" +msgstr "" + +msgid "exdev" +msgstr "" diff --git a/priv/gettext/nl/LC_MESSAGES/static_pages.po b/priv/gettext/nl/LC_MESSAGES/static_pages.po new file mode 100644 index 000000000..2972384fc --- /dev/null +++ b/priv/gettext/nl/LC_MESSAGES/static_pages.po @@ -0,0 +1,567 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-08-13 13:24+0300\n" +"PO-Revision-Date: 2022-08-14 11:04+0000\n" +"Last-Translator: Fristi \n" +"Language-Team: Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\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 as no +## effect: edit them in PO (.po) files instead. +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button" +msgid "Authorize" +msgstr "Machtigen" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "remote follow error" +msgid "Error fetching user" +msgstr "Fout bij ophalen gebruiker" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow header" +msgid "Remote follow" +msgstr "Extern volgen" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for auth code entry" +msgid "Authentication code" +msgstr "Authenticatiecode" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:10 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for password entry" +msgid "Password" +msgstr "Wachtwoord" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for username entry" +msgid "Username" +msgstr "Gebruikersnaam" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:13 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button for login" +msgid "Authorize" +msgstr "Machtigen" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button for mfa" +msgid "Authorize" +msgstr "Machtigen" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "remote follow error" +msgid "Error following account" +msgstr "Fout bij volgen van account" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow header, need login" +msgid "Log in to follow" +msgstr "Log in om te volgen" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow mfa header" +msgid "Two-factor authentication" +msgstr "Tweefactor authenticatie" + +#: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow success" +msgid "Account followed!" +msgstr "Account gevolgd!" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:7 +#, elixir-autogen, elixir-format +msgctxt "placeholder text for account id" +msgid "Your account ID, e.g. lain@quitter.se" +msgstr "Je account ID, b.v. gebruiker@instantie.net" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "remote follow authorization button for following with a remote account" +msgid "Follow" +msgstr "Volgen" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "remote follow error" +msgid "Error: %{error}" +msgstr "Fout: %{error}" + +#: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "remote follow header" +msgid "Remotely follow %{nickname}" +msgstr "%{nickname} extern volgen" + +#: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "password reset button" +msgid "Reset" +msgstr "Herstellen" + +#: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "password reset failed homepage link" +msgid "Homepage" +msgstr "Homepagina" + +#: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "password reset failed message" +msgid "Password reset failed" +msgstr "Wachtwoordherstel mislukt" + +#: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "password reset form confirm password prompt" +msgid "Confirmation" +msgstr "Bevestiging" + +#: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:4 +#, elixir-autogen, elixir-format +msgctxt "password reset form password prompt" +msgid "Password" +msgstr "Wachtwoord" + +#: lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "password reset invalid token message" +msgid "Invalid Token" +msgstr "Ongeldige Token" + +#: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "password reset successful homepage link" +msgid "Homepage" +msgstr "Homepagina" + +#: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "password reset successful message" +msgid "Password changed!" +msgstr "Wachtwoord gewijzigd!" + +#: lib/pleroma/web/templates/feed/feed/tag.atom.eex:15 +#: lib/pleroma/web/templates/feed/feed/tag.rss.eex:7 +#, elixir-autogen, elixir-format +msgctxt "tag feed description" +msgid "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse." +msgstr "" +"Dit zijn openbare berichten die getagd zijn met #%{tag}. Je kunt op deze " +"reageren indien je een account hebt in de fediverse." + +#: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "oauth authorization exists page title" +msgid "Authorization exists" +msgstr "Machtiging bestaat" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:32 +#, elixir-autogen, elixir-format +msgctxt "oauth authorize approve button" +msgid "Approve" +msgstr "Goedkeuren" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:30 +#, elixir-autogen, elixir-format +msgctxt "oauth authorize cancel button" +msgid "Cancel" +msgstr "Annuleren" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:23 +#, elixir-autogen, elixir-format +msgctxt "oauth authorize message" +msgid "Application %{client_name} is requesting access to your account." +msgstr "" +"Applicatie %{client_name} vraagt om toegang tot je account." + +#: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "oauth authorized page title" +msgid "Successfully authorized" +msgstr "Machtiging is geslaagd" + +#: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "oauth external provider page title" +msgid "Sign in with external provider" +msgstr "Inloggen bij externe provider" + +#: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:13 +#, elixir-autogen, elixir-format +msgctxt "oauth external provider sign in button" +msgid "Sign in with %{strategy}" +msgstr "Inloggen met %{strategy}" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:54 +#, elixir-autogen, elixir-format +msgctxt "oauth login button" +msgid "Log In" +msgstr "Inloggen" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:51 +#, elixir-autogen, elixir-format +msgctxt "oauth login password prompt" +msgid "Password" +msgstr "Wachtwoord" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:47 +#, elixir-autogen, elixir-format +msgctxt "oauth login username prompt" +msgid "Username" +msgstr "Gebruikersnaam" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:39 +#, elixir-autogen, elixir-format +msgctxt "oauth register nickname prompt" +msgid "Pleroma Handle" +msgstr "Pleroma Gebruiker" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:37 +#, elixir-autogen, elixir-format +msgctxt "oauth register nickname unchangeable warning" +msgid "Choose carefully! You won't be able to change this later. You will be able to change your display name, though." +msgstr "" +"Let op! Je kunt je accountnaam hierna niet meer wijzigen. Je kunt echter wel " +"nog je weergavenaam wijzigen." + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:18 +#, elixir-autogen, elixir-format +msgctxt "oauth register page email prompt" +msgid "Email" +msgstr "E-mail" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:10 +#, elixir-autogen, elixir-format +msgctxt "oauth register page fill form prompt" +msgid "If you'd like to register a new account, please provide the details below." +msgstr "" +"Indien je graag een nieuw account wilt registreren, vul dan a.u.b de " +"onderstaande details in." + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:35 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login button" +msgid "Proceed as existing user" +msgstr "Doorgaan als bestaande gebruiker" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:31 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login password prompt" +msgid "Password" +msgstr "Wachtwoord" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:24 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login prompt" +msgid "Alternatively, sign in to connect to existing account." +msgstr "Alternatief, log in om te verbinden met een bestaand account." + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:27 +#, elixir-autogen, elixir-format +msgctxt "oauth register page login username prompt" +msgid "Name or email" +msgstr "Naam of e-mail" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:14 +#, elixir-autogen, elixir-format +msgctxt "oauth register page nickname prompt" +msgid "Nickname" +msgstr "Weergavenaam" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:22 +#, elixir-autogen, elixir-format +msgctxt "oauth register page register button" +msgid "Proceed as new user" +msgstr "Doorgaan als nieuwe gebruiker" + +#: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "oauth register page title" +msgid "Registration Details" +msgstr "Registratiegegevens" + +#: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:36 +#, elixir-autogen, elixir-format +msgctxt "oauth register page title" +msgid "This is the first time you visit! Please enter your Pleroma handle." +msgstr "Dit is je eerste bezoek! Vul a.u.b. je Pleroma gebruikersnaam in." + +#: lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "oauth scopes message" +msgid "The following permissions will be granted" +msgstr "De volgende rechten zullen worden toegekend" + +#: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:2 +#: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:2 +#, elixir-autogen, elixir-format +msgctxt "oauth token code message" +msgid "Token code is
%{token}" +msgstr "Token code is
%{token}" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "mfa auth code prompt" +msgid "Authentication code" +msgstr "Authenticatiecode" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "mfa auth page title" +msgid "Two-factor authentication" +msgstr "Tweefactor authenticatie" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:23 +#, elixir-autogen, elixir-format +msgctxt "mfa auth page use recovery code link" +msgid "Enter a two-factor recovery code" +msgstr "Voer een tweefactor herstelcode in" + +#: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:20 +#, elixir-autogen, elixir-format +msgctxt "mfa auth verify code button" +msgid "Verify" +msgstr "Controleren" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "mfa recover page title" +msgid "Two-factor recovery" +msgstr "Tweefactor herstel" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:12 +#, elixir-autogen, elixir-format +msgctxt "mfa recover recovery code prompt" +msgid "Recovery code" +msgstr "Herstelcode" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:23 +#, elixir-autogen, elixir-format +msgctxt "mfa recover use 2fa code link" +msgid "Enter a two-factor code" +msgstr "Voer een tweefactor code in" + +#: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:20 +#, elixir-autogen, elixir-format +msgctxt "mfa recover verify recovery code button" +msgid "Verify" +msgstr "Controleren" + +#: lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex:8 +#, elixir-autogen, elixir-format +msgctxt "static fe profile page remote follow button" +msgid "Remote follow" +msgstr "Extern volgen" + +#: lib/pleroma/web/templates/email/digest.html.eex:163 +#, elixir-autogen, elixir-format +msgctxt "digest email header line" +msgid "Hey %{nickname}, here is what you've missed!" +msgstr "Hoi %{nickname}, dit is wat je hebt gemist!" + +#: lib/pleroma/web/templates/email/digest.html.eex:544 +#, elixir-autogen, elixir-format +msgctxt "digest email receiver address" +msgid "The email address you are subscribed as is %{email}. " +msgstr "" +"Het e-mailadres waarmee je bent ingeschreven is %{email}. " + +#: lib/pleroma/web/templates/email/digest.html.eex:538 +#, elixir-autogen, elixir-format +msgctxt "digest email sending reason" +msgid "You have received this email because you have signed up to receive digest emails from %{instance} Pleroma instance." +msgstr "" +"Je ontvangt deze e-mail omdat je bent ingeschreven voor overzichts-mails te " +"ontvangen van %{instance} Pleroma instantie." + +#: lib/pleroma/web/templates/email/digest.html.eex:547 +#, elixir-autogen, elixir-format +msgctxt "digest email unsubscribe action" +msgid "To unsubscribe, please go %{here}." +msgstr "Je kunt je %{here} uitschrijven voor deze e-mails." + +#: lib/pleroma/web/templates/email/digest.html.eex:547 +#, elixir-autogen, elixir-format +msgctxt "digest email unsubscribe action link text" +msgid "here" +msgstr "hier" + +#: lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "mailer unsubscribe failed message" +msgid "UNSUBSCRIBE FAILURE" +msgstr "UITSCHRIJVEN MISLUKT" + +#: lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex:1 +#, elixir-autogen, elixir-format +msgctxt "mailer unsubscribe successful message" +msgid "UNSUBSCRIBE SUCCESSFUL" +msgstr "UITSCHRIJVEN GESLAAGD" + +#: lib/pleroma/web/templates/email/digest.html.eex:385 +#, elixir-format +msgctxt "new followers count header" +msgid "%{count} New Follower" +msgid_plural "%{count} New Followers" +msgstr[0] "%{count} Nieuwe Volger" +msgstr[1] "%{count} Nieuwe Volgers" + +#: lib/pleroma/emails/user_email.ex:356 +#, elixir-autogen, elixir-format +msgctxt "account archive email body - self-requested" +msgid "

You requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" +msgstr "" +"

Je hebt een verzoek ingediend voor een volledige back-up van je Pleroma " +"account. Deze is gereed om te downloaden:

\n" +"

%{download_url}

\n" + +#: lib/pleroma/emails/user_email.ex:384 +#, elixir-autogen, elixir-format +msgctxt "account archive email subject" +msgid "Your account archive is ready" +msgstr "Je account archief is gereed" + +#: lib/pleroma/emails/user_email.ex:188 +#, elixir-autogen, elixir-format +msgctxt "approval pending email body" +msgid "

Awaiting Approval

\n

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

\n" +msgstr "" +"

Goedkeuring in afwachting

\n" +"

Je account bij %{instance_name} zal worden beoordeeld door de beheerders. " +"Je zult een opvolgende e-mail ontvangen wanneer je account goed gekeurd " +"is.

\n" + +#: lib/pleroma/emails/user_email.ex:202 +#, elixir-autogen, elixir-format +msgctxt "approval pending email subject" +msgid "Your account is awaiting approval" +msgstr "Je account is in afwachting van goedkeuring" + +#: lib/pleroma/emails/user_email.ex:158 +#, elixir-autogen, elixir-format +msgctxt "confirmation email body" +msgid "

Thank you for registering on %{instance_name}

\n

Email confirmation is required to activate the account.

\n

Please click the following link to activate your account.

\n" +msgstr "" +"

Bedankt voor het registreren bij %{instance_name}

\n" +"

Bevestiging via e-mail is vereist om je account te activeren.

\n" +"

Je kunt je account activeren door op deze " +"link te klikken.

\n" + +#: lib/pleroma/emails/user_email.ex:174 +#, elixir-autogen, elixir-format +msgctxt "confirmation email subject" +msgid "%{instance_name} account confirmation" +msgstr "%{instance_name} account bevestiging" + +#: lib/pleroma/emails/user_email.ex:310 +#, elixir-autogen, elixir-format +msgctxt "digest email subject" +msgid "Your digest from %{instance_name}" +msgstr "Je overzicht van %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:81 +#, elixir-autogen, elixir-format +msgctxt "password reset email body" +msgid "

Reset your password at %{instance_name}

\n

Someone has requested password change for your account at %{instance_name}.

\n

If it was you, visit the following link to proceed: reset password.

\n

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

\n" +msgstr "" +"

Herstel je wachtwoord bij %{instance_name}

\n" +"

Iemand heeft een verzoek ingediend om het wachtwoord van je account bij " +"%{instance_name} te herstellen.

\n" +"

Als je dit zelf geweest bent, volg dan de volgende link om door te gaan: " +"wachtwoord herstellen.

\n" +"

Indien je dit niet geweest bent, hoef je geen verdere acties te " +"ondernemen: je gegevens zijn veilig en je wachtwoord is niet gewijzigd.

\n" + +#: lib/pleroma/emails/user_email.ex:98 +#, elixir-autogen, elixir-format +msgctxt "password reset email subject" +msgid "Password reset" +msgstr "Wachtwoord herstellen" + +#: lib/pleroma/emails/user_email.ex:215 +#, elixir-autogen, elixir-format +msgctxt "successful registration email body" +msgid "

Hello @%{nickname},

\n

Your account at %{instance_name} has been registered successfully.

\n

No further action is required to activate your account.

\n" +msgstr "" +"

Hoi @%{nickname},

\n" +"

Het registreren van je account bij %{instance_name} is gelukt.

\n" +"

Er zijn geen verdere stappen vereist om je account te activeren.

\n" + +#: lib/pleroma/emails/user_email.ex:231 +#, elixir-autogen, elixir-format +msgctxt "successful registration email subject" +msgid "Account registered on %{instance_name}" +msgstr "Account registratie bij %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:119 +#, elixir-autogen, elixir-format +msgctxt "user invitation email body" +msgid "

You are invited to %{instance_name}

\n

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

\n

Click the following link to register: accept invitation.

\n" +msgstr "" +"

Je bent uitgenodigd bij %{instance_name}

\n" +"

%{inviter_name} nodigt je uit om je te registreren bij %{instance_name}, " +"een instantie van het Pleroma gefedereerde sociale netwerk.

\n" +"

Om je te registreren, klink op de volgende link: uitnodiging accepteren.

\n" + +#: lib/pleroma/emails/user_email.ex:136 +#, elixir-autogen, elixir-format +msgctxt "user invitation email subject" +msgid "Invitation to %{instance_name}" +msgstr "Uitnodiging van %{instance_name}" + +#: lib/pleroma/emails/user_email.ex:53 +#, elixir-autogen, elixir-format +msgctxt "welcome email html body" +msgid "Welcome to %{instance_name}!" +msgstr "Welkom bij %{instance_name}!" + +#: lib/pleroma/emails/user_email.ex:41 +#, elixir-autogen, elixir-format +msgctxt "welcome email subject" +msgid "Welcome to %{instance_name}!" +msgstr "Welkom bij %{instance_name}!" + +#: lib/pleroma/emails/user_email.ex:65 +#, elixir-autogen, elixir-format +msgctxt "welcome email text body" +msgid "Welcome to %{instance_name}!" +msgstr "Welkom bij %{instance_name}!" + +#: lib/pleroma/emails/user_email.ex:368 +#, elixir-autogen, elixir-format +msgctxt "account archive email body - admin requested" +msgid "

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" +msgstr "" +"

Beheerder @%{admin_nickname} heeft een verzoek ingediend voor een " +"volledige back-up van je Pleroma account. Deze is gereed om te " +"downloaden:

\n" +"

%{download_url}

\n" diff --git a/priv/gettext/static_pages.pot b/priv/gettext/static_pages.pot index fbc3e61a3..3c64f1a29 100644 --- a/priv/gettext/static_pages.pot +++ b/priv/gettext/static_pages.pot @@ -10,393 +10,394 @@ msgid "" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9 msgctxt "remote follow authorization button" msgid "Authorize" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:2 msgctxt "remote follow error" msgid "Error fetching user" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:4 msgctxt "remote follow header" msgid "Remote follow" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:8 msgctxt "placeholder text for auth code entry" msgid "Authentication code" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:10 msgctxt "placeholder text for password entry" msgid "Password" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:8 msgctxt "placeholder text for username entry" msgid "Username" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:13 msgctxt "remote follow authorization button for login" msgid "Authorize" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:12 msgctxt "remote follow authorization button for mfa" msgid "Authorize" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:2 msgctxt "remote follow error" msgid "Error following account" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:4 msgctxt "remote follow header, need login" msgid "Log in to follow" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:4 msgctxt "remote follow mfa header" msgid "Two-factor authentication" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:4 msgctxt "remote follow success" msgid "Account followed!" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:7 #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:7 msgctxt "placeholder text for account id" msgid "Your account ID, e.g. lain@quitter.se" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:8 msgctxt "remote follow authorization button for following with a remote account" msgid "Follow" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:2 msgctxt "remote follow error" msgid "Error: %{error}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:4 msgctxt "remote follow header" msgid "Remotely follow %{nickname}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:12 msgctxt "password reset button" msgid "Reset" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:4 msgctxt "password reset failed homepage link" msgid "Homepage" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:1 msgctxt "password reset failed message" msgid "Password reset failed" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:8 msgctxt "password reset form confirm password prompt" msgid "Confirmation" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:4 msgctxt "password reset form password prompt" msgid "Password" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex:1 msgctxt "password reset invalid token message" msgid "Invalid Token" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:2 msgctxt "password reset successful homepage link" msgid "Homepage" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:1 msgctxt "password reset successful message" msgid "Password changed!" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/feed/feed/tag.atom.eex:15 #: lib/pleroma/web/templates/feed/feed/tag.rss.eex:7 msgctxt "tag feed description" msgid "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:1 msgctxt "oauth authorization exists page title" msgid "Authorization exists" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:32 msgctxt "oauth authorize approve button" msgid "Approve" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:30 msgctxt "oauth authorize cancel button" msgid "Cancel" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:23 msgctxt "oauth authorize message" msgid "Application %{client_name} is requesting access to your account." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:1 msgctxt "oauth authorized page title" msgid "Successfully authorized" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:1 msgctxt "oauth external provider page title" msgid "Sign in with external provider" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:13 msgctxt "oauth external provider sign in button" msgid "Sign in with %{strategy}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:54 msgctxt "oauth login button" msgid "Log In" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:51 msgctxt "oauth login password prompt" msgid "Password" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:47 msgctxt "oauth login username prompt" msgid "Username" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:39 msgctxt "oauth register nickname prompt" msgid "Pleroma Handle" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:37 msgctxt "oauth register nickname unchangeable warning" msgid "Choose carefully! You won't be able to change this later. You will be able to change your display name, though." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:18 msgctxt "oauth register page email prompt" msgid "Email" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:10 msgctxt "oauth register page fill form prompt" msgid "If you'd like to register a new account, please provide the details below." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:35 msgctxt "oauth register page login button" msgid "Proceed as existing user" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:31 msgctxt "oauth register page login password prompt" msgid "Password" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:24 msgctxt "oauth register page login prompt" msgid "Alternatively, sign in to connect to existing account." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:27 msgctxt "oauth register page login username prompt" msgid "Name or email" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:14 msgctxt "oauth register page nickname prompt" msgid "Nickname" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:22 msgctxt "oauth register page register button" msgid "Proceed as new user" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:8 msgctxt "oauth register page title" msgid "Registration Details" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:36 msgctxt "oauth register page title" msgid "This is the first time you visit! Please enter your Pleroma handle." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex:2 msgctxt "oauth scopes message" msgid "The following permissions will be granted" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:2 #: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:2 msgctxt "oauth token code message" msgid "Token code is
%{token}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:12 msgctxt "mfa auth code prompt" msgid "Authentication code" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:8 msgctxt "mfa auth page title" msgid "Two-factor authentication" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:23 msgctxt "mfa auth page use recovery code link" msgid "Enter a two-factor recovery code" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:20 msgctxt "mfa auth verify code button" msgid "Verify" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:8 msgctxt "mfa recover page title" msgid "Two-factor recovery" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:12 msgctxt "mfa recover recovery code prompt" msgid "Recovery code" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:23 msgctxt "mfa recover use 2fa code link" msgid "Enter a two-factor code" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:20 msgctxt "mfa recover verify recovery code button" msgid "Verify" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex:8 msgctxt "static fe profile page remote follow button" msgid "Remote follow" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:163 msgctxt "digest email header line" msgid "Hey %{nickname}, here is what you've missed!" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:544 msgctxt "digest email receiver address" msgid "The email address you are subscribed as is %{email}. " msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:538 msgctxt "digest email sending reason" msgid "You have received this email because you have signed up to receive digest emails from %{instance} Pleroma instance." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:547 msgctxt "digest email unsubscribe action" msgid "To unsubscribe, please go %{here}." msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:547 msgctxt "digest email unsubscribe action link text" msgid "here" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex:1 msgctxt "mailer unsubscribe failed message" msgid "UNSUBSCRIBE FAILURE" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex:1 msgctxt "mailer unsubscribe successful message" msgid "UNSUBSCRIBE SUCCESSFUL" @@ -410,104 +411,152 @@ msgid_plural "%{count} New Followers" msgstr[0] "" msgstr[1] "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:356 msgctxt "account archive email body - self-requested" msgid "

You requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:384 msgctxt "account archive email subject" msgid "Your account archive is ready" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:188 msgctxt "approval pending email body" msgid "

Awaiting Approval

\n

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

\n" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:202 msgctxt "approval pending email subject" msgid "Your account is awaiting approval" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:158 msgctxt "confirmation email body" msgid "

Thank you for registering on %{instance_name}

\n

Email confirmation is required to activate the account.

\n

Please click the following link to activate your account.

\n" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:174 msgctxt "confirmation email subject" msgid "%{instance_name} account confirmation" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:310 msgctxt "digest email subject" msgid "Your digest from %{instance_name}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:81 msgctxt "password reset email body" msgid "

Reset your password at %{instance_name}

\n

Someone has requested password change for your account at %{instance_name}.

\n

If it was you, visit the following link to proceed: reset password.

\n

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

\n" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:98 msgctxt "password reset email subject" msgid "Password reset" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:215 msgctxt "successful registration email body" msgid "

Hello @%{nickname},

\n

Your account at %{instance_name} has been registered successfully.

\n

No further action is required to activate your account.

\n" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:231 msgctxt "successful registration email subject" msgid "Account registered on %{instance_name}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:119 msgctxt "user invitation email body" msgid "

You are invited to %{instance_name}

\n

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

\n

Click the following link to register: accept invitation.

\n" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:136 msgctxt "user invitation email subject" msgid "Invitation to %{instance_name}" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:53 msgctxt "welcome email html body" msgid "Welcome to %{instance_name}!" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:41 msgctxt "welcome email subject" msgid "Welcome to %{instance_name}!" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:65 msgctxt "welcome email text body" msgid "Welcome to %{instance_name}!" msgstr "" -#, elixir-format +#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:368 msgctxt "account archive email body - admin requested" msgid "

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:123 +msgctxt "remote follow error message - unknown error" +msgid "Something went wrong." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:67 +msgctxt "remote follow error message - user not found" +msgid "Could not find user" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:8 +msgctxt "status interact authorization button" +msgid "Interact" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:2 +msgctxt "status interact error" +msgid "Error: %{error}" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:95 +msgctxt "status interact error message - status not found" +msgid "Could not find status" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:144 +msgctxt "status interact error message - unknown error" +msgid "Something went wrong." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:4 +msgctxt "status interact header" +msgid "Interacting with %{nickname}'s %{status_link}" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:4 +msgctxt "status interact header - status link text" +msgid "status" +msgstr "" diff --git a/priv/gettext/uk/LC_MESSAGES/config_descriptions.po b/priv/gettext/uk/LC_MESSAGES/config_descriptions.po new file mode 100644 index 000000000..0bcb8a34b --- /dev/null +++ b/priv/gettext/uk/LC_MESSAGES/config_descriptions.po @@ -0,0 +1,6071 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-09-18 19:11+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Translate Toolkit 3.7.2\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/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd" +msgid "Before enabling this you must add :esshd to mix.exs as one of the extra_applications and generate host keys in your priv dir with ssh-keygen -m PEM -N \"\" -b 2048 -t rsa -f ssh_host_rsa_key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger" +msgid "Logger-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :mime" +msgid "Mime Types settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma" +msgid "Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack" +msgid "Quack-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug" +msgid "CORS plug config" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd" +msgid "ESSHD" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger" +msgid "Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime" +msgid "Mime Types" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma" +msgid "Pleroma Admin Token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma" +msgid "Pleroma Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack" +msgid "Quack Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:console" +msgid "Console logger settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger" +msgid "ExSyslogger-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub" +msgid "ActivityPub-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth" +msgid "Authentication / authorization settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool" +msgid "Advanced settings for `Gun` connections pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications" +msgid "Email notifications settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:features" +msgid "Customizable features" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed" +msgid "Configure feed rendering" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations" +msgid "This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for pleroma_fe are configured. If you want to add your own configuration your settings all fields must be complete." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends" +msgid "Installed frontends management" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher" +msgid "Gopher settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools" +msgid "Advanced settings for `Hackney` connections pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http" +msgid "HTTP settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security" +msgid "HTTP security settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance" +msgid "Instance-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instances_favicons" +msgid "Control favicons for instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap" +msgid "Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password will be verified by trying to authenticate (bind) to a LDAP server. If a user exists in the LDAP directory but there is no account with the same name yet on the Pleroma instance then a new Pleroma account will be created with the same name as the LDAP user name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:majic_pool" +msgid "Majic/libmagic configuration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:modules" +msgid "Custom Runtime Modules" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf" +msgid "General MRF settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_activity_expiration" +msgid "Adds automatic expiration to all local activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_follow_bot" +msgid "Automatically follows newly discovered accounts." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag" +msgid "Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)\n\nNote: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread" +msgid "Block messages with excessive user mentions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword" +msgid "Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_mention" +msgid "Block messages which mention a specific user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_normalize_markup" +msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age" +msgid "Rejects or delists posts based on their timestamp deviance from your server's clock." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic" +msgid "RejectNonPublic drops posts with non-public visibility settings." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple" +msgid "Simple ingress policies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji" +msgid "Steals emojis from selected instances when it sees them." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary" +msgid "Filter messages which belong to certain activity vocabularies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2" +msgid "Configure OAuth 2 provider capabilities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools" +msgid "Advanced settings for `Gun` workers pools" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit" +msgid "Rate limit settings. This is an advanced feature enabled only for :authentication by default." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated" +msgid "Disallow viewing timelines, user profiles and statuses for unauthenticated users." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media" +msgid "If enabled the instance will parse metadata from attached links to generate link previews" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout" +msgid "Pleroma shout settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:static_fe" +msgid "Render profiles and posts using server-generated HTML that is viewable without using JavaScript" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer" +msgid "Settings for notifications streamer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:uri_schemes" +msgid "URI schemes related settings" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome" +msgid "Welcome messages settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:workers" +msgid "Includes custom worker options not interpretable directly by `Oban`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter" +msgid "Limits configuration for background tasks." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban" +msgid "[Oban](https://github.com/sorentwo/oban) asynchronous job processor configuration." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha" +msgid "Captcha-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Kocaptcha is a very simple captcha service with a single API endpoint, the source code is here: https://github.com/koto-bank/kocaptcha. The default endpoint (https://captcha.kotobank.ch) is hosted by the developer." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer" +msgid "Mailer-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "New users admin email digest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail" +msgid "Email template settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter" +msgid "Configuration for Pleroma's link formatter which parses mentions, hashtags, and URLs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity" +msgid "Scheduled activities settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload" +msgid "Upload general settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename" +msgid "Filter replaces the filename of the upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify" +msgid "Uploads mogrify filter settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local" +msgid "Local uploader-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3" +msgid "S3 uploader-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup" +msgid "Account Backup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http" +msgid "HTTP invalidate settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script" +msgid "Invalidation script settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata" +msgid "Metadata-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Preload" +msgid "Preload-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Expired activities settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" +msgid "Prometheus app metrics endpoint configuration" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3" +msgid "S3" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console" +msgid "Console Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger" +msgid "ExSyslogger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub" +msgid "ActivityPub" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets" +msgid "Assets" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth" +msgid "Auth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool" +msgid "Connections pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications" +msgid "Email notifications" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji" +msgid "Emoji" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:features" +msgid "Features" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed" +msgid "Feed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations" +msgid "Frontend configurations" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends" +msgid "Frontends" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher" +msgid "Gopher" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools" +msgid "Hackney pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http" +msgid "HTTP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security" +msgid "HTTP security" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance" +msgid "Instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instances_favicons" +msgid "Instances favicons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap" +msgid "LDAP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:majic_pool" +msgid "Majic pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest" +msgid "Manifest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup" +msgid "Markup Settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:modules" +msgid "Modules" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf" +msgid "MRF" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_activity_expiration" +msgid "MRF Activity Expiration Policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_follow_bot" +msgid "MRF FollowBot Policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag" +msgid "MRF Hashtag" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread" +msgid "MRF Hellthread" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword" +msgid "MRF Keyword" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_mention" +msgid "MRF Mention" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_normalize_markup" +msgid "MRF Normalize Markup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age" +msgid "MRF Object Age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic" +msgid "MRF Reject Non Public" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple" +msgid "MRF Simple" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji" +msgid "MRF Emojis" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_subchain" +msgid "MRF Subchain" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary" +msgid "MRF Vocabulary" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2" +msgid "OAuth2" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools" +msgid "Pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table" +msgid "Populate hashtags table" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit" +msgid "Rate limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated" +msgid "Restrict Unauthenticated" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media" +msgid "Rich media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout" +msgid "Shout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:static_fe" +msgid "Static FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer" +msgid "Streamer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:uri_schemes" +msgid "URI Schemes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:user" +msgid "User" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl" +msgid "Web cache TTL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome" +msgid "Welcome" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:workers" +msgid "Workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter" +msgid "ConcurrentLimiter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban" +msgid "Oban" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha" +msgid "Pleroma.Captcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Pleroma.Captcha.Kocaptcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer" +msgid "Pleroma.Emails.Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "Pleroma.Emails.NewUsersDigestEmail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail" +msgid "Pleroma.Emails.UserEmail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter" +msgid "Linkify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity" +msgid "Pleroma.ScheduledActivity" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload" +msgid "Pleroma.Upload" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local" +msgid "Pleroma.Uploaders.Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3" +msgid "Pleroma.Uploaders.S3" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User" +msgid "Pleroma.User" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup" +msgid "Pleroma.User.Backup" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata" +msgid "Pleroma.Web.Metadata" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Preload" +msgid "Pleroma.Web.Preload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Pleroma.Workers.PurgeExpiredActivity" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details" +msgid "Vapid Details" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :enabled" +msgid "Enables SSH" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :handler" +msgid "Handler module" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :password_authenticator" +msgid "Authenticator module" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :port" +msgid "Port to connect" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :priv_dir" +msgid "Dir with SSH keys" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :access_key_id" +msgid "S3 access key ID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :host" +msgid "S3 host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :region" +msgid "S3 region (for AWS)" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:console > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger > :format" +msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :blockers_visible" +msgid "Whether a user can see someone who has blocked them" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Following handshake timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :note_replies_output_limit" +msgid "The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :outgoing_blocks" +msgid "Whether to federate blocks to other instances" +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :unfollow_blocked" +msgid "Whether blocks result in people getting unfollowed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:assets > :default_user_avatar" +msgid "URL of the default user avatar" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "OAuth admin scope requirement toggle. If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes). If disabled and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :oauth_consumer_strategies" +msgid "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable. Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\" (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to `lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Number of attempts to acquire the connection from the pool if it is overloaded. Default: 5" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Timeout to acquire a connection from pool. The total max time is this value multiplied by the number of retries. Default: 250ms." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Multiplier for the number of idle connection to be reclaimed if the pool is full. For example if the pool maxes out at 250 connections and this setting is set to 0.3, the pool will reclaim at most 75 idle connections if it's overloaded. Default: 0.1" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest" +msgid "emails of \"what you've missed\" for users who have been inactive for a while" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :active" +msgid "Globally enable or disable digest emails" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Minimum user inactivity threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :interval" +msgid "Minimum interval between digest emails to one user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:emoji > :groups" +msgid "Emojis are ordered in groups (tags). This is an array of key-value pairs where the key is the group name and the value is the location or array of locations. * can be used as a wildcard." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:emoji > :pack_extensions" +msgid "A list of file extensions for emojis, when no emoji.txt for a pack is present" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:features > :improved_hashtag_timeline" +msgid "Setting to force toggle / force disable improved hashtags timeline. `:enabled` forces hashtags to be fetched from `hashtags` table for hashtags timeline. `:disabled` forces object-embedded hashtags to be used (slower). Keep it `:auto` for automatic behaviour (it is auto-set to `:enabled` [unless overridden] when HashtagsTableMigrator completes)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title" +msgid "Configure title rendering" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title > :max_length" +msgid "Maximum number of characters before truncating title" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title > :omission" +msgid "Replacement which will be used after truncating string" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Settings for Pleroma FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "When disabled, auto-hide the subject field if it's empty" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "URL of the background, unless viewing a user profile with a background that is set" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "When a message has a subject (aka Content Warning), collapse it by default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Enables green text on lines prefixed with the > character" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hides filtered statuses from timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hides muted statuses from timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide notices statistics (repeats, favorites, ...)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hides instance name from PleromaFE banner" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide profile statistics (posts, posts per day, followers, followings, ...)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "URL of the logo, defaults to Pleroma's logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Allows you to adjust vertical margins between logo boundary and navbar borders. The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. If you want a colorful logo you must disable logoMask." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Limit scope selection to Direct, User default, and Scope of post replying to. Also prevents replying to a DM with a public post from PleromaFE." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "URL of the image to use for hiding NSFW media attachments in the timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Default post formatting option" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Relative URL which indicates where to redirect when a user is logged in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Relative URL which indicates where to redirect when a user isn't logged in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Copy the scope (private/unlisted/public) in replies to posts by default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Enables panel displaying functionality of the instance on the About page" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Whether to show the instance's custom panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Change alignment of sidebar and panels to the right" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Allows changing the default behaviour of subject lines in replies.\n `email`: copy and preprend re:, as in email,\n `masto`: copy verbatim, as in Mastodon,\n `noop`: don't copy the subject." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Which theme to use. Available themes are defined in styles.json" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :admin" +msgid "Admin frontend" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :admin > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available" +msgid "A map containing available frontends and parameters for their installation." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > build_dir" +msgid "The directory inside the zip file " +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > build_url" +msgid "Either an url to a zip file containing the frontend or a template to build it by inserting the `ref`. The string `${ref}` will be replaced by the configured `ref`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > custom-http-headers" +msgid "The custom HTTP headers for the frontend" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > name" +msgid "Name of the frontend." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > ref" +msgid "Reference of the frontend to be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :primary > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :dstport" +msgid "Port advertised in URLs (optional, defaults to port)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :enabled" +msgid "Enables the gopher interface" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :ip" +msgid "IP address to bind to" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :port" +msgid "Port to bind to" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media" +msgid "Settings for media pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter" +msgid "Adapter specific options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL options for HTTP adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "List of TLS version to use" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :user_agent" +msgid "What user agent to use. Must be a string or an atom `:default`. Default value is `:default`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :ct_max_age" +msgid "The maximum age for the Expect-CT header if sent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :enabled" +msgid "Whether the managed content security policy is enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :referrer_policy" +msgid "The referrer policy to use, either \"same-origin\" or \"no-referrer\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :report_uri" +msgid "Adds the specified URL to report-uri and report-to group in CSP header" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :sts" +msgid "Whether to additionally send a Strict-Transport-Security header" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :sts_max_age" +msgid "The maximum age for the Strict-Transport-Security header if sent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_activation_required" +msgid "Require users to confirm their emails before signing in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_approval_required" +msgid "Require users to be manually approved by an admin before signing in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_field_name_length" +msgid "An account field name maximum length. Default: 512." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_field_value_length" +msgid "An account field value maximum length. Default: 2048." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :allow_relay" +msgid "Permits remote instances to subscribe to all public posts of your instance. (Important!) This may increase the visibility of your instance." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :allowed_post_formats" +msgid "MIME-type list of formats allowed to be posted (transformed into HTML)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :attachment_links" +msgid "Enable to automatically add attachment link text to statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :autofollowed_nicknames" +msgid "Set to nicknames of (local) users that every new user should automatically follow" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :autofollowing_nicknames" +msgid "Set to nicknames of (local) users that automatically follows every newly registered user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :avatar_upload_limit" +msgid "File size limit of user's profile avatars" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :background_upload_limit" +msgid "File size limit of user's profile backgrounds" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :banner_upload_limit" +msgid "File size limit of user's profile banners" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :birthday_required" +msgid "Require users to enter their birthday." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :cleanup_attachments" +msgid "Enable to remove associated attachments when status is removed.\nThis will not affect duplicates and attachments without status.\nEnabling this will increase load to database when deleting statuses on larger instances.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :description" +msgid "The instance's description. It can be seen in nodeinfo and `/api/v1/instance`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :email" +msgid "Email used to reach an Administrator/Moderator of the instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :extended_nickname_format" +msgid "Enable to use extended local nicknames format (allows underscores/dashes). This will break federation with older software for theses nicknames." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :external_user_synchronization" +msgid "Enabling following/followers counters synchronization for external users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federating" +msgid "Enable federation with other instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Max. depth of reply-to and reply activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Timeout (in days) of each external federation target being unreachable prior to pausing federating to it" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :healthcheck" +msgid "If enabled, system data will be shown on `/api/pleroma/healthcheck`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :instance_thumbnail" +msgid "The instance thumbnail can be any image that represents your instance and is used by some apps or services when they display information about your instance." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :limit" +msgid "Posts character limit (CW/Subject included in the counter)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :limit_to_local_content" +msgid "Limit unauthenticated users to search for local statutes and users only. Default: `:unauthenticated`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_account_fields" +msgid "The maximum number of custom fields in the user profile. Default: 10." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_endorsed_users" +msgid "The maximum number of recommended accounts. 0 will disable the feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_media_attachments" +msgid "Maximum number of post media attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_pinned_statuses" +msgid "The maximum number of pinned statuses. 0 will disable the feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_remote_account_fields" +msgid "The maximum number of custom fields in the remote user profile. Default: 20." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_report_comment_size" +msgid "The maximum size of the report comment. Default: 1000." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi-factor authentication settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "MFA backup codes settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Determines the length of backup one-time pass-codes, in characters. Defaults to 16 characters." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number of backup codes to generate." +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Determines the length of a one-time pass-code, in characters. Defaults to 6 characters." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "A period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :name" +msgid "Name of the instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :notify_email" +msgid "Envelope FROM address for mail sent via Pleroma" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits" +msgid "A map with poll limits for local polls" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Maximum expiration time (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Maximum number of characters per option" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_options" +msgid "Maximum number of options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Minimum expiration time (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :privileged_staff" +msgid "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :profile_directory" +msgid "Enable profile directory." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :public" +msgid "Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note: when setting to `false`, please also check `:restrict_unauthenticated` setting." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :quarantined_instances" +msgid "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :registration_reason_length" +msgid "Maximum registration reason length. Default: 500." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :registrations_open" +msgid "Enable registrations for anyone. Invitations require this setting to be disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :remote_limit" +msgid "Hard character limit beyond which remote posts will be dropped" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :remote_post_retention_days" +msgid "The default amount of days to retain remote posts when pruning the database" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :safe_dm_mentions" +msgid "If enabled, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\"). Default: disabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :show_reactions" +msgid "Let favourites and emoji reactions be viewed through the API." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :skip_thread_containment" +msgid "Skip filtering out broken threads. Default: enabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :static_dir" +msgid "Instance static directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :upload_limit" +msgid "File size limit of uploads (except for avatar, background, banner)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :user_bio_length" +msgid "A user bio maximum length. Default: 5000." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :user_name_length" +msgid "A user name maximum length. Default: 100." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instances_favicons > :enabled" +msgid "Allow/disallow displaying and getting instances favicons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :base" +msgid "LDAP base, e.g. \"dc=example,dc=com\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :enabled" +msgid "Enables LDAP authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :host" +msgid "LDAP server hostname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :port" +msgid "LDAP port, e.g. 389 or 636" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :ssl" +msgid "Enable to use SSL, usually implies the port 636" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts" +msgid "Additional SSL options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tls" +msgid "Enable to use STARTTLS, usually implies the port 389" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts" +msgid "Additional TLS options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :uid" +msgid "LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:majic_pool > :size" +msgid "Number of majic workers to start." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :background_color" +msgid "Describe the background color of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :icons" +msgid "Describe the icons of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :theme_color" +msgid "Describe the theme color of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:markup > :scrub_policy" +msgid "Module names are shortened (removed leading `Pleroma.HTML.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :enabled" +msgid "Enables proxying of remote media preview to the instance's proxy. Requires enabled media proxy." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :image_quality" +msgid "Quality of the output. Ranges from 0 (min quality) to 100 (max quality)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length (in bytes) to perform preview. Media smaller in size will be served without thumbnailing." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Max height of preview thumbnail for images (video preview always has original dimensions)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Max width of preview thumbnail for images (video preview always has original dimensions)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :base_url" +msgid "The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :enabled" +msgid "Enables proxying of remote media via the instance's proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enables media cache object invalidation." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Module which will be used to purge objects from the cache." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts" +msgid "Internal Pleroma.ReverseProxy settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Maximum file size (in bytes) allowed through the Pleroma MediaProxy cache." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Timeout (in milliseconds) of GET request to the remote URI." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirects the client to the origin server upon encountering HTTP errors.\n\nNote that files larger than Max Body Length will trigger an error. (e.g., Peertube videos)\n\n\n**WARNING:** This setting will allow larger files to be accessed, but exposes the\n\nIP addresses of your users to the other servers, bypassing the MediaProxy.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :whitelist" +msgid "List of hosts with scheme to bypass the MediaProxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:modules > :runtime_dir" +msgid "A path to custom Elixir modules (such as MRF policies)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :policies" +msgid "A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :transparency" +msgid "Make the content of your Message Rewrite Facility settings public (via nodeinfo)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :transparency_exclusions" +msgid "Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. You can also provide a reason for excluding these instance names. The instances and reasons won't be publicly disclosed." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_activity_expiration > :days" +msgid "Default global expiration time for all local activities (in days)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "The name of the bot account to use for following newly discovered users." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :reject" +msgid "A list of hashtags which result in message being rejected." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :sensitive" +msgid "A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Number of mentioned users after which the message gets removed from timelines anddisables notifications. Set to 0 to disable." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Number of mentioned users after which the messaged gets rejected. Set to 0 to disable." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid " A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :reject" +msgid " A list of patterns which result in message being rejected.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :replace" +msgid " **Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n\n **Replacement**: a string. Leaving the field empty is permitted.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_mention > :actors" +msgid "A list of actors for which any post mentioning them will be dropped" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age > :actions" +msgid "A list of actions to apply to the post. `:delist` removes the post from public timelines; `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; `:reject` rejects the message entirely" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age > :threshold" +msgid "Required age (in seconds) of a post before actions are taken." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Whether to allow direct messages" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Whether to allow followers-only posts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :accept" +msgid "List of instances to only accept activities from (except deletes) and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :avatar_removal" +msgid "List of instances to strip avatars from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :banner_removal" +msgid "List of instances to strip banners from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "List of instances to remove from the Federated (aka The Whole Known Network) Timeline and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :followers_only" +msgid "Force posts from the given instances to be visible by followers only and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :media_nsfw" +msgid "List of instances to tag all media as NSFW (sensitive) from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :media_removal" +msgid "List of instances to strip media attachments from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :reject" +msgid "List of instances to reject activities from (except deletes) and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :reject_deletes" +msgid "List of instances to reject deletions from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :report_removal" +msgid "List of instances to reject reports from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :hosts" +msgid "List of hosts to steal emojis from" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid " A list of patterns or matches to reject shortcodes with.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "File size limit (in bytes), checked before an emoji is saved to the disk" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_subchain > :match_actor" +msgid "Matches a series of regular expressions against the actor field" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary > :accept" +msgid "A list of ActivityStreams terms to accept. If empty, all supported messages are accepted." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary > :reject" +msgid "A list of ActivityStreams terms to reject. If empty, no messages are rejected." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Enable a background job to clean expired OAuth tokens. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Keeps old refresh token or generate new refresh token when to obtain an access token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :token_expires_in" +msgid "The lifetime in seconds of the access token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default" +msgid "Settings for default pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media" +msgid "Settings for media pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if hashtags transfer failed for all records." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :app_account_creation" +msgid "For registering user accounts from the same IP address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :authentication" +msgid "For authentication create / password check / user existence check requests" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :relation_id_action" +msgid "For actions on relation with a specific user (follow, unfollow)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :relations_actions" +msgid "For actions on relationships with all users (follow, unfollow)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :search" +msgid "For the search requests (account & status search etc.)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :status_id_action" +msgid "For fav / unfav or reblog / unreblog actions on the same status by the same user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :statuses_actions" +msgid "For create / delete / fav / unfav / reblog / unreblog actions on any statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :timeline" +msgid "For requests to timelines (each timeline has it's own limiter)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities" +msgid "Settings for statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Disallow view local statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Disallow view remote statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Settings for user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Disallow view local user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Disallow view remote user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Settings for public and federated timelines." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Disallow view federated timeline." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Disallow view public timeline." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :enabled" +msgid "Enables RichMedia parsing of URLs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :failure_backoff" +msgid "Amount of milliseconds after request failure, during which the request will not be retried." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ignore_hosts" +msgid "List of hosts which will be ignored by the metadata parser" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ignore_tld" +msgid "List TLDs (top-level domains) which will ignore for parse metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :parsers" +msgid "List of Rich Media parsers. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parsers.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ttl_setters" +msgid "List of rich media TTL setters. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parser.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout > :enabled" +msgid "Enables the backend Shoutbox chat feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout > :limit" +msgid "Shout message character limit." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:static_fe > :enabled" +msgid "Enables the rendering of static HTML. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer > :overflow_workers" +msgid "Maximum number of workers created if pool is empty" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer > :workers" +msgid "Number of workers to send notifications" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:uri_schemes > :valid_schemes" +msgid "List of the scheme part that is considered valid to be an URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub routes (except question activities). Default: `nil` (no expiration)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub routes (question activities). Default: `30_000` (30 seconds)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enables sending a chat message to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :message" +msgid "A message that will be sent to newly registered users as a chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enables sending a direct message to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :message" +msgid "A message that will be sent to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :enabled" +msgid "Enables sending an email to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :html" +msgid "HTML content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :sender" +msgid "Email address and/or nickname that will be used to send the welcome email." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :subject" +msgid "Subject of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :text" +msgid "Text content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:workers > :retries" +msgid "Max retry attempts for failed jobs, per `Oban` queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Concurrent limits configuration for MediaProxyWarmingPolicy." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Concurrent limits configuration for getting RichMedia for activities." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :crontab" +msgid "Settings for cron background jobs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :log" +msgid "Logs verbose mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues" +msgid "Background jobs queues (keys: queues, values: max numbers of concurrent jobs)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachment deletion queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :background" +msgid "Background queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :backup" +msgid "Backup queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :federator_incoming" +msgid "Incoming federation queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Outgoing federation queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :mailer" +msgid "Email sender queue, see Pleroma.Emails.Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities queue, see Pleroma.ScheduledActivities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :web_push" +msgid "Web push notifications queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :enabled" +msgid "Whether the captcha should be shown on registration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :method" +msgid "The method/service to use for captcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "The time in seconds for which the captcha is valid" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "The kocaptcha endpoint to use" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "One of the mail adapters listed in [Swoosh documentation](https://hexdocs.pm/swoosh/Swoosh.html#module-adapters)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "SMTP AUTH enforcement mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "SMTP AUTH password" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "SMTP port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Hostname or IP address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "SMTP temporary (4xx) error retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use Implicit SSL/TLS. e.g. port 465" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "Explicit TLS (STARTTLS) enforcement mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "SMTP AUTH username" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enables new users admin digest email when `true`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "A path to a custom logo. Set it to `nil` to use the default Pleroma logo." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "A map with color settings for email templates." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :class" +msgid "Specify the class to be added to the generated link. Disable to clear." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :extra" +msgid "Link URLs with rarely used schemes (magnet, ipfs, irc, etc.)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :new_window" +msgid "Link URLs will open in a new window/tab." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :rel" +msgid "Override the rel attribute. Disable to clear." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip the scheme prefix." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :truncate" +msgid "Set to a number to truncate URLs longer than the number. Truncated URLs will end in `...`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Set to false to disable TLD validation for URLs/emails. Can be set to :no_scheme to validate TLDs only for URLs without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "The number of scheduled activities a user is allowed to create in a single day. Default: 25." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Whether scheduled activities are sent to the job queue to be executed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "The number of scheduled activities a user is allowed to create in total. Default: 300." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL for the uploads. Required if you use a CDN or host attachments under a different domain." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Set max length of a filename to display. 0 = no limit. Default: 30" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :filters" +msgid "List of filter modules for uploads. Module names are shortened (removed leading `Pleroma.Upload.Filter.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :link_name" +msgid "If enabled, a name parameter will be added to the URL of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy requests to the remote uploader.\n\nUseful if media upload endpoint is not internet accessible.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :uploader" +msgid "Module which will be used for uploads" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text to replace filenames in links. If no setting, {random}.extension will be used. You can get the original filename extension by using {extension}, for example custom-file-name.{extension}." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "List of actions for the mogrify command. It's possible to add self-written settings as string. For example `auto-orient, strip, {\"resize\", \"3840x1080>\"}` value will be parsed into valid list of the settings." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Path where user's uploads will be saved" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "S3 bucket" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "S3 bucket namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc. For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in Upload base_url." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User > :email_blacklist" +msgid "List of email domains users may not register with." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "List of nicknames users may not register with." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit user to export not more often than once per N days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Remove backup achives after N days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Enables strict input validation (useful in development, not recommended in production)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "HTTP headers of request" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "HTTP method of request. Default: :purge" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Request options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Path to executable script which will purge cached items." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "Optional URL format preprocessing. Only required for Apache's htcacheclean." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "List of metadata providers to enable" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "When enabled NSFW attachments will be shown in previews" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enable/disable the plug. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid " A list of strings naming the HTTP headers to use when deriving the true client IP. Default: `[\"x-forwarded-for\"]`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "A list of upstream proxy IP subnets in CIDR notation from which we will parse the content of `headers`. Defaults to `[]`. IPv4 entries without a bitmask will be assumed to be /32 and IPv6 /128." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid " A list of reserved IP subnets in CIDR notation which should be ignored if found in `headers`. Defaults to `[\"127.0.0.0/8\", \"::1/128\", \"fc00::/7\", \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"]`\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Preload > :providers" +msgid "List of preload providers to enable" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enables expired activities addition & deletion" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Minimum lifetime for ephemeral activity (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Enables HTTP Basic Auth for app metrics endpoint." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "[Pleroma extension] Enables app metrics endpoint." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "App metrics endpoint output format." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "Restrict access of app metrics endpoint to the specified IP addresses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "App metrics endpoint URI path." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :meta" +msgid "Configure which metadata you want to report on" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :webhook_url" +msgid "Configure the Slack incoming webhook" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :private_key" +msgid "VAPID private key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :public_key" +msgid "VAPID public key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :subject" +msgid "A mailto link for the administrative contact. It's best if this email is not a personal email address, but rather a group email to the instance moderation team." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :credentials" +msgid "Credentials" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :expose" +msgid "Expose" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :max_age" +msgid "Max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :methods" +msgid "Methods" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :handler" +msgid "Handler" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :password_authenticator" +msgid "Password authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :priv_dir" +msgid "Priv dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :access_key_id" +msgid "Access key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :host" +msgid "Host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :region" +msgid "Region" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :secret_access_key" +msgid "Secret access key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger > :backends" +msgid "Backends" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :metadata" +msgid "Metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :ident" +msgid "Ident" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :metadata" +msgid "Metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types" +msgid "Types" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/activity+json" +msgid "\"application/activity+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/jrd+json" +msgid "\"application/jrd+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/ld+json" +msgid "\"application/ld+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/xml" +msgid "\"application/xml\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/xrd+xml" +msgid "\"application/xrd+xml\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma > Pleroma.Web.Auth.Authenticator" +msgid "Pleroma.Web.Auth.Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :blockers_visible" +msgid "Blockers visible" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Follow handshake timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :note_replies_output_limit" +msgid "Note replies output limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :outgoing_blocks" +msgid "Outgoing blocks" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :sign_object_fetches" +msgid "Sign object fetches" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :unfollow_blocked" +msgid "Unfollow blocked" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :default_mascot" +msgid "Default mascot" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :default_user_avatar" +msgid "Default user avatar" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :mascots" +msgid "Mascots" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :auth_template" +msgid "Auth template" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "Enforce OAuth admin scope usage" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :oauth_consumer_strategies" +msgid "OAuth consumer strategies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer template" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connect_timeout" +msgid "Connect timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Connection acquisition retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Connection acquisition wait" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Reclaim multiplier" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest" +msgid "Digest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :active" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Inactivity threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :interval" +msgid "Interval" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :schedule" +msgid "Schedule" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :default_manifest" +msgid "Default manifest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :groups" +msgid "Groups" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :pack_extensions" +msgid "Pack extensions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :shared_pack_cache_seconds_per_file" +msgid "Shared pack cache s/file" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :shortcode_globs" +msgid "Shortcode globs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:features > :improved_hashtag_timeline" +msgid "Improved hashtag timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title" +msgid "Post title" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title > :max_length" +msgid "Max length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title > :omission" +msgid "Omission" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Pleroma FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "Always show subject input" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "Background" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "Collapse message with subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Greentext" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hide Filtered Statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hide Muted Posts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide post stats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hide Sitename" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide user stats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "Logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Logo margin" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "Logo mask" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Minimal scopes mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "NSFW Censor Image" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Post Content Type" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Redirect root login" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Redirect root no login" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Scope copy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Show instance features panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Show instance specific panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Sidebar on Right" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Subject line behavior" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Theme" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin" +msgid "Admin" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available" +msgid "Available" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > build_dir" +msgid "Build directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > build_url" +msgid "Build URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > custom-http-headers" +msgid "Custom HTTP headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > git" +msgid "Git Repository URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary" +msgid "Primary" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :dstport" +msgid "Dstport" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :ip" +msgid "IP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation" +msgid "Federation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media" +msgid "Media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload" +msgid "Upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter" +msgid "Adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "Versions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :send_user_agent" +msgid "Send user agent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :user_agent" +msgid "User agent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :ct_max_age" +msgid "CT max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :referrer_policy" +msgid "Referrer policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :report_uri" +msgid "Report URI" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :sts" +msgid "STS" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :sts_max_age" +msgid "STS max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_activation_required" +msgid "Account activation required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_approval_required" +msgid "Account approval required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_field_name_length" +msgid "Account field name length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_field_value_length" +msgid "Account field value length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :allow_relay" +msgid "Allow relay" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :allowed_post_formats" +msgid "Allowed post formats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :attachment_links" +msgid "Attachment links" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :autofollowed_nicknames" +msgid "Autofollowed nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :autofollowing_nicknames" +msgid "Autofollowing nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :avatar_upload_limit" +msgid "Avatar upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :background_upload_limit" +msgid "Background upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :banner_upload_limit" +msgid "Banner upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :birthday_min_age" +msgid "Birthday min age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :birthday_required" +msgid "Birthday required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :cleanup_attachments" +msgid "Cleanup attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :description" +msgid "Description" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :email" +msgid "Admin Email Address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :extended_nickname_format" +msgid "Extended nickname format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :external_user_synchronization" +msgid "External user synchronization" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federating" +msgid "Federating" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Fed. incoming replies max depth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Fed. reachability timeout days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :healthcheck" +msgid "Healthcheck" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :instance_thumbnail" +msgid "Instance thumbnail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :invites_enabled" +msgid "Invites enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :limit" +msgid "Limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :limit_to_local_content" +msgid "Limit to local content" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_account_fields" +msgid "Max account fields" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_endorsed_users" +msgid "Max endorsed users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_media_attachments" +msgid "Max media attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_pinned_statuses" +msgid "Max pinned statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_remote_account_fields" +msgid "Max remote account fields" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_report_comment_size" +msgid "Max report comment size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi factor authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "Backup codes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp" +msgid "TOTP settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Digits" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "Period" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :notify_email" +msgid "Sender Email Address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits" +msgid "Poll limits" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Max expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Max option chars" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_options" +msgid "Max options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Min expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :privileged_staff" +msgid "Privileged staff" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :profile_directory" +msgid "Profile directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :public" +msgid "Public" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :quarantined_instances" +msgid "Quarantined instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :registration_reason_length" +msgid "Registration reason length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :registrations_open" +msgid "Registrations open" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :remote_limit" +msgid "Remote limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :remote_post_retention_days" +msgid "Remote post retention days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :safe_dm_mentions" +msgid "Safe DM mentions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :show_reactions" +msgid "Show reactions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :skip_thread_containment" +msgid "Skip thread containment" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :static_dir" +msgid "Static dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :upload_limit" +msgid "Upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :user_bio_length" +msgid "User bio length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :user_name_length" +msgid "User name length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instances_favicons > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :base" +msgid "Base" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :host" +msgid "Host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :ssl" +msgid "SSL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts" +msgid "SSL options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts > :verify" +msgid "Verify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tls" +msgid "TLS" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts" +msgid "TLS options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts > :verify" +msgid "Verify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :uid" +msgid "UID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:majic_pool > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :background_color" +msgid "Background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :icons" +msgid "Icons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :theme_color" +msgid "Theme color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_fonts" +msgid "Allow fonts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_headings" +msgid "Allow headings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_inline_images" +msgid "Allow inline images" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_tables" +msgid "Allow tables" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :image_quality" +msgid "Image quality" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Thumbnail max height" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Thumbnail max width" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :base_url" +msgid "Base URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation" +msgid "Invalidation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Provider" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts" +msgid "Advanced MediaProxy Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Max body length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Max read duration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirect on failure" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :whitelist" +msgid "Whitelist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:modules > :runtime_dir" +msgid "Runtime dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :policies" +msgid "Policies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :transparency" +msgid "MRF transparency" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :transparency_exclusions" +msgid "MRF transparency exclusions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_activity_expiration > :days" +msgid "Days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "Follower nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :sensitive" +msgid "Sensitive" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Delist threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Reject threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :replace" +msgid "Replace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_mention > :actors" +msgid "Actors" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_normalize_markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age > :actions" +msgid "Actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age > :threshold" +msgid "Threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Allow direct" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Allow followers-only" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :accept" +msgid "Accept" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :avatar_removal" +msgid "Avatar removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :banner_removal" +msgid "Banner removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :followers_only" +msgid "Followers only" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :media_nsfw" +msgid "Media NSFW" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :media_removal" +msgid "Media removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :reject_deletes" +msgid "Reject deletes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :report_removal" +msgid "Report removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :hosts" +msgid "Hosts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid "Rejected shortcodes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "Size limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_subchain > :match_actor" +msgid "Match actor" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary > :accept" +msgid "Accept" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Clean expired tokens" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Issue new refresh token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :token_expires_in" +msgid "Token expires in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default" +msgid "Default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation" +msgid "Federation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media" +msgid "Media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload" +msgid "Upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :app_account_creation" +msgid "App account creation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :authentication" +msgid "Authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :relation_id_action" +msgid "Relation ID action" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :relations_actions" +msgid "Relations actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :search" +msgid "Search" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :status_id_action" +msgid "Status ID action" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :statuses_actions" +msgid "Statuses actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :timeline" +msgid "Timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities" +msgid "Activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Profiles" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Federated" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :failure_backoff" +msgid "Failure backoff" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ignore_hosts" +msgid "Ignore hosts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ignore_tld" +msgid "Ignore TLD" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :parsers" +msgid "Parsers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ttl_setters" +msgid "TTL setters" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout > :limit" +msgid "Limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:static_fe > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer > :overflow_workers" +msgid "Overflow workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer > :workers" +msgid "Workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:uri_schemes > :valid_schemes" +msgid "Valid schemes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:user > :deny_follow_blocked" +msgid "Deny follow blocked" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub question" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message" +msgid "Chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :message" +msgid "Message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message" +msgid "Direct message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :message" +msgid "Message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email" +msgid "Email" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :html" +msgid "Html" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :sender" +msgid "Sender" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :subject" +msgid "Subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :text" +msgid "Text" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:workers > :retries" +msgid "Retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Pleroma.Web.RichMedia.Helpers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :crontab" +msgid "Crontab" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :log" +msgid "Log" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues" +msgid "Queues" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachments cleanup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :background" +msgid "Background" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :backup" +msgid "Backup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :federator_incoming" +msgid "Federator incoming" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Federator outgoing" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :mailer" +msgid "Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :web_push" +msgid "Web push" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :method" +msgid "Method" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "Seconds valid" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "Endpoint" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "Adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :enabled" +msgid "Mailer Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:access_key" +msgid "AWS Access Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:region" +msgid "AWS Region" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:secret" +msgid "AWS Secret Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Dyn-:api_key" +msgid "Dyn API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Gmail-:access_token" +msgid "GMail API Access Token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:api_key" +msgid "Mailgun API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:domain" +msgid "Domain" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:api_key" +msgid "MailJet Public API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:secret" +msgid "MailJet Private API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mandrill-:api_key" +msgid "Mandrill API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Postmark-:api_key" +msgid "Postmark API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "AUTH Mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "Password" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Relay" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "Retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use SSL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "STARTTLS Mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "Username" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendgrid-:api_key" +msgid "SendGrid API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_args" +msgid "Cmd args" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_path" +msgid "Cmd path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:qmail" +msgid "Qmail compat mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:api_key" +msgid "SocketLabs API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:server_id" +msgid "Server ID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:api_key" +msgid "SparkPost API key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:endpoint" +msgid "Endpoint" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "Logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "Styling" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :background_color" +msgid "Background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :content_background_color" +msgid "Content background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :header_color" +msgid "Header color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :link_color" +msgid "Link color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_color" +msgid "Text color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_muted_color" +msgid "Text muted color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :class" +msgid "Class" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :extra" +msgid "Extra" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :new_window" +msgid "New window" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :rel" +msgid "Rel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip prefix" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :truncate" +msgid "Truncate" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Validate tld" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "Daily user limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "Total user limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Filename display max length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :filters" +msgid "Filters" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :link_name" +msgid "Link name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :uploader" +msgid "Uploader" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "Args" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Uploads" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "Bucket" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "Bucket namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Streaming enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "Truncated namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User > :email_blacklist" +msgid "Email blacklist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "Restricted nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Purge after days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Strict" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "Method" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options > :params" +msgid "Params" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Script path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "URL Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "Providers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "Unfurl NSFW" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "Proxies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid "Reserved" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Preload > :providers" +msgid "Providers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Min lifetime" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Auth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "IP Whitelist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "Path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :meta" +msgid "Meta" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :webhook_url" +msgid "Webhook URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :private_key" +msgid "Private key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :public_key" +msgid "Public key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :subject" +msgid "Subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :authorized_fetch_mode" +msgid "Require HTTP signatures for AP fetches" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :short_description" +msgid "Shorter version of instance description. It can be seen on `/api/v1/instance`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :authorized_fetch_mode" +msgid "Authorized fetch mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :short_description" +msgid "Short description" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:delete_context_objects" +msgid "`delete_context_objects` background migration settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:delete_context_objects > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if context object deletion failed for all records." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:delete_context_objects > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :birthday_min_age" +msgid "Minimum required age (in days) for users to create account. Only used if birthday is required." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:delete_context_objects" +msgid "Delete context objects" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:delete_context_objects > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:delete_context_objects > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" diff --git a/priv/gettext/uk/LC_MESSAGES/default.po b/priv/gettext/uk/LC_MESSAGES/default.po new file mode 100644 index 000000000..ce4f96173 --- /dev/null +++ b/priv/gettext/uk/LC_MESSAGES/default.po @@ -0,0 +1,197 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-09-18 19:11+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Translate Toolkit 3.7.2\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 as no +## effect: edit them in PO (.po) files instead. + +#: lib/pleroma/web/api_spec/render_error.ex:122 +#, elixir-autogen, elixir-format +msgid "%{name} - %{count} is not a multiple of %{multiple}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:131 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than exclusive maximum %{max}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:140 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than inclusive maximum %{max}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:149 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than exclusive minimum %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:158 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than inclusive minimum %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:102 +#, elixir-autogen, elixir-format +msgid "%{name} - Array items must be unique." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:114 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is larger than maxItems: %{}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:106 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is smaller than minItems: %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:166 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid %{type}. Got: %{value}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:174 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid format. Expected %{format}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:51 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid schema.type. Got: %{type}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:178 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid value for enum." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:95 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is larger than maxLength: %{length}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:88 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is smaller than minLength: %{length}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:63 +#, elixir-autogen, elixir-format +msgid "%{name} - null value where %{type} expected." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:60 +#, elixir-autogen, elixir-format +msgid "%{name} - null value." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:182 +#, elixir-autogen, elixir-format +msgid "Failed to cast to any schema in %{polymorphic_type}" +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:71 +#, elixir-autogen, elixir-format +msgid "Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:84 +#, elixir-autogen, elixir-format +msgid "Failed to cast value to one of: %{failed_schemas}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:78 +#, elixir-autogen, elixir-format +msgid "Failed to cast value using any of: %{failed_schemas}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:212 +#, elixir-autogen, elixir-format +msgid "Invalid value for header: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:204 +#, elixir-autogen, elixir-format +msgid "Missing field: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:208 +#, elixir-autogen, elixir-format +msgid "Missing header: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:196 +#, elixir-autogen, elixir-format +msgid "No value provided for required discriminator `%{field}`." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:216 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:224 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" +msgstr "" + +#: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 +#, elixir-autogen, elixir-format +msgid "Oops" +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:188 +#, elixir-autogen, elixir-format +msgid "Unexpected field: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:200 +#, elixir-autogen, elixir-format +msgid "Unknown schema: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:192 +#, elixir-autogen, elixir-format +msgid "Value used as discriminator for `%{field}` matches no schemas." +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:43 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 +#, elixir-autogen, elixir-format +msgid "announces" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:44 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:38 +#, elixir-autogen, elixir-format +msgid "likes" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:42 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:36 +#, elixir-autogen, elixir-format +msgid "replies" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:27 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:22 +#, elixir-autogen, elixir-format +msgid "sensitive media" +msgstr "" diff --git a/priv/gettext/uk/LC_MESSAGES/errors.po b/priv/gettext/uk/LC_MESSAGES/errors.po index 9638761ec..2a41b3c1d 100644 --- a/priv/gettext/uk/LC_MESSAGES/errors.po +++ b/priv/gettext/uk/LC_MESSAGES/errors.po @@ -3,17 +3,17 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-12-10 16:09+0000\n" -"PO-Revision-Date: 2020-12-11 00:56+0000\n" -"Last-Translator: ZEN \n" -"Language-Team: Ukrainian \n" +"PO-Revision-Date: 2022-09-18 17:09+0000\n" +"Last-Translator: Dmytro Poltavchenko \n" +"Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=" -"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.0.4\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.13.1\n" ## This file is a PO Template file. ## @@ -312,7 +312,7 @@ msgstr "Цей ресурс вимагає автентифікації." #: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206 #, elixir-format msgid "Throttled" -msgstr "Обмежено. Перевищено ліміт запитів." +msgstr "Перевищено ліміт запитів" #: lib/pleroma/web/common_api/common_api.ex:356 #, elixir-format diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po b/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po new file mode 100644 index 000000000..ff9ad5245 --- /dev/null +++ b/priv/gettext/zh_Hans/LC_MESSAGES/config_descriptions.po @@ -0,0 +1,6034 @@ +msgid "" +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: 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/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd" +msgid "Before enabling this you must add :esshd to mix.exs as one of the extra_applications and generate host keys in your priv dir with ssh-keygen -m PEM -N \"\" -b 2048 -t rsa -f ssh_host_rsa_key" +msgstr "" +"在启用这个之前,必须先把 :esshd 作为 extra_application 中之一添加到 mix.exs " +"里,然后在你的 priv 目录里通过 ssh-keygen -m PEM -N \"\" -b 2048 -t rsa -f " +"ssh_host_rsa_key 生成主机密钥" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger" +msgid "Logger-related settings" +msgstr "日志器相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :mime" +msgid "Mime Types settings" +msgstr "Mime 类型设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma" +msgid "Authenticator" +msgstr "鉴权器" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack" +msgid "Quack-related settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug" +msgid "CORS plug config" +msgstr "CORS 插件配置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd" +msgid "ESSHD" +msgstr "ESSHD" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger" +msgid "Logger" +msgstr "日志器" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime" +msgid "Mime Types" +msgstr "Mime 类型" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma" +msgid "Pleroma Admin Token" +msgstr "Pleroma 管理员令牌" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma" +msgid "Pleroma Authenticator" +msgstr "Pleroma 鉴权器" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack" +msgid "Quack Logger" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:console" +msgid "Console logger settings" +msgstr "终端日志器设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger" +msgid "ExSyslogger-related settings" +msgstr "ExSyslogger 相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub" +msgid "ActivityPub-related settings" +msgstr "ActivityPub 相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth" +msgid "Authentication / authorization settings" +msgstr "鉴权/授权设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool" +msgid "Advanced settings for `Gun` connections pool" +msgstr "「Gun」连接池的高级设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications" +msgid "Email notifications settings" +msgstr "邮件通知设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:features" +msgid "Customizable features" +msgstr "可定制的特性" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed" +msgid "Configure feed rendering" +msgstr "配置 feed 渲染" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations" +msgid "This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for pleroma_fe are configured. If you want to add your own configuration your settings all fields must be complete." +msgstr "" +"这个表单可以用来配置一个 keyword " +"列表,来存放给任意种类的前端的配置数据。默认地,这里配置了 pleroma_fe " +"的设置。如果你想添加自己的配置,所有的项都得完成。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends" +msgid "Installed frontends management" +msgstr "已经安装的前端的管理" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher" +msgid "Gopher settings" +msgstr "Gopher 设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools" +msgid "Advanced settings for `Hackney` connections pools" +msgstr "「Hackney」连接池的高级设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http" +msgid "HTTP settings" +msgstr "HTTP 设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security" +msgid "HTTP security settings" +msgstr "HTTP 安全设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance" +msgid "Instance-related settings" +msgstr "实例相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instances_favicons" +msgid "Control favicons for instances" +msgstr "控制实例的 favicon" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap" +msgid "Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password will be verified by trying to authenticate (bind) to a LDAP server. If a user exists in the LDAP directory but there is no account with the same name yet on the Pleroma instance then a new Pleroma account will be created with the same name as the LDAP user name." +msgstr "" +"用 LDAP 作用户鉴权。当用户登录进 Pleroma 实例时,会通过向 LDAP " +"服务器尝试鉴权(绑定)来验证名字和密码。如果用户在 LDAP 目录里,但同名账号在 " +"Pleroma 实例里还不存在,那么就会创建一个新的 Pleroma 账号,它的名字和 LDAP " +"用户名一样。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:majic_pool" +msgid "Majic/libmagic configuration" +msgstr "Majic/libmagic 配置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format, fuzzy +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。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "媒体预览代理" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "媒体代理" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format, fuzzy +msgctxt "config description at :pleroma-:modules" +msgid "Custom Runtime Modules" +msgstr "自定义 Runtime 模块" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf" +msgid "General MRF settings" +msgstr "通用 MRF 设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_activity_expiration" +msgid "Adds automatic expiration to all local activities" +msgstr "给所有本地 activity 添加自动过期" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_follow_bot" +msgid "Automatically follows newly discovered accounts." +msgstr "自动关注新发现的账号。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag" +msgid "Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)\n\nNote: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.\n" +msgstr "" +"把带有特定标签(不带开头#号)的讯息拒绝,从已知网络里删除或者设成敏感的\n" +"\n" +"注:这个 MRF 策略总是开启的,如果你想禁用它,你得设置成空列表。\n" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread" +msgid "Block messages with excessive user mentions" +msgstr "屏蔽提及太多用户的讯息" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword" +msgid "Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html)." +msgstr "对匹配一个关键词或者[正则](https://hexdocs.pm/elixir/Regex." +"html)的讯息拒绝或替换词语。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_mention" +msgid "Block messages which mention a specific user" +msgstr "拒绝提及特定用户的讯息" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_normalize_markup" +msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age" +msgid "Rejects or delists posts based on their timestamp deviance from your server's clock." +msgstr "基于时间戳和服务器时钟的差距而拒绝或除列文章。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic" +msgid "RejectNonPublic drops posts with non-public visibility settings." +msgstr "RejectNonPublic 丢弃有非公开的可见性设置的文章。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple" +msgid "Simple ingress policies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji" +msgid "Steals emojis from selected instances when it sees them." +msgstr "从选择的实例偷取看到的 emoji。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary" +msgid "Filter messages which belong to certain activity vocabularies" +msgstr "过滤属于特定 activity 词汇的讯息" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2" +msgid "Configure OAuth 2 provider capabilities" +msgstr "配置 OAuth 2 提供者的能力" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools" +msgid "Advanced settings for `Gun` workers pools" +msgstr "「Gun」工人池的高级设置" + +#: 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」后台迁移设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit" +msgid "Rate limit settings. This is an advanced feature enabled only for :authentication by default." +msgstr "频率限制设置。这是高级特性,默认只对 :authentication (鉴权)开启。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated" +msgid "Disallow viewing timelines, user profiles and statuses for unauthenticated users." +msgstr "不允许未被鉴权的用户查看时间线、用户主页和状态。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media" +msgid "If enabled the instance will parse metadata from attached links to generate link previews" +msgstr "如果开启,实例会从附上的链接里析出元数据来生成链接预览" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout" +msgid "Pleroma shout settings" +msgstr "Pleroma 留言板设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:static_fe" +msgid "Render profiles and posts using server-generated HTML that is viewable without using JavaScript" +msgstr "用服务器生成的,不用 JavaScript 就可以查看的 HTML 来渲染用户页和文章" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer" +msgid "Settings for notifications streamer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:uri_schemes" +msgid "URI schemes related settings" +msgstr "" + +#: 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」来禁用过期。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome" +msgid "Welcome messages settings" +msgstr "欢迎讯息设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:workers" +msgid "Includes custom worker options not interpretable directly by `Oban`" +msgstr "包含不能直接被「Oban」解读的自定工人选项" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter" +msgid "Limits configuration for background tasks." +msgstr "后台任务的限制的配置。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban" +msgid "[Oban](https://github.com/sorentwo/oban) asynchronous job processor configuration." +msgstr "[Oban](https://github.com/sorentwo/oban) 异步工作处理器的配置。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha" +msgid "Captcha-related settings" +msgstr "验证码相关设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Kocaptcha is a very simple captcha service with a single API endpoint, the source code is here: https://github.com/koto-bank/kocaptcha. The default endpoint (https://captcha.kotobank.ch) is hosted by the developer." +msgstr "" +"Kocaptcha 是一个非常简单的验证码服务,只有一个 API 终点,源码在此: " +"https://github.com/koto-bank/kocaptcha 。默认终点( https://" +"captcha.kotobank.ch )由开发者托管。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer" +msgid "Mailer-related settings" +msgstr "邮递员相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "New users admin email digest" +msgstr "新用户管理邮件摘要" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail" +msgid "Email template settings" +msgstr "邮件模板设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter" +msgid "Configuration for Pleroma's link formatter which parses mentions, hashtags, and URLs." +msgstr "这是 Pleroma 的链接格式器的具体设定,可在此配置提及,标签与网址等。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity" +msgid "Scheduled activities settings" +msgstr "定时活动设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload" +msgid "Upload general settings" +msgstr "上传通用设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename" +msgid "Filter replaces the filename of the upload" +msgstr "过滤器将会匿名化上传文件的文件名" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify" +msgid "Uploads mogrify filter settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local" +msgid "Local uploader-related settings" +msgstr "本地上传器相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3" +msgid "S3 uploader-related settings" +msgstr "S3 上传器相关设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup" +msgid "Account Backup" +msgstr "账户备份" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http" +msgid "HTTP invalidate settings" +msgstr "HTTP 无效化设置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script" +msgid "Invalidation script settings" +msgstr "无效的脚本设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata" +msgid "Metadata-related settings" +msgstr "元数据相关设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Preload" +msgid "Preload-related settings" +msgstr "预加载相关设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Expired activities settings" +msgstr "失效活动设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter" +msgid "Prometheus app metrics endpoint configuration" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3" +msgid "S3" +msgstr "S3" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console" +msgid "Console Logger" +msgstr "终端日志器" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger" +msgid "ExSyslogger" +msgstr "ExSyslogger" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub" +msgid "ActivityPub" +msgstr "ActivityPub" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets" +msgid "Assets" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth" +msgid "Auth" +msgstr "验证" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool" +msgid "Connections pool" +msgstr "连接池" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications" +msgid "Email notifications" +msgstr "邮件通知" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji" +msgid "Emoji" +msgstr "Emoji" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:features" +msgid "Features" +msgstr "特性" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed" +msgid "Feed" +msgstr "信息流" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations" +msgid "Frontend configurations" +msgstr "前端配置" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends" +msgid "Frontends" +msgstr "前端" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher" +msgid "Gopher" +msgstr "Gopher" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools" +msgid "Hackney pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http" +msgid "HTTP" +msgstr "HTTP" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security" +msgid "HTTP security" +msgstr "HTTP 安全性" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance" +msgid "Instance" +msgstr "实例" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instances_favicons" +msgid "Instances favicons" +msgstr "实例图标" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap" +msgid "LDAP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:majic_pool" +msgid "Majic pool" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest" +msgid "Manifest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup" +msgid "Markup Settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy" +msgid "Media preview proxy" +msgstr "媒体文件预览代理" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy" +msgid "Media proxy" +msgstr "媒体文件代理" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:modules" +msgid "Modules" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf" +msgid "MRF" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_activity_expiration" +msgid "MRF Activity Expiration Policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_follow_bot" +msgid "MRF FollowBot Policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag" +msgid "MRF Hashtag" +msgstr "MRF 标签" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread" +msgid "MRF Hellthread" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword" +msgid "MRF Keyword" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_mention" +msgid "MRF Mention" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_normalize_markup" +msgid "MRF Normalize Markup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age" +msgid "MRF Object Age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic" +msgid "MRF Reject Non Public" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple" +msgid "MRF Simple" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji" +msgid "MRF Emojis" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_subchain" +msgid "MRF Subchain" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary" +msgid "MRF Vocabulary" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2" +msgid "OAuth2" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools" +msgid "Pools" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table" +msgid "Populate hashtags table" +msgstr "本站话题标签列表" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit" +msgid "Rate limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated" +msgid "Restrict Unauthenticated" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media" +msgid "Rich media" +msgstr "富媒体" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout" +msgid "Shout" +msgstr "留言板" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:static_fe" +msgid "Static FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer" +msgid "Streamer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:uri_schemes" +msgid "URI Schemes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:user" +msgid "User" +msgstr "用户" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl" +msgid "Web cache TTL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome" +msgid "Welcome" +msgstr "欢迎" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:workers" +msgid "Workers" +msgstr "工人" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter" +msgid "ConcurrentLimiter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban" +msgid "Oban" +msgstr "Oban" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha" +msgid "Pleroma.Captcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha" +msgid "Pleroma.Captcha.Kocaptcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer" +msgid "Pleroma.Emails.Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail" +msgid "Pleroma.Emails.NewUsersDigestEmail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail" +msgid "Pleroma.Emails.UserEmail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter" +msgid "Linkify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity" +msgid "Pleroma.ScheduledActivity" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload" +msgid "Pleroma.Upload" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local" +msgid "Pleroma.Uploaders.Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3" +msgid "Pleroma.Uploaders.S3" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User" +msgid "Pleroma.User" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup" +msgid "Pleroma.User.Backup" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata" +msgid "Pleroma.Web.Metadata" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Preload" +msgid "Pleroma.Web.Preload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity" +msgid "Pleroma.Workers.PurgeExpiredActivity" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details" +msgid "Vapid Details" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :enabled" +msgid "Enables SSH" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :handler" +msgid "Handler module" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :password_authenticator" +msgid "Authenticator module" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :port" +msgid "Port to connect" +msgstr "用于连接的端口" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :esshd > :priv_dir" +msgid "Dir with SSH keys" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :access_key_id" +msgid "S3 access key ID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :host" +msgid "S3 host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :ex_aws-:s3 > :region" +msgid "S3 region (for AWS)" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:console > :level" +msgid "Log level" +msgstr "日志等级" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger > :format" +msgid "Default: \"$date $time [$level] $levelpad$node $metadata $message\"" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :logger-:ex_syslogger > :level" +msgid "Log level" +msgstr "日志等级" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma > :admin_token" +msgid "Admin token" +msgstr "管理令牌" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :blockers_visible" +msgid "Whether a user can see someone who has blocked them" +msgstr "用户能否查看屏蔽了他们的用户" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Following handshake timeout" +msgstr "关注请求超时" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :note_replies_output_limit" +msgid "The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :outgoing_blocks" +msgid "Whether to federate blocks to other instances" +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:activitypub > :unfollow_blocked" +msgid "Whether blocks result in people getting unfollowed" +msgstr "屏蔽对象时是否同时取消对其的关注" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:assets > :default_user_avatar" +msgid "URL of the default user avatar" +msgstr "默认用户头像的网址" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "OAuth admin scope requirement toggle. If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token (client app must support admin scopes). If disabled and token doesn't have admin scope(s), `is_admin` user flag grants access to admin-specific actions." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :oauth_consumer_strategies" +msgid "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable. Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\" (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to `lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Number of attempts to acquire the connection from the pool if it is overloaded. Default: 5" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Timeout to acquire a connection from pool. The total max time is this value multiplied by the number of retries. Default: 250ms." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Multiplier for the number of idle connection to be reclaimed if the pool is full. For example if the pool maxes out at 250 connections and this setting is set to 0.3, the pool will reclaim at most 75 idle connections if it's overloaded. Default: 0.1" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest" +msgid "emails of \"what you've missed\" for users who have been inactive for a while" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :active" +msgid "Globally enable or disable digest emails" +msgstr "完全开启或关闭摘要邮件" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Minimum user inactivity threshold" +msgstr "非活跃用户数量最低门槛" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:email_notifications > :digest > :interval" +msgid "Minimum interval between digest emails to one user" +msgstr "单个用户每次收到摘要邮件的间隔" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:emoji > :groups" +msgid "Emojis are ordered in groups (tags). This is an array of key-value pairs where the key is the group name and the value is the location or array of locations. * can be used as a wildcard." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:emoji > :pack_extensions" +msgid "A list of file extensions for emojis, when no emoji.txt for a pack is present" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:features > :improved_hashtag_timeline" +msgid "Setting to force toggle / force disable improved hashtags timeline. `:enabled` forces hashtags to be fetched from `hashtags` table for hashtags timeline. `:disabled` forces object-embedded hashtags to be used (slower). Keep it `:auto` for automatic behaviour (it is auto-set to `:enabled` [unless overridden] when HashtagsTableMigrator completes)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title" +msgid "Configure title rendering" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title > :max_length" +msgid "Maximum number of characters before truncating title" +msgstr "不被折叠的用户名的字数上限" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:feed > :post_title > :omission" +msgid "Replacement which will be used after truncating string" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Settings for Pleroma FE" +msgstr "Pleroma FE 设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "When disabled, auto-hide the subject field if it's empty" +msgstr "当被停用时,自动隐藏未被填写的标题栏" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "URL of the background, unless viewing a user profile with a background that is set" +msgstr "输入背景的网址,若浏览已设定背景的用户资料时此处将不生效" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "When a message has a subject (aka Content Warning), collapse it by default" +msgstr "默认状态下,将自动折叠带有标题的信息(内容警告)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Enables green text on lines prefixed with the > character" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hides filtered statuses from timelines" +msgstr "从时间线上隐藏被过滤的状态" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hides muted statuses from timelines" +msgstr "从时间线上折叠被隐藏的状态" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide notices statistics (repeats, favorites, ...)" +msgstr "关闭互动提醒(转发,点赞等)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hides instance name from PleromaFE banner" +msgstr "在 PleromaFE 横幅上隐藏实例名称" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide profile statistics (posts, posts per day, followers, followings, ...)" +msgstr "隐藏账号页面数据(发文数量、平均每日发文数量、关注者数量、正在关注数量等)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "URL of the logo, defaults to Pleroma's logo" +msgstr "输入指定 logo 的链接,默认下为 Pleroma 的 logo" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Allows you to adjust vertical margins between logo boundary and navbar borders. The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout." +msgstr "您可以自定义 logo 与导航栏边界之间的垂直间隔。此功能是为了去除多余的 logo " +"间隔,允许您根据自己所需来调整布局。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. If you want a colorful logo you must disable logoMask." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Limit scope selection to Direct, User default, and Scope of post replying to. Also prevents replying to a DM with a public post from PleromaFE." +msgstr "可见范围选项将只保留私信与用户默认,或是跟随被回复帖文的设定。这能够帮助 " +"Pleroma FE 的用户不会意外将对私信的回复设置为公开。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "URL of the image to use for hiding NSFW media attachments in the timeline" +msgstr "在此指定用于隐藏出现在时间线上 NSFW 媒体文件的遮罩图片链接" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Default post formatting option" +msgstr "贴文格式默认选项" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Relative URL which indicates where to redirect when a user is logged in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Relative URL which indicates where to redirect when a user isn't logged in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Copy the scope (private/unlisted/public) in replies to posts by default" +msgstr "回复的可见范围(仅关注者/不公开/公开)将默认跟随原贴文的设定" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Enables panel displaying functionality of the instance on the About page" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Whether to show the instance's custom panel" +msgstr "是否展示该实例的自定义面板" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Change alignment of sidebar and panels to the right" +msgstr "将面板与侧栏向右对齐" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Allows changing the default behaviour of subject lines in replies.\n `email`: copy and preprend re:, as in email,\n `masto`: copy verbatim, as in Mastodon,\n `noop`: don't copy the subject." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Which theme to use. Available themes are defined in styles.json" +msgstr "使用某个主题。styles.json 中已限定了可用的主题" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :admin" +msgid "Admin frontend" +msgstr "管理员前端" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "已安装的前端名称。只有包含了「名称」与「引用」数值才能被算作有效配置。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :admin > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available" +msgid "A map containing available frontends and parameters for their installation." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > build_dir" +msgid "The directory inside the zip file " +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > build_url" +msgid "Either an url to a zip file containing the frontend or a template to build it by inserting the `ref`. The string `${ref}` will be replaced by the configured `ref`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > custom-http-headers" +msgid "The custom HTTP headers for the frontend" +msgstr "" + +#: 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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > name" +msgid "Name of the frontend." +msgstr "前端名称。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :available > ref" +msgid "Reference of the frontend to be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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 "" + +#: 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 "已安装的前端名称。只有包含了「名称」与「引用」数值才能被算作有效配置。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:frontends > :primary > ref" +msgid "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :dstport" +msgid "Port advertised in URLs (optional, defaults to port)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :enabled" +msgid "Enables the gopher interface" +msgstr "启用 gopher 界面" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :ip" +msgid "IP address to bind to" +msgstr "指定绑定IP地址" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:gopher > :port" +msgid "Port to bind to" +msgstr "指定绑定端口" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Number workers in the pool." +msgstr "池内的工人数量。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media" +msgid "Settings for media pool." +msgstr "媒体池设定。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Number workers in the pool." +msgstr "池内的工人数量。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Number workers in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout while `hackney` will wait for response." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter" +msgid "Adapter specific options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL options for HTTP adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "List of TLS version to use" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "代理网址" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http > :user_agent" +msgid "What user agent to use. Must be a string or an atom `:default`. Default value is `:default`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :ct_max_age" +msgid "The maximum age for the Expect-CT header if sent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :enabled" +msgid "Whether the managed content security policy is enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :referrer_policy" +msgid "The referrer policy to use, either \"same-origin\" or \"no-referrer\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :report_uri" +msgid "Adds the specified URL to report-uri and report-to group in CSP header" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :sts" +msgid "Whether to additionally send a Strict-Transport-Security header" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:http_security > :sts_max_age" +msgid "The maximum age for the Strict-Transport-Security header if sent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_activation_required" +msgid "Require users to confirm their emails before signing in" +msgstr "要求用户登陆时必须确认邮件" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_approval_required" +msgid "Require users to be manually approved by an admin before signing in" +msgstr "用户登陆需要管理员同意" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_field_name_length" +msgid "An account field name maximum length. Default: 512." +msgstr "单个用户信息名称的字数上限。默认为512。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :account_field_value_length" +msgid "An account field value maximum length. Default: 2048." +msgstr "单个用户信息内容的字数上限。默认为2048。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :allow_relay" +msgid "Permits remote instances to subscribe to all public posts of your instance. (Important!) This may increase the visibility of your instance." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :allowed_post_formats" +msgid "MIME-type list of formats allowed to be posted (transformed into HTML)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :attachment_links" +msgid "Enable to automatically add attachment link text to statuses" +msgstr "启用此功能将自动添加附件链接至状态中" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :autofollowed_nicknames" +msgid "Set to nicknames of (local) users that every new user should automatically follow" +msgstr "为会被新用户自动关注的(本地)用户设定昵称" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :autofollowing_nicknames" +msgid "Set to nicknames of (local) users that automatically follows every newly registered user" +msgstr "为会自动关注每一个新用户的(本地)用户设定昵称" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :avatar_upload_limit" +msgid "File size limit of user's profile avatars" +msgstr "用户头像的文件大小上限" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :background_upload_limit" +msgid "File size limit of user's profile backgrounds" +msgstr "用户资料背景的文件大小上限" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :banner_upload_limit" +msgid "File size limit of user's profile banners" +msgstr "用户资料横幅的文件大小上限" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :birthday_min_age" +msgid "Minimum required age for users to create account. Only used if birthday is required." +msgstr "创建账户的最低年龄限制。只有当需要输入生日时才生效。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :birthday_required" +msgid "Require users to enter their birthday." +msgstr "要求用户输入出生日期。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :cleanup_attachments" +msgid "Enable to remove associated attachments when status is removed.\nThis will not affect duplicates and attachments without status.\nEnabling this will increase load to database when deleting statuses on larger instances.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :description" +msgid "The instance's description. It can be seen in nodeinfo and `/api/v1/instance`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :email" +msgid "Email used to reach an Administrator/Moderator of the instance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :extended_nickname_format" +msgid "Enable to use extended local nicknames format (allows underscores/dashes). This will break federation with older software for theses nicknames." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :external_user_synchronization" +msgid "Enabling following/followers counters synchronization for external users" +msgstr "为外部用户启用对关注者与正在关注数量的同步" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federating" +msgid "Enable federation with other instances" +msgstr "启用与其他实例的联邦互通" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Max. depth of reply-to and reply activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Timeout (in days) of each external federation target being unreachable prior to pausing federating to it" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format, fuzzy +msgctxt "config description at :pleroma-:instance > :healthcheck" +msgid "If enabled, system data will be shown on `/api/pleroma/healthcheck`" +msgstr "若启用,「/api/pleroma/healthcheck」下将显示系统数据" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :instance_thumbnail" +msgid "The instance thumbnail can be any image that represents your instance and is used by some apps or services when they display information about your instance." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, 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」选项)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :limit" +msgid "Posts character limit (CW/Subject included in the counter)" +msgstr "贴文字数上限(内容警告/标题包含在内)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :limit_to_local_content" +msgid "Limit unauthenticated users to search for local statutes and users only. Default: `:unauthenticated`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_account_fields" +msgid "The maximum number of custom fields in the user profile. Default: 10." +msgstr "用户资料中可展示的自定用户信息最大上限。默认为10。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_endorsed_users" +msgid "The maximum number of recommended accounts. 0 will disable the feature." +msgstr "推荐账户的最大数量。设置为0将关闭该功能。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_media_attachments" +msgid "Maximum number of post media attachments" +msgstr "最多可上传的媒体文件数量" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_pinned_statuses" +msgid "The maximum number of pinned statuses. 0 will disable the feature." +msgstr "可被置顶的状态数量上限。设定为0则关闭该功能。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_remote_account_fields" +msgid "The maximum number of custom fields in the remote user profile. Default: 20." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :max_report_comment_size" +msgid "The maximum size of the report comment. Default: 1000." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi-factor authentication settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "MFA backup codes settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Determines the length of backup one-time pass-codes, in characters. Defaults to 16 characters." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number of backup codes to generate." +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 "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Determines the length of a one-time pass-code, in characters. Defaults to 6 characters." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "A period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :name" +msgid "Name of the instance" +msgstr "实例名称" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :notify_email" +msgid "Envelope FROM address for mail sent via Pleroma" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits" +msgid "A map with poll limits for local polls" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Maximum expiration time (in seconds)" +msgstr "最大有效时间(以秒为单位)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Maximum number of characters per option" +msgstr "单个选项的字数上限" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :max_options" +msgid "Maximum number of options" +msgstr "选项数量上限" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Minimum expiration time (in seconds)" +msgstr "最小有效时间(以秒为单位)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format, fuzzy +msgctxt "config description at :pleroma-:instance > :privileged_staff" +msgid "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" +msgstr "允许管理员访问敏感信息(例,更新用户凭据、取得密码重置令牌、删除用户、能够索" +"引并阅览私密状态与聊天信息)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :profile_directory" +msgid "Enable profile directory." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :public" +msgid "Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note: when setting to `false`, please also check `:restrict_unauthenticated` setting." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :quarantined_instances" +msgid "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :registration_reason_length" +msgid "Maximum registration reason length. Default: 500." +msgstr "申请注册理由的字数上限。默认为500。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :registrations_open" +msgid "Enable registrations for anyone. Invitations require this setting to be disabled." +msgstr "开放注册。若要启用邀请制注册则需关闭此项。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :remote_limit" +msgid "Hard character limit beyond which remote posts will be dropped" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :remote_post_retention_days" +msgid "The default amount of days to retain remote posts when pruning the database" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :safe_dm_mentions" +msgid "If enabled, only mentions at the beginning of a post will be used to address people in direct messages. This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\"). Default: disabled" +msgstr "" +"启用后,只有处于私信最开头的用户名才会被提及。这将有助于防止意外提及不想要的" +"用户(例,“@admin 请留意 @bad_actor”)。默认下为关闭状态" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format, fuzzy +msgctxt "config description at :pleroma-:instance > :show_reactions" +msgid "Let favourites and emoji reactions be viewed through the API." +msgstr "允许通过此API来看见喜欢数量与表情反应。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :skip_thread_containment" +msgid "Skip filtering out broken threads. Default: enabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :static_dir" +msgid "Instance static directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :upload_limit" +msgid "File size limit of uploads (except for avatar, background, banner)" +msgstr "上传文件大小上限(不包括头像、背景与横幅)" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :user_bio_length" +msgid "A user bio maximum length. Default: 5000." +msgstr "用户自传的字数上限。默认为5000。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instance > :user_name_length" +msgid "A user name maximum length. Default: 100." +msgstr "用户名的字数上限。默认为100。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:instances_favicons > :enabled" +msgid "Allow/disallow displaying and getting instances favicons" +msgstr "允许/不允许获取并展示实例图标" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :base" +msgid "LDAP base, e.g. \"dc=example,dc=com\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :enabled" +msgid "Enables LDAP authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :host" +msgid "LDAP server hostname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :port" +msgid "LDAP port, e.g. 389 or 636" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :ssl" +msgid "Enable to use SSL, usually implies the port 636" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts" +msgid "Additional SSL options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :sslopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tls" +msgid "Enable to use STARTTLS, usually implies the port 389" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts" +msgid "Additional TLS options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Path to file with PEM encoded cacerts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :tlsopts > :verify" +msgid "Type of cert verification" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:ldap > :uid" +msgid "LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:majic_pool > :size" +msgid "Number of majic workers to start." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :background_color" +msgid "Describe the background color of the app" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :icons" +msgid "Describe the icons of the app" +msgstr "描述此应用的图标" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:manifest > :theme_color" +msgid "Describe the theme color of the app" +msgstr "描述此应用的主题颜色" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:markup > :scrub_policy" +msgid "Module names are shortened (removed leading `Pleroma.HTML.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :enabled" +msgid "Enables proxying of remote media preview to the instance's proxy. Requires enabled media proxy." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :image_quality" +msgid "Quality of the output. Ranges from 0 (min quality) to 100 (max quality)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length (in bytes) to perform preview. Media smaller in size will be served without thumbnailing." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Max height of preview thumbnail for images (video preview always has original dimensions)." +msgstr "图像的生成预览缩略图的长度上限(视频预览则始终保持原始尺寸)。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Max width of preview thumbnail for images (video preview always has original dimensions)." +msgstr "图像的生成预览缩略图的宽度上限(视频预览则始终保持原始尺寸)。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :base_url" +msgid "The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :enabled" +msgid "Enables proxying of remote media via the instance's proxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enables media cache object invalidation." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Module which will be used to purge objects from the cache." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts" +msgid "Internal Pleroma.ReverseProxy settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Maximum file size (in bytes) allowed through the Pleroma MediaProxy cache." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Timeout (in milliseconds) of GET request to the remote URI." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirects the client to the origin server upon encountering HTTP errors.\n\nNote that files larger than Max Body Length will trigger an error. (e.g., Peertube videos)\n\n\n**WARNING:** This setting will allow larger files to be accessed, but exposes the\n\nIP addresses of your users to the other servers, bypassing the MediaProxy.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:media_proxy > :whitelist" +msgid "List of hosts with scheme to bypass the MediaProxy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:modules > :runtime_dir" +msgid "A path to custom Elixir modules (such as MRF policies)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :policies" +msgid "A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :transparency" +msgid "Make the content of your Message Rewrite Facility settings public (via nodeinfo)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf > :transparency_exclusions" +msgid "Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. You can also provide a reason for excluding these instance names. The instances and reasons won't be publicly disclosed." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_activity_expiration > :days" +msgid "Default global expiration time for all local activities (in days)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "The name of the bot account to use for following newly discovered users." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :reject" +msgid "A list of hashtags which result in message being rejected." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hashtag > :sensitive" +msgid "A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Number of mentioned users after which the message gets removed from timelines anddisables notifications. Set to 0 to disable." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Number of mentioned users after which the messaged gets rejected. Set to 0 to disable." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid " A list of patterns which result in message being removed from federated timelines (a.k.a unlisted).\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :reject" +msgid " A list of patterns which result in message being rejected.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_keyword > :replace" +msgid " **Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n\n **Replacement**: a string. Leaving the field empty is permitted.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_mention > :actors" +msgid "A list of actors for which any post mentioning them will be dropped" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age > :actions" +msgid "A list of actions to apply to the post. `:delist` removes the post from public timelines; `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; `:reject` rejects the message entirely" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_object_age > :threshold" +msgid "Required age (in seconds) of a post before actions are taken." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Whether to allow direct messages" +msgstr "是否允许私信" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Whether to allow followers-only posts" +msgstr "是否允许仅限关注者的帖文" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :accept" +msgid "List of instances to only accept activities from (except deletes) and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :avatar_removal" +msgid "List of instances to strip avatars from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :banner_removal" +msgid "List of instances to strip banners from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "List of instances to remove from the Federated (aka The Whole Known Network) Timeline and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :followers_only" +msgid "Force posts from the given instances to be visible by followers only and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :media_nsfw" +msgid "List of instances to tag all media as NSFW (sensitive) from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :media_removal" +msgid "List of instances to strip media attachments from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :reject" +msgid "List of instances to reject activities from (except deletes) and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :reject_deletes" +msgid "List of instances to reject deletions from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_simple > :report_removal" +msgid "List of instances to reject reports from and the reason for doing so" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :hosts" +msgid "List of hosts to steal emojis from" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid " A list of patterns or matches to reject shortcodes with.\n\n Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "File size limit (in bytes), checked before an emoji is saved to the disk" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_subchain > :match_actor" +msgid "Matches a series of regular expressions against the actor field" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary > :accept" +msgid "A list of ActivityStreams terms to accept. If empty, all supported messages are accepted." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:mrf_vocabulary > :reject" +msgid "A list of ActivityStreams terms to reject. If empty, no messages are rejected." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Enable a background job to clean expired OAuth tokens. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Keeps old refresh token or generate new refresh token when to obtain an access token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:oauth2 > :token_expires_in" +msgid "The lifetime in seconds of the access token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default" +msgid "Settings for default pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :default > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation" +msgid "Settings for federation pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :federation > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media" +msgid "Settings for media pool." +msgstr "媒体池设定。" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :media > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload" +msgid "Settings for upload pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :max_waiting" +msgid "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :recv_timeout" +msgid "Timeout for the pool while gun will wait for response" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:pools > :upload > :size" +msgid "Maximum number of concurrent requests in the pool." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if hashtags transfer failed for all records." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :app_account_creation" +msgid "For registering user accounts from the same IP address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :authentication" +msgid "For authentication create / password check / user existence check requests" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :relation_id_action" +msgid "For actions on relation with a specific user (follow, unfollow)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :relations_actions" +msgid "For actions on relationships with all users (follow, unfollow)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :search" +msgid "For the search requests (account & status search etc.)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :status_id_action" +msgid "For fav / unfav or reblog / unreblog actions on the same status by the same user" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :statuses_actions" +msgid "For create / delete / fav / unfav / reblog / unreblog actions on any statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rate_limit > :timeline" +msgid "For requests to timelines (each timeline has it's own limiter)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities" +msgid "Settings for statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Disallow view local statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Disallow view remote statuses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Settings for user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Disallow view local user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Disallow view remote user profiles." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Settings for public and federated timelines." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Disallow view federated timeline." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Disallow view public timeline." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :enabled" +msgid "Enables RichMedia parsing of URLs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :failure_backoff" +msgid "Amount of milliseconds after request failure, during which the request will not be retried." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ignore_hosts" +msgid "List of hosts which will be ignored by the metadata parser" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ignore_tld" +msgid "List TLDs (top-level domains) which will ignore for parse metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :parsers" +msgid "List of Rich Media parsers. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parsers.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:rich_media > :ttl_setters" +msgid "List of rich media TTL setters. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parser.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout > :enabled" +msgid "Enables the backend Shoutbox chat feature." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:shout > :limit" +msgid "Shout message character limit." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:static_fe > :enabled" +msgid "Enables the rendering of static HTML. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer > :overflow_workers" +msgid "Maximum number of workers created if pool is empty" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:streamer > :workers" +msgid "Number of workers to send notifications" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:uri_schemes > :valid_schemes" +msgid "List of the scheme part that is considered valid to be an URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub routes (except question activities). Default: `nil` (no expiration)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub routes (question activities). Default: `30_000` (30 seconds)." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enables sending a chat message to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :message" +msgid "A message that will be sent to newly registered users as a chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enables sending a direct message to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :message" +msgid "A message that will be sent to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "The nickname of the local user that sends a welcome message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :enabled" +msgid "Enables sending an email to newly registered users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :html" +msgid "HTML content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :sender" +msgid "Email address and/or nickname that will be used to send the welcome email." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :subject" +msgid "Subject of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:welcome > :email > :text" +msgid "Text content of the welcome email. EEX template with user and instance_name variables can be used." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-:workers > :retries" +msgid "Max retry attempts for failed jobs, per `Oban` queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Concurrent limits configuration for MediaProxyWarmingPolicy." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Concurrent limits configuration for getting RichMedia for activities." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running concurrently jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting jobs." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :crontab" +msgid "Settings for cron background jobs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :log" +msgid "Logs verbose mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues" +msgid "Background jobs queues (keys: queues, values: max numbers of concurrent jobs)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachment deletion queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :background" +msgid "Background queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :backup" +msgid "Backup queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :federator_incoming" +msgid "Incoming federation queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Outgoing federation queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :mailer" +msgid "Email sender queue, see Pleroma.Emails.Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities queue, see Pleroma.ScheduledActivities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Oban > :queues > :web_push" +msgid "Web push notifications queue" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :enabled" +msgid "Whether the captcha should be shown on registration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :method" +msgid "The method/service to use for captcha" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "The time in seconds for which the captcha is valid" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "The kocaptcha endpoint to use" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "One of the mail adapters listed in [Swoosh documentation](https://hexdocs.pm/swoosh/Swoosh.html#module-adapters)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "SMTP AUTH enforcement mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "SMTP AUTH password" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "SMTP port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Hostname or IP address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "SMTP temporary (4xx) error retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use Implicit SSL/TLS. e.g. port 465" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "Explicit TLS (STARTTLS) enforcement mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "SMTP AUTH username" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enables new users admin digest email when `true`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "A path to a custom logo. Set it to `nil` to use the default Pleroma logo." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "A map with color settings for email templates." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :class" +msgid "Specify the class to be added to the generated link. Disable to clear." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :extra" +msgid "Link URLs with rarely used schemes (magnet, ipfs, irc, etc.)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :new_window" +msgid "Link URLs will open in a new window/tab." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :rel" +msgid "Override the rel attribute. Disable to clear." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip the scheme prefix." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :truncate" +msgid "Set to a number to truncate URLs longer than the number. Truncated URLs will end in `...`" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Set to false to disable TLD validation for URLs/emails. Can be set to :no_scheme to validate TLDs only for URLs without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "The number of scheduled activities a user is allowed to create in a single day. Default: 25." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Whether scheduled activities are sent to the job queue to be executed" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "The number of scheduled activities a user is allowed to create in total. Default: 300." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL for the uploads. Required if you use a CDN or host attachments under a different domain." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Set max length of a filename to display. 0 = no limit. Default: 30" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :filters" +msgid "List of filter modules for uploads. Module names are shortened (removed leading `Pleroma.Upload.Filter.` part), but on adding custom module you need to use full name." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :link_name" +msgid "If enabled, a name parameter will be added to the URL of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy requests to the remote uploader.\n\nUseful if media upload endpoint is not internet accessible.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload > :uploader" +msgid "Module which will be used for uploads" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text to replace filenames in links. If no setting, {random}.extension will be used. You can get the original filename extension by using {extension}, for example custom-file-name.{extension}." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "List of actions for the mogrify command. It's possible to add self-written settings as string. For example `auto-orient, strip, {\"resize\", \"3840x1080>\"}` value will be parsed into valid list of the settings." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Path where user's uploads will be saved" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "S3 bucket" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "S3 bucket namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc. For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in Upload base_url." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User > :email_blacklist" +msgid "List of email domains users may not register with." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "List of nicknames users may not register with." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit user to export not more often than once per N days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Remove backup achives after N days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Enables strict input validation (useful in development, not recommended in production)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "HTTP headers of request" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "HTTP method of request. Default: :purge" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Request options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Path to executable script which will purge cached items." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "Optional URL format preprocessing. Only required for Apache's htcacheclean." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "List of metadata providers to enable" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "When enabled NSFW attachments will be shown in previews" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enable/disable the plug. Default: disabled." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid " A list of strings naming the HTTP headers to use when deriving the true client IP. Default: `[\"x-forwarded-for\"]`.\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "A list of upstream proxy IP subnets in CIDR notation from which we will parse the content of `headers`. Defaults to `[]`. IPv4 entries without a bitmask will be assumed to be /32 and IPv6 /128." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid " A list of reserved IP subnets in CIDR notation which should be ignored if found in `headers`. Defaults to `[\"127.0.0.0/8\", \"::1/128\", \"fc00::/7\", \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"]`\n" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Web.Preload > :providers" +msgid "List of preload providers to enable" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enables expired activities addition & deletion" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Minimum lifetime for ephemeral activity (in seconds)" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Enables HTTP Basic Auth for app metrics endpoint." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "[Pleroma extension] Enables app metrics endpoint." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "App metrics endpoint output format." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "Restrict access of app metrics endpoint to the specified IP addresses." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "App metrics endpoint URI path." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :level" +msgid "Log level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :meta" +msgid "Configure which metadata you want to report on" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :quack > :webhook_url" +msgid "Configure the Slack incoming webhook" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :private_key" +msgid "VAPID private key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :public_key" +msgid "VAPID public key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config description at :web_push_encryption-:vapid_details > :subject" +msgid "A mailto link for the administrative contact. It's best if this email is not a personal email address, but rather a group email to the instance moderation team." +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :credentials" +msgid "Credentials" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :expose" +msgid "Expose" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :max_age" +msgid "Max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :cors_plug > :methods" +msgid "Methods" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :handler" +msgid "Handler" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :password_authenticator" +msgid "Password authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :esshd > :priv_dir" +msgid "Priv dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :access_key_id" +msgid "Access key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :host" +msgid "Host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :region" +msgid "Region" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :ex_aws-:s3 > :secret_access_key" +msgid "Secret access key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger > :backends" +msgid "Backends" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:console > :metadata" +msgid "Metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :ident" +msgid "Ident" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :logger-:ex_syslogger > :metadata" +msgid "Metadata" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types" +msgid "Types" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/activity+json" +msgid "\"application/activity+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/jrd+json" +msgid "\"application/jrd+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/ld+json" +msgid "\"application/ld+json\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/xml" +msgid "\"application/xml\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :mime > :types > application/xrd+xml" +msgid "\"application/xrd+xml\"" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma > :admin_token" +msgid "Admin token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma > Pleroma.Web.Auth.Authenticator" +msgid "Pleroma.Web.Auth.Authenticator" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :blockers_visible" +msgid "Blockers visible" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :follow_handshake_timeout" +msgid "Follow handshake timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :note_replies_output_limit" +msgid "Note replies output limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :outgoing_blocks" +msgid "Outgoing blocks" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :sign_object_fetches" +msgid "Sign object fetches" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:activitypub > :unfollow_blocked" +msgid "Unfollow blocked" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :default_mascot" +msgid "Default mascot" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :default_user_avatar" +msgid "Default user avatar" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:assets > :mascots" +msgid "Mascots" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :auth_template" +msgid "Auth template" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :enforce_oauth_admin_scope_usage" +msgid "Enforce OAuth admin scope usage" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :oauth_consumer_strategies" +msgid "OAuth consumer strategies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:auth > :oauth_consumer_template" +msgid "OAuth consumer template" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connect_timeout" +msgid "Connect timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_retries" +msgid "Connection acquisition retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :connection_acquisition_wait" +msgid "Connection acquisition wait" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:connections_pool > :reclaim_multiplier" +msgid "Reclaim multiplier" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest" +msgid "Digest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :active" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :inactivity_threshold" +msgid "Inactivity threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :interval" +msgid "Interval" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:email_notifications > :digest > :schedule" +msgid "Schedule" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :default_manifest" +msgid "Default manifest" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :groups" +msgid "Groups" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :pack_extensions" +msgid "Pack extensions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :shared_pack_cache_seconds_per_file" +msgid "Shared pack cache s/file" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:emoji > :shortcode_globs" +msgid "Shortcode globs" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:features > :improved_hashtag_timeline" +msgid "Improved hashtag timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title" +msgid "Post title" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title > :max_length" +msgid "Max length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:feed > :post_title > :omission" +msgid "Omission" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe" +msgid "Pleroma FE" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :alwaysShowSubjectInput" +msgid "Always show subject input" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :background" +msgid "Background" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :collapseMessageWithSubject" +msgid "Collapse message with subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :greentext" +msgid "Greentext" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideFilteredStatuses" +msgid "Hide Filtered Statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideMutedPosts" +msgid "Hide Muted Posts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hidePostStats" +msgid "Hide post stats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideSitename" +msgid "Hide Sitename" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :hideUserStats" +msgid "Hide user stats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logo" +msgid "Logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMargin" +msgid "Logo margin" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :logoMask" +msgid "Logo mask" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :minimalScopesMode" +msgid "Minimal scopes mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :nsfwCensorImage" +msgid "NSFW Censor Image" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :postContentType" +msgid "Post Content Type" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootLogin" +msgid "Redirect root login" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :redirectRootNoLogin" +msgid "Redirect root no login" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :scopeCopy" +msgid "Scope copy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showFeaturesPanel" +msgid "Show instance features panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :showInstanceSpecificPanel" +msgid "Show instance specific panel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :sidebarRight" +msgid "Sidebar on Right" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :subjectLineBehavior" +msgid "Subject line behavior" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontend_configurations > :pleroma_fe > :theme" +msgid "Theme" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin" +msgid "Admin" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :admin > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available" +msgid "Available" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > build_dir" +msgid "Build directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > build_url" +msgid "Build URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > custom-http-headers" +msgid "Custom HTTP headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > git" +msgid "Git Repository URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :available > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary" +msgid "Primary" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary > name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:frontends > :primary > ref" +msgid "Reference" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :dstport" +msgid "Dstport" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :ip" +msgid "IP" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:gopher > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation" +msgid "Federation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :federation > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media" +msgid "Media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :media > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload" +msgid "Upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload > :max_connections" +msgid "Max connections" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:hackney_pools > :upload > :timeout" +msgid "Timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter" +msgid "Adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options" +msgid "SSL Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :adapter > :ssl_options > :versions" +msgid "Versions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :proxy_url" +msgid "Proxy URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :send_user_agent" +msgid "Send user agent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http > :user_agent" +msgid "User agent" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :ct_max_age" +msgid "CT max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :referrer_policy" +msgid "Referrer policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :report_uri" +msgid "Report URI" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :sts" +msgid "STS" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:http_security > :sts_max_age" +msgid "STS max age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_activation_required" +msgid "Account activation required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_approval_required" +msgid "Account approval required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_field_name_length" +msgid "Account field name length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :account_field_value_length" +msgid "Account field value length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :allow_relay" +msgid "Allow relay" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :allowed_post_formats" +msgid "Allowed post formats" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :attachment_links" +msgid "Attachment links" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :autofollowed_nicknames" +msgid "Autofollowed nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :autofollowing_nicknames" +msgid "Autofollowing nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :avatar_upload_limit" +msgid "Avatar upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :background_upload_limit" +msgid "Background upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :banner_upload_limit" +msgid "Banner upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :birthday_min_age" +msgid "Birthday min age" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :birthday_required" +msgid "Birthday required" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :cleanup_attachments" +msgid "Cleanup attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :description" +msgid "Description" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :email" +msgid "Admin Email Address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :extended_nickname_format" +msgid "Extended nickname format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :external_user_synchronization" +msgid "External user synchronization" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federating" +msgid "Federating" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federation_incoming_replies_max_depth" +msgid "Fed. incoming replies max depth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :federation_reachability_timeout_days" +msgid "Fed. reachability timeout days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :healthcheck" +msgid "Healthcheck" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :instance_thumbnail" +msgid "Instance thumbnail" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :invites_enabled" +msgid "Invites enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :limit" +msgid "Limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :limit_to_local_content" +msgid "Limit to local content" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_account_fields" +msgid "Max account fields" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_endorsed_users" +msgid "Max endorsed users" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_media_attachments" +msgid "Max media attachments" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_pinned_statuses" +msgid "Max pinned statuses" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_remote_account_fields" +msgid "Max remote account fields" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :max_report_comment_size" +msgid "Max report comment size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication" +msgid "Multi factor authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes" +msgid "Backup codes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :length" +msgid "Length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :backup_codes > :number" +msgid "Number" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp" +msgid "TOTP settings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :digits" +msgid "Digits" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :multi_factor_authentication > :totp > :period" +msgid "Period" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :name" +msgid "Name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :notify_email" +msgid "Sender Email Address" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits" +msgid "Poll limits" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_expiration" +msgid "Max expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_option_chars" +msgid "Max option chars" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :max_options" +msgid "Max options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :poll_limits > :min_expiration" +msgid "Min expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :privileged_staff" +msgid "Privileged staff" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :profile_directory" +msgid "Profile directory" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :public" +msgid "Public" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :quarantined_instances" +msgid "Quarantined instances" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :registration_reason_length" +msgid "Registration reason length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :registrations_open" +msgid "Registrations open" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :remote_limit" +msgid "Remote limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :remote_post_retention_days" +msgid "Remote post retention days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :safe_dm_mentions" +msgid "Safe DM mentions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :show_reactions" +msgid "Show reactions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :skip_thread_containment" +msgid "Skip thread containment" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :static_dir" +msgid "Static dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :upload_limit" +msgid "Upload limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :user_bio_length" +msgid "User bio length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instance > :user_name_length" +msgid "User name length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:instances_favicons > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :base" +msgid "Base" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :host" +msgid "Host" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :ssl" +msgid "SSL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts" +msgid "SSL options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :sslopts > :verify" +msgid "Verify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tls" +msgid "TLS" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts" +msgid "TLS options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts > :cacertfile" +msgid "Cacertfile" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :tlsopts > :verify" +msgid "Verify" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:ldap > :uid" +msgid "UID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:majic_pool > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :background_color" +msgid "Background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :icons" +msgid "Icons" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:manifest > :theme_color" +msgid "Theme color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_fonts" +msgid "Allow fonts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_headings" +msgid "Allow headings" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_inline_images" +msgid "Allow inline images" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :allow_tables" +msgid "Allow tables" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :image_quality" +msgid "Image quality" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :min_content_length" +msgid "Min content length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_height" +msgid "Thumbnail max height" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_preview_proxy > :thumbnail_max_width" +msgid "Thumbnail max width" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :base_url" +msgid "Base URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation" +msgid "Invalidation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :invalidation > :provider" +msgid "Provider" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts" +msgid "Advanced MediaProxy Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_body_length" +msgid "Max body length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :max_read_duration" +msgid "Max read duration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :proxy_opts > :redirect_on_failure" +msgid "Redirect on failure" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:media_proxy > :whitelist" +msgid "Whitelist" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:modules > :runtime_dir" +msgid "Runtime dir" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :policies" +msgid "Policies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :transparency" +msgid "MRF transparency" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf > :transparency_exclusions" +msgid "MRF transparency exclusions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_activity_expiration > :days" +msgid "Days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_follow_bot > :follower_nickname" +msgid "Follower nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hashtag > :sensitive" +msgid "Sensitive" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread > :delist_threshold" +msgid "Delist threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_hellthread > :reject_threshold" +msgid "Reject threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_keyword > :replace" +msgid "Replace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_mention > :actors" +msgid "Actors" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_normalize_markup > :scrub_policy" +msgid "Scrub policy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age > :actions" +msgid "Actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_object_age > :threshold" +msgid "Threshold" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_direct" +msgid "Allow direct" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_rejectnonpublic > :allow_followersonly" +msgid "Allow followers-only" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :accept" +msgid "Accept" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :avatar_removal" +msgid "Avatar removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :banner_removal" +msgid "Banner removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :federated_timeline_removal" +msgid "Federated timeline removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :followers_only" +msgid "Followers only" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :media_nsfw" +msgid "Media NSFW" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :media_removal" +msgid "Media removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :reject_deletes" +msgid "Reject deletes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_simple > :report_removal" +msgid "Report removal" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :hosts" +msgid "Hosts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :rejected_shortcodes" +msgid "Rejected shortcodes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_steal_emoji > :size_limit" +msgid "Size limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_subchain > :match_actor" +msgid "Match actor" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary > :accept" +msgid "Accept" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:mrf_vocabulary > :reject" +msgid "Reject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :clean_expired_tokens" +msgid "Clean expired tokens" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :issue_new_refresh_token" +msgid "Issue new refresh token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:oauth2 > :token_expires_in" +msgid "Token expires in" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default" +msgid "Default" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :default > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation" +msgid "Federation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :federation > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media" +msgid "Media" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :media > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload" +msgid "Upload" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :recv_timeout" +msgid "Recv timeout" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:pools > :upload > :size" +msgid "Size" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:populate_hashtags_table > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :app_account_creation" +msgid "App account creation" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :authentication" +msgid "Authentication" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :relation_id_action" +msgid "Relation ID action" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :relations_actions" +msgid "Relations actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :search" +msgid "Search" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :status_id_action" +msgid "Status ID action" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :statuses_actions" +msgid "Statuses actions" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rate_limit > :timeline" +msgid "Timeline" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities" +msgid "Activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :activities > :remote" +msgid "Remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles" +msgid "Profiles" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :profiles > :remote" +msgid "Remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines" +msgid "Timelines" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :federated" +msgid "Federated" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:restrict_unauthenticated > :timelines > :local" +msgid "Local" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :failure_backoff" +msgid "Failure backoff" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ignore_hosts" +msgid "Ignore hosts" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ignore_tld" +msgid "Ignore TLD" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :parsers" +msgid "Parsers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:rich_media > :ttl_setters" +msgid "TTL setters" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:shout > :limit" +msgid "Limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:static_fe > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer > :overflow_workers" +msgid "Overflow workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:streamer > :workers" +msgid "Workers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:uri_schemes > :valid_schemes" +msgid "Valid schemes" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:user > :deny_follow_blocked" +msgid "Deny follow blocked" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub" +msgid "Activity pub" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:web_cache_ttl > :activity_pub_question" +msgid "Activity pub question" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message" +msgid "Chat message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :message" +msgid "Message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :chat_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message" +msgid "Direct message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :message" +msgid "Message" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :direct_message > :sender_nickname" +msgid "Sender nickname" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email" +msgid "Email" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :html" +msgid "Html" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :sender" +msgid "Sender" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :subject" +msgid "Subject" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:welcome > :email > :text" +msgid "Text" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-:workers > :retries" +msgid "Retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgid "Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_running" +msgid "Max running" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers" +msgid "Pleroma.Web.RichMedia.Helpers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_running" +msgid "Max running" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-ConcurrentLimiter > Pleroma.Web.RichMedia.Helpers > :max_waiting" +msgid "Max waiting" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :crontab" +msgid "Crontab" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :log" +msgid "Log" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues" +msgid "Queues" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :activity_expiration" +msgid "Activity expiration" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :attachments_cleanup" +msgid "Attachments cleanup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :background" +msgid "Background" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :backup" +msgid "Backup" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :federator_incoming" +msgid "Federator incoming" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :federator_outgoing" +msgid "Federator outgoing" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :mailer" +msgid "Mailer" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :scheduled_activities" +msgid "Scheduled activities" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :transmogrifier" +msgid "Transmogrifier" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Oban > :queues > :web_push" +msgid "Web push" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :method" +msgid "Method" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha > :seconds_valid" +msgid "Seconds valid" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint" +msgid "Endpoint" +msgstr "终点" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :adapter" +msgid "Adapter" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > :enabled" +msgid "Mailer Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:access_key" +msgid "AWS Access Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:region" +msgid "AWS Region" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.AmazonSES-:secret" +msgid "AWS Secret Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Dyn-:api_key" +msgid "Dyn API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Gmail-:access_token" +msgid "GMail API Access Token" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:api_key" +msgid "Mailgun API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailgun-:domain" +msgid "Domain" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:api_key" +msgid "MailJet Public API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mailjet-:secret" +msgid "MailJet Private API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Mandrill-:api_key" +msgid "Mandrill API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Postmark-:api_key" +msgid "Postmark API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:auth" +msgid "AUTH Mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password" +msgid "Password" +msgstr "密码" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:port" +msgid "Port" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:relay" +msgid "Relay" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:retries" +msgid "Retries" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:ssl" +msgid "Use SSL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:tls" +msgid "STARTTLS Mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:username" +msgid "Username" +msgstr "用户名" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendgrid-:api_key" +msgid "SendGrid API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_args" +msgid "Cmd args" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:cmd_path" +msgid "Cmd path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.Sendmail-:qmail" +msgid "Qmail compat mode" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:api_key" +msgid "SocketLabs API Key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SocketLabs-:server_id" +msgid "Server ID" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:api_key" +msgid "SparkPost API key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SparkPost-:endpoint" +msgid "Endpoint" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.NewUsersDigestEmail > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :logo" +msgid "Logo" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling" +msgid "Styling" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :background_color" +msgid "Background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :content_background_color" +msgid "Content background color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :header_color" +msgid "Header color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :link_color" +msgid "Link color" +msgstr "链接颜色" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_color" +msgid "Text color" +msgstr "文本颜色" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_muted_color" +msgid "Text muted color" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :class" +msgid "Class" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :extra" +msgid "Extra" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :new_window" +msgid "New window" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :rel" +msgid "Rel" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :strip_prefix" +msgid "Strip prefix" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :truncate" +msgid "Truncate" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Formatter > :validate_tld" +msgid "Validate tld" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :daily_user_limit" +msgid "Daily user limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.ScheduledActivity > :total_user_limit" +msgid "Total user limit" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :base_url" +msgid "Base URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :filename_display_max_length" +msgid "Filename display max length" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :filters" +msgid "Filters" +msgstr "过滤器" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :link_name" +msgid "Link name" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :proxy_remote" +msgid "Proxy remote" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload > :uploader" +msgid "Uploader" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.AnonymizeFilename > :text" +msgid "Text" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Upload.Filter.Mogrify > :args" +msgid "Args" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.Local > :uploads" +msgid "Uploads" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket" +msgid "Bucket" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :bucket_namespace" +msgid "Bucket namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :streaming_enabled" +msgid "Streaming enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Uploaders.S3 > :truncated_namespace" +msgid "Truncated namespace" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User > :email_blacklist" +msgid "Email blacklist" +msgstr "邮件黑名单" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User > :restricted_nicknames" +msgid "Restricted nicknames" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup > :limit_days" +msgid "Limit days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.User.Backup > :purge_after_days" +msgid "Purge after days" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.ApiSpec.CastAndValidate > :strict" +msgid "Strict" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :method" +msgid "Method" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options" +msgid "Options" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http > :options > :params" +msgid "Params" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :script_path" +msgid "Script path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Script > :url_format" +msgid "URL Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :providers" +msgid "Providers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Metadata > :unfurl_nsfw" +msgid "Unfurl NSFW" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :enabled" +msgid "Enabled" +msgstr "已启用" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :headers" +msgid "Headers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :proxies" +msgid "Proxies" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Plugs.RemoteIp > :reserved" +msgid "Reserved" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Web.Preload > :providers" +msgid "Providers" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled" +msgid "Enabled" +msgstr "已启用" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :min_lifetime" +msgid "Min lifetime" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :auth" +msgid "Auth" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :enabled" +msgid "Enabled" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :format" +msgid "Format" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :ip_whitelist" +msgid "IP Whitelist" +msgstr "IP 白名单" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :path" +msgid "Path" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :level" +msgid "Level" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :meta" +msgid "Meta" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :quack > :webhook_url" +msgid "Webhook URL" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :private_key" +msgid "Private key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :public_key" +msgid "Public key" +msgstr "" + +#: lib/pleroma/docs/translator.ex:5 +#, elixir-autogen, elixir-format +msgctxt "config label at :web_push_encryption-:vapid_details > :subject" +msgid "Subject" +msgstr "" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/default.po b/priv/gettext/zh_Hans/LC_MESSAGES/default.po index 06995d283..ed0d1576b 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/default.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/default.po @@ -8,179 +8,186 @@ ## 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: zh_Hans\n" -"Plural-Forms: nplurals=1\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" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:122 +#, elixir-format msgid "%{name} - %{count} is not a multiple of %{multiple}." -msgstr "" +msgstr "%{name} - %{count} 不是 %{multiple} 的倍数。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:131 +#, elixir-format msgid "%{name} - %{value} is larger than exclusive maximum %{max}." -msgstr "" +msgstr "%{name} - %{value} 大于排除性最大值 %{max}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:140 +#, elixir-format msgid "%{name} - %{value} is larger than inclusive maximum %{max}." -msgstr "" +msgstr "%{name} - %{value} 大于包括性最大值 %{max}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:149 +#, elixir-format msgid "%{name} - %{value} is smaller than exclusive minimum %{min}." -msgstr "" +msgstr "%{name} - %{value} 小于排除性最小值 %{min}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:158 +#, elixir-format msgid "%{name} - %{value} is smaller than inclusive minimum %{min}." -msgstr "" +msgstr "%{name} - %{value} 小于包括性最小值 %{min}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:102 +#, elixir-format msgid "%{name} - Array items must be unique." -msgstr "" +msgstr "%{name} - 数组项目必须唯一。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:114 +#, elixir-format msgid "%{name} - Array length %{length} is larger than maxItems: %{}." -msgstr "" +msgstr "%{name} - 数组长度 %{length} 大于最大项目数: %{}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:106 +#, elixir-format msgid "%{name} - Array length %{length} is smaller than minItems: %{min}." -msgstr "" +msgstr "%{name} - 数组长度 %{length} 小于最小项目数: %{min}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:166 +#, elixir-format msgid "%{name} - Invalid %{type}. Got: %{value}." -msgstr "" +msgstr "%{name} - 不合法的 %{type}。得到的是:%{value}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:174 +#, elixir-format msgid "%{name} - Invalid format. Expected %{format}." -msgstr "" +msgstr "%{name} - 不合法的格式。预期是 %{format}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:51 +#, elixir-format msgid "%{name} - Invalid schema.type. Got: %{type}." -msgstr "" +msgstr "%{name} - 不合法的 schema.type。得到的是:%{type}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:178 +#, elixir-format msgid "%{name} - Invalid value for enum." -msgstr "" +msgstr "%{name} - 枚举值不合法。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:95 +#, elixir-format msgid "%{name} - String length is larger than maxLength: %{length}." -msgstr "" +msgstr "%{name} - 字串长度大于最大长度:%{length}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:88 +#, elixir-format msgid "%{name} - String length is smaller than minLength: %{length}." -msgstr "" +msgstr "%{name} - 字串长度小于最小长度:%{length}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:63 +#, elixir-format msgid "%{name} - null value where %{type} expected." -msgstr "" +msgstr "%{name} - null 值,但是预期该是 %{type}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:60 +#, elixir-format msgid "%{name} - null value." -msgstr "" +msgstr "%{name} - null 值。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:182 +#, elixir-format msgid "Failed to cast to any schema in %{polymorphic_type}" -msgstr "" +msgstr "转换到 %{polymorphic_type} 中的任一 schema 失败" -#, elixir-format #: 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 "" +msgstr "把值转换成 %{invalid_schema} 失败。值必须可以被转换成在列的「所有」schema。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:84 +#, elixir-format msgid "Failed to cast value to one of: %{failed_schemas}." -msgstr "" +msgstr "转换值为 %{failed_schemas} 中的一个失败。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:78 +#, elixir-format msgid "Failed to cast value using any of: %{failed_schemas}." -msgstr "" +msgstr "转换值为 %{failed_schemas} 中的任意一个失败。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:212 +#, elixir-format msgid "Invalid value for header: %{name}." -msgstr "" +msgstr "头 %{name} 的不合法的值。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:204 +#, elixir-format msgid "Missing field: %{name}." -msgstr "" +msgstr "缺少字段:%{name}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:208 -msgid "Missing header: %{name}." -msgstr "" - #, elixir-format +msgid "Missing header: %{name}." +msgstr "缺少头:%{name}。" + #: lib/pleroma/web/api_spec/render_error.ex:196 +#, elixir-format msgid "No value provided for required discriminator `%{field}`." msgstr "" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:216 +#, elixir-format msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." msgstr "" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:224 +#, elixir-format msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" msgstr "" -#, elixir-format #: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 +#, elixir-format msgid "Oops" -msgstr "" +msgstr "嗨呀" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:188 +#, elixir-format msgid "Unexpected field: %{name}." -msgstr "" +msgstr "超出预期的字段:%{name}。" -#, elixir-format #: lib/pleroma/web/api_spec/render_error.ex:200 -msgid "Unknown schema: %{name}." -msgstr "" - #, elixir-format +msgid "Unknown schema: %{name}." +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 "" -#, elixir-format #: lib/pleroma/web/templates/embed/show.html.eex:43 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 -msgid "announces" -msgstr "" - #, elixir-format +msgid "announces" +msgstr "传播" + #: lib/pleroma/web/templates/embed/show.html.eex:44 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:38 -msgid "likes" -msgstr "" - #, elixir-format +msgid "likes" +msgstr "喜欢" + #: lib/pleroma/web/templates/embed/show.html.eex:42 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:36 -msgid "replies" -msgstr "" - #, elixir-format +msgid "replies" +msgstr "回复" + #: lib/pleroma/web/templates/embed/show.html.eex:27 #: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:22 +#, elixir-format msgid "sensitive media" -msgstr "" +msgstr "敏感媒体" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/errors.po b/priv/gettext/zh_Hans/LC_MESSAGES/errors.po index 569b00a42..4431445e3 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/errors.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/errors.po @@ -3,16 +3,16 @@ 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: 2020-12-14 06:00+0000\n" -"Last-Translator: shironeko \n" -"Language-Team: Chinese (Simplified) \n" +"PO-Revision-Date: 2022-07-22 19:00+0000\n" +"Last-Translator: Yating Zhan \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.0.4\n" +"X-Generator: Weblate 4.13.1\n" ## This file is a PO Template file. ## @@ -65,7 +65,7 @@ msgstr[0] "应为 %{count} 个字符" msgid "should have %{count} item(s)" msgid_plural "should have %{count} item(s)" -msgstr[0] "应有 %{item} 项" +msgstr[0] "应有 %{count} 项" msgid "should be at least %{count} character(s)" msgid_plural "should be at least %{count} character(s)" @@ -99,371 +99,370 @@ msgstr "必须大于等于 %{number}" msgid "must be equal to %{number}" msgstr "必须等于 %{number}" -#, elixir-format #: lib/pleroma/web/common_api.ex:523 +#, elixir-format msgid "Account not found" msgstr "未找到账号" -#, elixir-format #: lib/pleroma/web/common_api.ex:316 +#, elixir-format msgid "Already voted" msgstr "已经进行了投票" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:402 +#, elixir-format msgid "Bad request" msgstr "不正确的请求" -#, elixir-format #: lib/pleroma/web/controller_helper.ex:97 #: lib/pleroma/web/controller_helper.ex:103 +#, elixir-format msgid "Can't display this activity" msgstr "不能显示该活动" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:324 +#, elixir-format msgid "Can't find user" msgstr "找不到用户" -#, elixir-format #: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:80 +#, elixir-format msgid "Can't get favorites" msgstr "不能获取收藏" -#, elixir-format #: lib/pleroma/web/common_api/utils.ex:482 +#, elixir-format msgid "Cannot post an empty status without attachments" msgstr "无法发送空白且不包含附件的状态" -#, elixir-format, fuzzy #: lib/pleroma/web/common_api/utils.ex:441 +#, elixir-format msgid "Comment must be up to %{max_size} characters" msgstr "评论最多可使用 %{max_size} 字符" -#, elixir-format #: lib/pleroma/config_db.ex:200 +#, elixir-format msgid "Config with params %{params} not found" msgstr "无法找到包含参数 %{params} 的配置" -#, elixir-format #: lib/pleroma/web/common_api.ex:167 #: lib/pleroma/web/common_api.ex:171 +#, elixir-format msgid "Could not delete" msgstr "无法删除" -#, elixir-format #: lib/pleroma/web/common_api.ex:217 +#, elixir-format msgid "Could not favorite" msgstr "无法收藏" -#, elixir-format #: lib/pleroma/web/common_api.ex:254 +#, elixir-format msgid "Could not unfavorite" msgstr "无法取消收藏" -#, elixir-format #: lib/pleroma/web/common_api.ex:202 +#, elixir-format msgid "Could not unrepeat" msgstr "无法取消转发" -#, elixir-format #: lib/pleroma/web/common_api.ex:530 #: lib/pleroma/web/common_api.ex:539 +#, elixir-format msgid "Could not update state" msgstr "无法更新状态" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:205 +#, elixir-format msgid "Error." msgstr "错误。" -#, elixir-format #: lib/pleroma/web/twitter_api/twitter_api.ex:99 +#, elixir-format msgid "Invalid CAPTCHA" msgstr "无效的验证码" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:144 #: lib/pleroma/web/o_auth/o_auth_controller.ex:631 +#, elixir-format msgid "Invalid credentials" msgstr "无效的凭据" -#, elixir-format #: lib/pleroma/web/plugs/ensure_authenticated_plug.ex:42 +#, elixir-format msgid "Invalid credentials." msgstr "无效的凭据。" -#, elixir-format #: lib/pleroma/web/common_api.ex:337 +#, elixir-format msgid "Invalid indices" msgstr "无效的索引" -#, elixir-format #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:29 +#, elixir-format msgid "Invalid parameters" msgstr "无效的参数" -#, elixir-format #: lib/pleroma/web/common_api/utils.ex:349 +#, elixir-format msgid "Invalid password." msgstr "无效的密码。" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:254 +#, elixir-format msgid "Invalid request" msgstr "无效的请求" -#, elixir-format #: lib/pleroma/web/twitter_api/twitter_api.ex:102 +#, elixir-format msgid "Kocaptcha service unavailable" msgstr "Kocaptcha 服务不可用" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:140 +#, elixir-format msgid "Missing parameters" msgstr "缺少参数" -#, elixir-format #: lib/pleroma/web/common_api/utils.ex:477 +#, elixir-format msgid "No such conversation" msgstr "没有该对话" -#, elixir-format, fuzzy #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:171 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:197 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:239 +#, elixir-format msgid "No such permission_group" msgstr "没有该权限组" -#, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:504 #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11 #: lib/pleroma/web/feed/tag_controller.ex:16 #: lib/pleroma/web/feed/user_controller.ex:69 #: lib/pleroma/web/o_status/o_status_controller.ex:132 #: lib/pleroma/web/plugs/uploaded_media.ex:84 +#, elixir-format msgid "Not found" msgstr "未找到" -#, elixir-format #: lib/pleroma/web/common_api.ex:308 +#, elixir-format msgid "Poll's author can't vote" msgstr "投票的发起者不能投票" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:52 #: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:326 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 +#, elixir-format msgid "Record not found" msgstr "未找到该记录" -#, elixir-format #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:35 #: lib/pleroma/web/feed/user_controller.ex:78 #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:42 #: lib/pleroma/web/o_status/o_status_controller.ex:138 +#, elixir-format msgid "Something went wrong" msgstr "发生了一些错误" -#, elixir-format #: lib/pleroma/web/common_api/activity_draft.ex:143 +#, elixir-format msgid "The message visibility must be direct" msgstr "该消息必须为私信" -#, elixir-format #: lib/pleroma/web/common_api/utils.ex:492 +#, elixir-format msgid "The status is over the character limit" msgstr "状态超过了字符数限制" -#, elixir-format #: lib/pleroma/web/plugs/ensure_public_or_authenticated_plug.ex:36 +#, elixir-format msgid "This resource requires authentication." msgstr "该资源需要认证。" -#, elixir-format, fuzzy #: lib/pleroma/web/plugs/rate_limiter.ex:208 -msgid "Throttled" -msgstr "节流了" - #, elixir-format +msgid "Throttled" +msgstr "限流了" + #: lib/pleroma/web/common_api.ex:338 +#, elixir-format msgid "Too many choices" msgstr "太多选项" -#, elixir-format #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:268 +#, elixir-format msgid "You can't revoke your own admin status." msgstr "您不能撤消自己的管理员权限。" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:243 #: lib/pleroma/web/o_auth/o_auth_controller.ex:333 +#, elixir-format msgid "Your account is currently disabled" msgstr "您的账户已被禁用" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:205 #: lib/pleroma/web/o_auth/o_auth_controller.ex:356 +#, elixir-format msgid "Your login is missing a confirmed e-mail address" msgstr "您的账户缺少已认证的 e-mail 地址" -#, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:392 +#, elixir-format msgid "can't read inbox of %{nickname} as %{as_nickname}" msgstr "无法以 %{as_nickname} 读取 %{nickname} 的收件箱" -#, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:491 +#, elixir-format msgid "can't update outbox of %{nickname} as %{as_nickname}" msgstr "无法以 %{as_nickname} 更新 %{nickname} 的出件箱" -#, elixir-format #: lib/pleroma/web/common_api.ex:475 +#, elixir-format msgid "conversation is already muted" msgstr "对话已经被静音" -#, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:510 +#, elixir-format msgid "error" msgstr "错误" -#, elixir-format #: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:34 +#, elixir-format msgid "mascots can only be images" msgstr "吉祥物只能是图片" -#, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:63 +#, elixir-format msgid "not found" msgstr "未找到" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:437 +#, elixir-format msgid "Bad OAuth request." msgstr "错误的 OAuth 请求。" -#, elixir-format #: lib/pleroma/web/twitter_api/twitter_api.ex:108 +#, elixir-format msgid "CAPTCHA already used" msgstr "验证码已被使用" -#, elixir-format #: lib/pleroma/web/twitter_api/twitter_api.ex:105 +#, elixir-format msgid "CAPTCHA expired" msgstr "验证码已过期" -#, elixir-format #: lib/pleroma/web/plugs/uploaded_media.ex:57 +#, elixir-format msgid "Failed" msgstr "失败" -#, elixir-format, fuzzy #: lib/pleroma/web/o_auth/o_auth_controller.ex:453 -msgid "Failed to authenticate: %{message}." -msgstr "认证失败:%{message}。" - #, elixir-format +msgid "Failed to authenticate: %{message}." +msgstr "鉴权失败:%{message}。" + #: lib/pleroma/web/o_auth/o_auth_controller.ex:484 +#, elixir-format msgid "Failed to set up user account." msgstr "建立用户帐号失败。" -#, elixir-format #: lib/pleroma/web/plugs/o_auth_scopes_plug.ex:37 +#, elixir-format msgid "Insufficient permissions: %{permissions}." msgstr "权限不足:%{permissions}。" -#, elixir-format #: lib/pleroma/web/plugs/uploaded_media.ex:111 +#, elixir-format msgid "Internal Error" msgstr "内部错误" -#, elixir-format #: lib/pleroma/web/o_auth/fallback_controller.ex:22 #: lib/pleroma/web/o_auth/fallback_controller.ex:29 +#, elixir-format msgid "Invalid Username/Password" msgstr "无效的用户名/密码" -#, elixir-format, fuzzy #: lib/pleroma/web/twitter_api/twitter_api.ex:111 +#, elixir-format msgid "Invalid answer data" msgstr "无效的回答数据" -#, elixir-format #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33 +#, elixir-format, fuzzy msgid "Nodeinfo schema version not handled" -msgstr "" +msgstr "Nodeinfo schema 版本没被处理" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:194 +#, elixir-format msgid "This action is outside the authorized scopes" msgstr "此操作在许可范围以外" -#, elixir-format #: lib/pleroma/web/o_auth/fallback_controller.ex:14 +#, elixir-format msgid "Unknown error, please check the details and try again." msgstr "未知错误,请检查并重试。" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:136 #: lib/pleroma/web/o_auth/o_auth_controller.ex:180 -msgid "Unlisted redirect_uri." -msgstr "" - #, elixir-format +msgid "Unlisted redirect_uri." +msgstr "没被列出的重定向 URI(redirect_uri)。" + #: lib/pleroma/web/o_auth/o_auth_controller.ex:433 +#, elixir-format msgid "Unsupported OAuth provider: %{provider}." msgstr "不支持的 OAuth 提供者:%{provider}。" -#, elixir-format, fuzzy #: lib/pleroma/uploaders/uploader.ex:74 -msgid "Uploader callback timeout" -msgstr "上传回复超时" - #, elixir-format +msgid "Uploader callback timeout" +msgstr "上传器回调超时" + #: lib/pleroma/web/uploader_controller.ex:23 +#, elixir-format msgid "bad request" msgstr "错误的请求" -#, elixir-format #: lib/pleroma/web/twitter_api/twitter_api.ex:96 +#, elixir-format msgid "CAPTCHA Error" msgstr "验证码错误" -#, elixir-format, fuzzy #: lib/pleroma/web/common_api.ex:266 +#, elixir-format msgid "Could not add reaction emoji" msgstr "无法添加表情反应" -#, elixir-format #: lib/pleroma/web/common_api.ex:277 +#, elixir-format msgid "Could not remove reaction emoji" msgstr "无法移除表情反应" -#, elixir-format #: lib/pleroma/web/twitter_api/twitter_api.ex:122 +#, elixir-format msgid "Invalid CAPTCHA (Missing parameter: %{name})" msgstr "无效的验证码(缺少参数:%{name})" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:96 +#, elixir-format msgid "List not found" msgstr "未找到列表" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:151 +#, elixir-format msgid "Missing parameter: %{name}" msgstr "缺少参数:%{name}" -#, elixir-format #: lib/pleroma/web/o_auth/o_auth_controller.ex:232 #: lib/pleroma/web/o_auth/o_auth_controller.ex:346 +#, elixir-format msgid "Password reset is required" msgstr "需要重置密码" -#, elixir-format #: lib/pleroma/tests/auth_test_controller.ex:9 #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6 @@ -540,78 +539,79 @@ msgstr "需要重置密码" #: lib/pleroma/web/twitter_api/controllers/util_controller.ex:6 #: lib/pleroma/web/uploader_controller.ex:6 #: lib/pleroma/web/web_finger/web_finger_controller.ex:6 +#, elixir-format msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped." -msgstr "" +msgstr "安全违例:OAuth 域检查既没处理也没显式跳过。" -#, elixir-format, fuzzy #: lib/pleroma/web/plugs/ensure_authenticated_plug.ex:32 +#, elixir-format msgid "Two-factor authentication enabled, you must use a access token." -msgstr "已启用两因素验证,您需要使用访问令牌。" +msgstr "已启用两因素鉴权,您需要使用访问令牌。" -#, elixir-format, fuzzy #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 +#, elixir-format msgid "Web push subscription is disabled on this Pleroma instance" msgstr "此 Pleroma 实例禁用了网页推送订阅" -#, elixir-format #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:234 +#, elixir-format msgid "You can't revoke your own admin/moderator status." msgstr "您不能撤消自己的管理员权限。" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:129 +#, elixir-format msgid "authorization required for timeline view" msgstr "浏览时间线需要认证" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24 +#, elixir-format msgid "Access denied" msgstr "拒绝访问" -#, elixir-format #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:321 +#, elixir-format msgid "This API requires an authenticated user" msgstr "此 API 需要已认证的用户" -#, elixir-format #: lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex:26 #: lib/pleroma/web/plugs/user_is_admin_plug.ex:21 +#, elixir-format msgid "User is not an admin." msgstr "该用户不是管理员。" -#, elixir-format #: lib/pleroma/user/backup.ex:75 +#, elixir-format msgid "Last export was less than a day ago" msgid_plural "Last export was less than %{days} days ago" -msgstr[0] "" +msgstr[0] "上次导出还不到 %{days} 天前" -#, elixir-format #: lib/pleroma/user/backup.ex:93 +#, elixir-format msgid "Backups require enabled email" -msgstr "" +msgstr "备份要求开启邮件" -#, elixir-format #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:423 -msgid "Character limit (%{limit} characters) exceeded, contains %{length} characters" -msgstr "" - #, elixir-format +msgid "Character limit (%{limit} characters) exceeded, contains %{length} characters" +msgstr "超过字符限制(%{limit} 个字符),包含了 %{length} 个字符" + #: lib/pleroma/user/backup.ex:98 +#, elixir-format msgid "Email is required" -msgstr "" +msgstr "需要邮箱" -#, elixir-format, fuzzy #: lib/pleroma/web/common_api/utils.ex:507 +#, elixir-format msgid "Too many attachments" -msgstr "太多选项" +msgstr "太多附件" -#, elixir-format, fuzzy #: lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex:33 #: lib/pleroma/web/plugs/user_is_staff_plug.ex:20 -msgid "User is not a staff member." -msgstr "该用户不是管理员。" - #, elixir-format +msgid "User is not a staff member." +msgstr "该用户不是运营成员。" + #: lib/pleroma/web/o_auth/o_auth_controller.ex:366 +#, elixir-format msgid "Your account is awaiting approval." -msgstr "" +msgstr "你的账号正等待批准。" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po b/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po index d0d08cc9c..c486a5486 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/posix_errors.po @@ -8,107 +8,114 @@ ## 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: zh_Hans\n" -"Plural-Forms: nplurals=1\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" msgid "eperm" -msgstr "" +msgstr "不允许的操作" msgid "eacces" -msgstr "" +msgstr "权限不够" msgid "eagain" -msgstr "" +msgstr "资源暂时不可用" msgid "ebadf" -msgstr "" +msgstr "坏的文件描述符" msgid "ebadmsg" -msgstr "" +msgstr "坏讯息" msgid "ebusy" -msgstr "" +msgstr "设备或资源忙" msgid "edeadlk" -msgstr "" +msgstr "避免了资源死锁" msgid "edeadlock" -msgstr "" +msgstr "避免了资源死锁" msgid "edquot" -msgstr "" +msgstr "超出了磁盘配额" msgid "eexist" -msgstr "" +msgstr "文件存在" msgid "efault" -msgstr "" +msgstr "坏地址" msgid "efbig" -msgstr "" +msgstr "文件太大" msgid "eftype" -msgstr "" +msgstr "不合适的文件类型或格式" msgid "eintr" -msgstr "" +msgstr "系统调用被中断" msgid "einval" -msgstr "" +msgstr "不合法的参数" msgid "eio" -msgstr "" +msgstr "输入/输出错误" msgid "eisdir" -msgstr "" +msgstr "在目录上非法操作" msgid "eloop" -msgstr "" +msgstr "太多层符号链接" msgid "emfile" -msgstr "" +msgstr "太多打开的文件" msgid "emlink" -msgstr "" +msgstr "太多链接" msgid "emultihop" msgstr "" msgid "enametoolong" -msgstr "" +msgstr "文件名太长" msgid "enfile" -msgstr "" +msgstr "系统里太多打开的文件" msgid "enobufs" -msgstr "" +msgstr "没有可用的缓冲空间" msgid "enodev" -msgstr "" +msgstr "没这设备" msgid "enolck" -msgstr "" +msgstr "没有可用的锁" msgid "enolink" -msgstr "" +msgstr "链接被切断了" msgid "enoent" -msgstr "" +msgstr "没这文件或目录" msgid "enomem" -msgstr "" +msgstr "不能分配内存" msgid "enospc" -msgstr "" +msgstr "设备上没剩余空间" msgid "enosr" msgstr "" msgid "enostr" -msgstr "" +msgstr "设备不是流" msgid "enosys" -msgstr "" +msgstr "功能没实现" msgid "enotblk" msgstr "" @@ -117,16 +124,16 @@ msgid "enotdir" msgstr "" msgid "enotsup" -msgstr "" +msgstr "不受支持的操作" msgid "enxio" -msgstr "" +msgstr "该设备或路径不存在" msgid "eopnotsupp" -msgstr "" +msgstr "不受支持的操作" msgid "eoverflow" -msgstr "" +msgstr "请为给定类型的数据指定较小的数值" msgid "epipe" msgstr "" @@ -135,19 +142,19 @@ msgid "erange" msgstr "" msgid "erofs" -msgstr "" +msgstr "只读权限文件系统" msgid "espipe" msgstr "" msgid "esrch" -msgstr "" +msgstr "具体进程不存在" msgid "estale" msgstr "" msgid "etxtbsy" -msgstr "" +msgstr "文本文件忙碌" msgid "exdev" -msgstr "" +msgstr "该多设备链接不可用" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po b/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po index fa0412cec..cbd6feb60 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po @@ -2,459 +2,464 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2022-04-07 17:40-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" +"PO-Revision-Date: 2022-07-21 23:35+0000\n" +"Last-Translator: tusooa \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_Hans\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\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" -#~ ## "msgid"s in this file come from POT (.pot) files. -#~ ## -#~ ## Do not add, change, or remove "msgid"s manually here as -#~ ## they're tied to the ones in the corresponding POT file -#~ ## (with the same domain). -#~ ## -#~ ## Use "mix gettext.extract --merge" or "mix gettext.merge" -#~ ## to merge POT files into PO files. +## "msgid"s in this file come from POT (.pot) files. +## +## Do not add, change, or remove "msgid"s manually here as +## they're tied to the ones in the corresponding POT file +## (with the same domain). +## +## Use "mix gettext.extract --merge" or "mix gettext.merge" +## to merge POT files into PO files. #~ msgid "" #~ msgstr "" #~ "Language: zh_Hans\n" #~ "Plural-Forms: nplurals=1\n" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9 +#, elixir-format msgctxt "remote follow authorization button" msgid "Authorize" msgstr "授权" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:2 +#, elixir-format msgctxt "remote follow error" msgid "Error fetching user" msgstr "获取用户时出错" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:4 +#, elixir-format msgctxt "remote follow header" msgid "Remote follow" msgstr "远程关注" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:8 +#, elixir-format msgctxt "placeholder text for auth code entry" msgid "Authentication code" msgstr "授权代码" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:10 +#, elixir-format msgctxt "placeholder text for password entry" msgid "Password" msgstr "密码" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:8 +#, elixir-format msgctxt "placeholder text for username entry" msgid "Username" msgstr "用户名" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:13 +#, elixir-format msgctxt "remote follow authorization button for login" msgid "Authorize" msgstr "授权" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:12 +#, elixir-format msgctxt "remote follow authorization button for mfa" msgid "Authorize" msgstr "授权" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:2 +#, elixir-format msgctxt "remote follow error" msgid "Error following account" msgstr "关注用户时出错" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex:4 +#, elixir-format msgctxt "remote follow header, need login" msgid "Log in to follow" msgstr "登录以关注" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex:4 +#, elixir-format msgctxt "remote follow mfa header" msgid "Two-factor authentication" msgstr "两步鉴权" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex:4 +#, elixir-format msgctxt "remote follow success" msgid "Account followed!" msgstr "已经关注了账号!" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:7 +#, elixir-format msgctxt "placeholder text for account id" msgid "Your account ID, e.g. lain@quitter.se" msgstr "你的账户 ID,如 lain@quitter.se" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:8 +#, elixir-format msgctxt "remote follow authorization button for following with a remote account" msgid "Follow" msgstr "关注" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:2 +#, elixir-format msgctxt "remote follow error" msgid "Error: %{error}" msgstr "错误:%{error}" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:4 +#, elixir-format msgctxt "remote follow header" msgid "Remotely follow %{nickname}" msgstr "远程关注 %{nickname}" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:12 +#, elixir-format msgctxt "password reset button" msgid "Reset" msgstr "重置" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:4 +#, elixir-format msgctxt "password reset failed homepage link" msgid "Homepage" msgstr "回主页" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex:1 +#, elixir-format msgctxt "password reset failed message" msgid "Password reset failed" msgstr "密码重置失败" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:8 +#, elixir-format msgctxt "password reset form confirm password prompt" msgid "Confirmation" msgstr "确认密码" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset.html.eex:4 +#, elixir-format msgctxt "password reset form password prompt" msgid "Password" msgstr "密码" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex:1 +#, elixir-format msgctxt "password reset invalid token message" msgid "Invalid Token" msgstr "无效的令牌" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:2 +#, elixir-format msgctxt "password reset successful homepage link" msgid "Homepage" msgstr "回主页" -#, elixir-format #: lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex:1 +#, elixir-format msgctxt "password reset successful message" msgid "Password changed!" msgstr "密码已经修改了!" -#, elixir-format #: lib/pleroma/web/templates/feed/feed/tag.atom.eex:15 #: lib/pleroma/web/templates/feed/feed/tag.rss.eex:7 +#, elixir-format msgctxt "tag feed description" msgid "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse." msgstr "这些是标了 #%{tag} 签的公开文章。你要是在联邦宇宙的任何地方有账号,就能和它们互动。" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:1 +#, elixir-format msgctxt "oauth authorization exists page title" msgid "Authorization exists" msgstr "授权已经存在" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:32 +#, elixir-format msgctxt "oauth authorize approve button" msgid "Approve" msgstr "批准" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:30 +#, elixir-format msgctxt "oauth authorize cancel button" msgid "Cancel" msgstr "取消" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:23 +#, elixir-format msgctxt "oauth authorize message" msgid "Application %{client_name} is requesting access to your account." msgstr "应用程序 %{client_name} 在请求访问你的账号。" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:1 +#, elixir-format msgctxt "oauth authorized page title" msgid "Successfully authorized" msgstr "成功授权" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:1 +#, elixir-format msgctxt "oauth external provider page title" msgid "Sign in with external provider" msgstr "通过外部提供者登录" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex:13 +#, elixir-format msgctxt "oauth external provider sign in button" msgid "Sign in with %{strategy}" msgstr "通过 %{strategy} 登录" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:54 +#, elixir-format msgctxt "oauth login button" msgid "Log In" msgstr "登录" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:51 +#, elixir-format msgctxt "oauth login password prompt" msgid "Password" msgstr "密码" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:47 +#, elixir-format msgctxt "oauth login username prompt" msgid "Username" msgstr "用户名" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:39 +#, elixir-format msgctxt "oauth register nickname prompt" msgid "Pleroma Handle" msgstr "Pleroma 用户名" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:37 +#, elixir-format msgctxt "oauth register nickname unchangeable warning" msgid "Choose carefully! You won't be able to change this later. You will be able to change your display name, though." msgstr "选仔细了!你之后就不能改它了。但是你可以改显示名。" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:18 +#, elixir-format msgctxt "oauth register page email prompt" msgid "Email" msgstr "邮箱" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:10 +#, elixir-format msgctxt "oauth register page fill form prompt" msgid "If you'd like to register a new account, please provide the details below." msgstr "如果你想注册新账号,请提供如下信息。" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:35 +#, elixir-format msgctxt "oauth register page login button" msgid "Proceed as existing user" msgstr "以已有用户继续" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:31 +#, elixir-format msgctxt "oauth register page login password prompt" msgid "Password" msgstr "密码" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:24 +#, elixir-format msgctxt "oauth register page login prompt" msgid "Alternatively, sign in to connect to existing account." msgstr "或者,登录到已有账号。" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:27 +#, elixir-format msgctxt "oauth register page login username prompt" msgid "Name or email" msgstr "名字或邮箱" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:14 +#, elixir-format msgctxt "oauth register page nickname prompt" msgid "Nickname" msgstr "昵称" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:22 +#, elixir-format msgctxt "oauth register page register button" msgid "Proceed as new user" msgstr "以新用户继续" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/register.html.eex:8 +#, elixir-format msgctxt "oauth register page title" msgid "Registration Details" msgstr "注册详情" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/show.html.eex:36 +#, elixir-format msgctxt "oauth register page title" msgid "This is the first time you visit! Please enter your Pleroma handle." msgstr "这是你第一次访问。请输入 Pleroma 用户名。" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex:2 +#, elixir-format msgctxt "oauth scopes message" msgid "The following permissions will be granted" msgstr "将要允许如下权限" -#, elixir-format #: lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex:2 #: lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex:2 +#, elixir-format msgctxt "oauth token code message" msgid "Token code is
%{token}" msgstr "令牌代码是
%{token}" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:12 +#, elixir-format msgctxt "mfa auth code prompt" msgid "Authentication code" msgstr "鉴权代码" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:8 +#, elixir-format msgctxt "mfa auth page title" msgid "Two-factor authentication" msgstr "两步鉴权" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:23 +#, elixir-format msgctxt "mfa auth page use recovery code link" msgid "Enter a two-factor recovery code" msgstr "输入两步恢复码" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/totp.html.eex:20 +#, elixir-format msgctxt "mfa auth verify code button" msgid "Verify" msgstr "验证" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:8 +#, elixir-format msgctxt "mfa recover page title" msgid "Two-factor recovery" msgstr "两步恢复" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:12 +#, elixir-format msgctxt "mfa recover recovery code prompt" msgid "Recovery code" msgstr "恢复码" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:23 +#, elixir-format msgctxt "mfa recover use 2fa code link" msgid "Enter a two-factor code" msgstr "输入鉴权码" -#, elixir-format #: lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex:20 +#, elixir-format msgctxt "mfa recover verify recovery code button" msgid "Verify" msgstr "验证" -#, elixir-format #: lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex:8 +#, elixir-format msgctxt "static fe profile page remote follow button" msgid "Remote follow" msgstr "远程关注" -#, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:163 +#, elixir-format msgctxt "digest email header line" msgid "Hey %{nickname}, here is what you've missed!" msgstr "早 %{nickname},你刚错过这些!" -#, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:544 +#, elixir-format msgctxt "digest email receiver address" msgid "The email address you are subscribed as is %{email}. " -msgstr "你订阅的邮箱地址是 %{email}。" +msgstr "" +"你订阅的邮箱地址是 %{email}。 " -#, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:538 +#, elixir-format msgctxt "digest email sending reason" msgid "You have received this email because you have signed up to receive digest emails from %{instance} Pleroma instance." msgstr "因为你选择了收取来自 %{instance} 的摘要邮件,所以你会收到这封邮件。" -#, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:547 +#, elixir-format msgctxt "digest email unsubscribe action" msgid "To unsubscribe, please go %{here}." -msgstr "要取消订阅,请去%{here}" +msgstr "要取消订阅,请去%{here}。" -#, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:547 +#, elixir-format msgctxt "digest email unsubscribe action link text" msgid "here" msgstr "此处" -#, elixir-format #: lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex:1 +#, elixir-format msgctxt "mailer unsubscribe failed message" msgid "UNSUBSCRIBE FAILURE" msgstr "取消订阅失败" -#, elixir-format #: lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex:1 +#, elixir-format msgctxt "mailer unsubscribe successful message" msgid "UNSUBSCRIBE SUCCESSFUL" msgstr "取消订阅成功" -#, elixir-format #: lib/pleroma/web/templates/email/digest.html.eex:385 +#, elixir-format msgctxt "new followers count header" msgid "%{count} New Follower" msgid_plural "%{count} New Followers" msgstr[0] "%{count} 个新关注者" -#, elixir-format #: lib/pleroma/emails/user_email.ex:356 +#, elixir-format msgctxt "account archive email body - self-requested" msgid "

You requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" msgstr "" "

你之前要了一份你的 Pleroma 账号的完整备份。现在可以下载了:

\n" "

%{download_url}

\n" -#, elixir-format #: lib/pleroma/emails/user_email.ex:384 +#, elixir-format msgctxt "account archive email subject" msgid "Your account archive is ready" msgstr "你的账号存档准备好了" -#, elixir-format #: lib/pleroma/emails/user_email.ex:188 +#, elixir-format msgctxt "approval pending email body" msgid "

Awaiting Approval

\n

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

\n" msgstr "" "

等待批准

\n" "

管理人员正在审核你在 %{instance_name} 的账号。等账号批准之后你会收到另一封邮件。

\n" -#, elixir-format #: lib/pleroma/emails/user_email.ex:202 +#, elixir-format msgctxt "approval pending email subject" msgid "Your account is awaiting approval" msgstr "你的账号在等待批准" -#, elixir-format #: lib/pleroma/emails/user_email.ex:158 +#, elixir-format msgctxt "confirmation email body" msgid "

Thank you for registering on %{instance_name}

\n

Email confirmation is required to activate the account.

\n

Please click the following link to activate your account.

\n" msgstr "" @@ -462,20 +467,20 @@ msgstr "" "

要激活账号,必须验证邮箱。

\n" "

请点如下链接来激活账号

\n" -#, elixir-format #: lib/pleroma/emails/user_email.ex:174 +#, elixir-format msgctxt "confirmation email subject" msgid "%{instance_name} account confirmation" msgstr "%{instance_name} 账号激活" -#, elixir-format #: lib/pleroma/emails/user_email.ex:310 +#, elixir-format msgctxt "digest email subject" msgid "Your digest from %{instance_name}" msgstr "来自 %{instance_name} 的摘要" -#, elixir-format #: lib/pleroma/emails/user_email.ex:81 +#, elixir-format msgctxt "password reset email body" msgid "

Reset your password at %{instance_name}

\n

Someone has requested password change for your account at %{instance_name}.

\n

If it was you, visit the following link to proceed: reset password.

\n

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

\n" msgstr "" @@ -484,14 +489,14 @@ msgstr "" "

如果那是你,访问如下链接以继续:重置密码

\n" "

如果是别人,不必担心:你的数据很安全,密码也没变。

\n" -#, elixir-format #: lib/pleroma/emails/user_email.ex:98 +#, elixir-format msgctxt "password reset email subject" msgid "Password reset" msgstr "密码重置" -#, elixir-format #: lib/pleroma/emails/user_email.ex:215 +#, elixir-format msgctxt "successful registration email body" msgid "

Hello @%{nickname},

\n

Your account at %{instance_name} has been registered successfully.

\n

No further action is required to activate your account.

\n" msgstr "" @@ -499,14 +504,14 @@ msgstr "" "

你在 %{instance_name} 上的账号已经成功注册了。

\n" "

你的账号已经激活,无需再做任何操作。

\n" -#, elixir-format #: lib/pleroma/emails/user_email.ex:231 +#, elixir-format msgctxt "successful registration email subject" msgid "Account registered on %{instance_name}" msgstr "在 %{instance_name} 上注册了账号" -#, elixir-format #: lib/pleroma/emails/user_email.ex:119 +#, elixir-format msgctxt "user invitation email body" msgid "

You are invited to %{instance_name}

\n

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

\n

Click the following link to register: accept invitation.

\n" msgstr "" @@ -514,32 +519,32 @@ msgstr "" "

%{inviter_name} 邀请你去 %{instance_name}。这是社交网络平台 Pleroma 的一个实例。

\n" "

点如下链接以注册:接受邀请

\n" -#, elixir-format #: lib/pleroma/emails/user_email.ex:136 +#, elixir-format msgctxt "user invitation email subject" msgid "Invitation to %{instance_name}" msgstr "去 %{instance_name} 的邀请" -#, elixir-format #: lib/pleroma/emails/user_email.ex:53 +#, elixir-format msgctxt "welcome email html body" msgid "Welcome to %{instance_name}!" msgstr "欢迎来到 %{instance_name}!" -#, elixir-format #: lib/pleroma/emails/user_email.ex:41 +#, elixir-format msgctxt "welcome email subject" msgid "Welcome to %{instance_name}!" msgstr "欢迎来到 %{instance_name}!" -#, elixir-format #: lib/pleroma/emails/user_email.ex:65 +#, elixir-format msgctxt "welcome email text body" msgid "Welcome to %{instance_name}!" msgstr "欢迎来到 %{instance_name}!" -#, elixir-format #: lib/pleroma/emails/user_email.ex:368 +#, elixir-format msgctxt "account archive email body - admin requested" msgid "

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

\n

%{download_url}

\n" msgstr "" diff --git a/priv/repo/migrations/20220509180452_change_thread_visibility_to_be_local_only_aware.exs b/priv/repo/migrations/20220509180452_change_thread_visibility_to_be_local_only_aware.exs new file mode 100644 index 000000000..ea6ae6c5c --- /dev/null +++ b/priv/repo/migrations/20220509180452_change_thread_visibility_to_be_local_only_aware.exs @@ -0,0 +1,153 @@ +defmodule Pleroma.Repo.Migrations.ChangeThreadVisibilityToBeLocalOnlyAware do + use Ecto.Migration + + def up do + execute("DROP FUNCTION IF EXISTS thread_visibility(actor varchar, activity_id varchar)") + execute(update_thread_visibility()) + end + + def down do + execute( + "DROP FUNCTION IF EXISTS thread_visibility(actor varchar, activity_id varchar, local_public varchar)" + ) + + execute(restore_thread_visibility()) + end + + def update_thread_visibility do + """ + CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar, local_public varchar default '') RETURNS boolean AS $$ + DECLARE + public varchar := 'https://www.w3.org/ns/activitystreams#Public'; + child objects%ROWTYPE; + activity activities%ROWTYPE; + author_fa varchar; + valid_recipients varchar[]; + actor_user_following varchar[]; + BEGIN + --- Fetch actor following + SELECT array_agg(following.follower_address) INTO actor_user_following FROM following_relationships + JOIN users ON users.id = following_relationships.follower_id + JOIN users AS following ON following.id = following_relationships.following_id + WHERE users.ap_id = actor; + + --- Fetch our initial activity. + SELECT * INTO activity FROM activities WHERE activities.data->>'id' = activity_id; + + LOOP + --- Ensure that we have an activity before continuing. + --- If we don't, the thread is not satisfiable. + IF activity IS NULL THEN + RETURN false; + END IF; + + --- We only care about Create activities. + IF activity.data->>'type' != 'Create' THEN + RETURN true; + END IF; + + --- Normalize the child object into child. + SELECT * INTO child FROM objects + INNER JOIN activities ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id' + WHERE COALESCE(activity.data->'object'->>'id', activity.data->>'object') = objects.data->>'id'; + + --- Fetch the author's AS2 following collection. + SELECT COALESCE(users.follower_address, '') INTO author_fa FROM users WHERE users.ap_id = activity.actor; + + --- Prepare valid recipients array. + valid_recipients := ARRAY[actor, public]; + --- If we specified local public, add it. + IF local_public <> '' THEN + valid_recipients := valid_recipients || local_public; + END IF; + IF ARRAY[author_fa] && actor_user_following THEN + valid_recipients := valid_recipients || author_fa; + END IF; + + --- Check visibility. + IF NOT valid_recipients && activity.recipients THEN + --- activity not visible, break out of the loop + RETURN false; + END IF; + + --- If there's a parent, load it and do this all over again. + IF (child.data->'inReplyTo' IS NOT NULL) AND (child.data->'inReplyTo' != 'null'::jsonb) THEN + SELECT * INTO activity FROM activities + INNER JOIN objects ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id' + WHERE child.data->>'inReplyTo' = objects.data->>'id'; + ELSE + RETURN true; + END IF; + END LOOP; + END; + $$ LANGUAGE plpgsql IMMUTABLE; + """ + end + + # priv/repo/migrations/20191007073319_create_following_relationships.exs + def restore_thread_visibility do + """ + CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar) RETURNS boolean AS $$ + DECLARE + public varchar := 'https://www.w3.org/ns/activitystreams#Public'; + child objects%ROWTYPE; + activity activities%ROWTYPE; + author_fa varchar; + valid_recipients varchar[]; + actor_user_following varchar[]; + BEGIN + --- Fetch actor following + SELECT array_agg(following.follower_address) INTO actor_user_following FROM following_relationships + JOIN users ON users.id = following_relationships.follower_id + JOIN users AS following ON following.id = following_relationships.following_id + WHERE users.ap_id = actor; + + --- Fetch our initial activity. + SELECT * INTO activity FROM activities WHERE activities.data->>'id' = activity_id; + + LOOP + --- Ensure that we have an activity before continuing. + --- If we don't, the thread is not satisfiable. + IF activity IS NULL THEN + RETURN false; + END IF; + + --- We only care about Create activities. + IF activity.data->>'type' != 'Create' THEN + RETURN true; + END IF; + + --- Normalize the child object into child. + SELECT * INTO child FROM objects + INNER JOIN activities ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id' + WHERE COALESCE(activity.data->'object'->>'id', activity.data->>'object') = objects.data->>'id'; + + --- Fetch the author's AS2 following collection. + SELECT COALESCE(users.follower_address, '') INTO author_fa FROM users WHERE users.ap_id = activity.actor; + + --- Prepare valid recipients array. + valid_recipients := ARRAY[actor, public]; + IF ARRAY[author_fa] && actor_user_following THEN + valid_recipients := valid_recipients || author_fa; + END IF; + + --- Check visibility. + IF NOT valid_recipients && activity.recipients THEN + --- activity not visible, break out of the loop + RETURN false; + END IF; + + --- If there's a parent, load it and do this all over again. + IF (child.data->'inReplyTo' IS NOT NULL) AND (child.data->'inReplyTo' != 'null'::jsonb) THEN + SELECT * INTO activity FROM activities + INNER JOIN objects ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id' + WHERE child.data->>'inReplyTo' = objects.data->>'id'; + ELSE + RETURN true; + END IF; + END LOOP; + END; + $$ LANGUAGE plpgsql IMMUTABLE; + """ + end +end diff --git a/priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs b/priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs new file mode 100644 index 000000000..0656c885f --- /dev/null +++ b/priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs @@ -0,0 +1,51 @@ +defmodule Pleroma.Repo.Migrations.AddUpdateToNotificationsEnum do + use Ecto.Migration + + @disable_ddl_transaction true + + def up do + """ + alter type notification_type add value 'update' + """ + |> execute() + end + + # 20210717000000_add_poll_to_notifications_enum.exs + def down do + alter table(:notifications) do + modify(:type, :string) + end + + """ + delete from notifications where type = 'update' + """ + |> execute() + + """ + drop type if exists notification_type + """ + |> execute() + + """ + create type notification_type as enum ( + 'follow', + 'follow_request', + 'mention', + 'move', + 'pleroma:emoji_reaction', + 'pleroma:chat_mention', + 'reblog', + 'favourite', + 'pleroma:report', + 'poll' + ) + """ + |> execute() + + """ + alter table notifications + alter column type type notification_type using (type::notification_type) + """ + |> execute() + end +end diff --git a/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs b/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs new file mode 100644 index 000000000..9e117e376 --- /dev/null +++ b/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs @@ -0,0 +1,13 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.AddExpiresAtToUserRelationships do + use Ecto.Migration + + def change do + alter table(:user_relationships) do + add_if_not_exists(:expires_at, :utc_datetime) + end + end +end diff --git a/priv/repo/migrations/20220711182322_add_associated_object_id_function.exs b/priv/repo/migrations/20220711182322_add_associated_object_id_function.exs new file mode 100644 index 000000000..76348f31a --- /dev/null +++ b/priv/repo/migrations/20220711182322_add_associated_object_id_function.exs @@ -0,0 +1,37 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.AddAssociatedObjectIdFunction do + use Ecto.Migration + + def up do + statement = """ + CREATE OR REPLACE FUNCTION associated_object_id(data jsonb) RETURNS varchar AS $$ + DECLARE + object_data jsonb; + BEGIN + IF jsonb_typeof(data->'object') = 'array' THEN + object_data := data->'object'->0; + ELSE + object_data := data->'object'; + END IF; + + IF jsonb_typeof(object_data->'id') = 'string' THEN + RETURN object_data->>'id'; + ELSIF jsonb_typeof(object_data) = 'string' THEN + RETURN object_data#>>'{}'; + ELSE + RETURN NULL; + END IF; + END; + $$ LANGUAGE plpgsql IMMUTABLE; + """ + + execute(statement) + end + + def down do + execute("DROP FUNCTION IF EXISTS associated_object_id(data jsonb)") + end +end diff --git a/priv/repo/migrations/20220711192750_switch_to_associated_object_id_index.exs b/priv/repo/migrations/20220711192750_switch_to_associated_object_id_index.exs new file mode 100644 index 000000000..75c1cd40b --- /dev/null +++ b/priv/repo/migrations/20220711192750_switch_to_associated_object_id_index.exs @@ -0,0 +1,37 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.SwitchToAssociatedObjectIdIndex do + use Ecto.Migration + @disable_ddl_transaction true + @disable_migration_lock true + + def up do + drop_if_exists( + index(:activities, ["(coalesce(data->'object'->>'id', data->>'object'))"], + name: :activities_create_objects_index + ) + ) + + create( + index(:activities, ["associated_object_id(data)"], + name: :activities_create_objects_index, + concurrently: true + ) + ) + end + + def down do + drop_if_exists( + index(:activities, ["associated_object_id(data)"], name: :activities_create_objects_index) + ) + + create( + index(:activities, ["(coalesce(data->'object'->>'id', data->>'object'))"], + name: :activities_create_objects_index, + concurrently: true + ) + ) + end +end diff --git a/priv/repo/migrations/20220807125023_data_migration_delete_context_objects.exs b/priv/repo/migrations/20220807125023_data_migration_delete_context_objects.exs new file mode 100644 index 000000000..84365dbe3 --- /dev/null +++ b/priv/repo/migrations/20220807125023_data_migration_delete_context_objects.exs @@ -0,0 +1,18 @@ +defmodule Pleroma.Repo.Migrations.DataMigrationDeleteContextObjects do + use Ecto.Migration + + require Logger + + def up do + dt = NaiveDateTime.utc_now() + + execute( + "INSERT INTO data_migrations(name, inserted_at, updated_at) " <> + "VALUES ('delete_context_objects', '#{dt}', '#{dt}') ON CONFLICT DO NOTHING;" + ) + end + + def down do + execute("DELETE FROM data_migrations WHERE name = 'delete_context_objects';") + end +end diff --git a/priv/repo/migrations/20220821004840_change_thread_visibility_to_use_new_object_id_index.exs b/priv/repo/migrations/20220821004840_change_thread_visibility_to_use_new_object_id_index.exs new file mode 100644 index 000000000..bb56843cb --- /dev/null +++ b/priv/repo/migrations/20220821004840_change_thread_visibility_to_use_new_object_id_index.exs @@ -0,0 +1,156 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.ChangeThreadVisibilityToUseNewObjectIdIndex do + use Ecto.Migration + + def up do + execute(update_thread_visibility()) + end + + def down do + execute(restore_thread_visibility()) + end + + def update_thread_visibility do + """ + CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar, local_public varchar default '') RETURNS boolean AS $$ + DECLARE + public varchar := 'https://www.w3.org/ns/activitystreams#Public'; + child objects%ROWTYPE; + activity activities%ROWTYPE; + author_fa varchar; + valid_recipients varchar[]; + actor_user_following varchar[]; + BEGIN + --- Fetch actor following + SELECT array_agg(following.follower_address) INTO actor_user_following FROM following_relationships + JOIN users ON users.id = following_relationships.follower_id + JOIN users AS following ON following.id = following_relationships.following_id + WHERE users.ap_id = actor; + + --- Fetch our initial activity. + SELECT * INTO activity FROM activities WHERE activities.data->>'id' = activity_id; + + LOOP + --- Ensure that we have an activity before continuing. + --- If we don't, the thread is not satisfiable. + IF activity IS NULL THEN + RETURN false; + END IF; + + --- We only care about Create activities. + IF activity.data->>'type' != 'Create' THEN + RETURN true; + END IF; + + --- Normalize the child object into child. + SELECT * INTO child FROM objects + INNER JOIN activities ON associated_object_id(activities.data) = objects.data->>'id' + WHERE associated_object_id(activity.data) = objects.data->>'id'; + + --- Fetch the author's AS2 following collection. + SELECT COALESCE(users.follower_address, '') INTO author_fa FROM users WHERE users.ap_id = activity.actor; + + --- Prepare valid recipients array. + valid_recipients := ARRAY[actor, public]; + --- If we specified local public, add it. + IF local_public <> '' THEN + valid_recipients := valid_recipients || local_public; + END IF; + IF ARRAY[author_fa] && actor_user_following THEN + valid_recipients := valid_recipients || author_fa; + END IF; + + --- Check visibility. + IF NOT valid_recipients && activity.recipients THEN + --- activity not visible, break out of the loop + RETURN false; + END IF; + + --- If there's a parent, load it and do this all over again. + IF (child.data->'inReplyTo' IS NOT NULL) AND (child.data->'inReplyTo' != 'null'::jsonb) THEN + SELECT * INTO activity FROM activities + INNER JOIN objects ON associated_object_id(activities.data) = objects.data->>'id' + WHERE child.data->>'inReplyTo' = objects.data->>'id'; + ELSE + RETURN true; + END IF; + END LOOP; + END; + $$ LANGUAGE plpgsql IMMUTABLE; + """ + end + + # priv/repo/migrations/20220509180452_change_thread_visibility_to_be_local_only_aware.exs + def restore_thread_visibility do + """ + CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar, local_public varchar default '') RETURNS boolean AS $$ + DECLARE + public varchar := 'https://www.w3.org/ns/activitystreams#Public'; + child objects%ROWTYPE; + activity activities%ROWTYPE; + author_fa varchar; + valid_recipients varchar[]; + actor_user_following varchar[]; + BEGIN + --- Fetch actor following + SELECT array_agg(following.follower_address) INTO actor_user_following FROM following_relationships + JOIN users ON users.id = following_relationships.follower_id + JOIN users AS following ON following.id = following_relationships.following_id + WHERE users.ap_id = actor; + + --- Fetch our initial activity. + SELECT * INTO activity FROM activities WHERE activities.data->>'id' = activity_id; + + LOOP + --- Ensure that we have an activity before continuing. + --- If we don't, the thread is not satisfiable. + IF activity IS NULL THEN + RETURN false; + END IF; + + --- We only care about Create activities. + IF activity.data->>'type' != 'Create' THEN + RETURN true; + END IF; + + --- Normalize the child object into child. + SELECT * INTO child FROM objects + INNER JOIN activities ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id' + WHERE COALESCE(activity.data->'object'->>'id', activity.data->>'object') = objects.data->>'id'; + + --- Fetch the author's AS2 following collection. + SELECT COALESCE(users.follower_address, '') INTO author_fa FROM users WHERE users.ap_id = activity.actor; + + --- Prepare valid recipients array. + valid_recipients := ARRAY[actor, public]; + --- If we specified local public, add it. + IF local_public <> '' THEN + valid_recipients := valid_recipients || local_public; + END IF; + IF ARRAY[author_fa] && actor_user_following THEN + valid_recipients := valid_recipients || author_fa; + END IF; + + --- Check visibility. + IF NOT valid_recipients && activity.recipients THEN + --- activity not visible, break out of the loop + RETURN false; + END IF; + + --- If there's a parent, load it and do this all over again. + IF (child.data->'inReplyTo' IS NOT NULL) AND (child.data->'inReplyTo' != 'null'::jsonb) THEN + SELECT * INTO activity FROM activities + INNER JOIN objects ON COALESCE(activities.data->'object'->>'id', activities.data->>'object') = objects.data->>'id' + WHERE child.data->>'inReplyTo' = objects.data->>'id'; + ELSE + RETURN true; + END IF; + END LOOP; + END; + $$ LANGUAGE plpgsql IMMUTABLE; + """ + end +end diff --git a/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs b/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs new file mode 100644 index 000000000..43bc7100b --- /dev/null +++ b/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs @@ -0,0 +1,28 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.GenerateUnsetUserKeys do + use Ecto.Migration + import Ecto.Query + alias Pleroma.Keys + alias Pleroma.Repo + alias Pleroma.User + + def change do + query = + from(u in User, + where: u.local == true, + where: is_nil(u.keys), + select: u + ) + + Repo.stream(query) + |> Enum.each(fn user -> + with {:ok, pem} <- Keys.generate_rsa_pem() do + Ecto.Changeset.cast(user, %{keys: pem}, [:keys]) + |> Repo.update() + end + end) + end +end diff --git a/priv/repo/migrations/20221103014611_create_oban_peers.exs b/priv/repo/migrations/20221103014611_create_oban_peers.exs new file mode 100644 index 000000000..cb522a056 --- /dev/null +++ b/priv/repo/migrations/20221103014611_create_oban_peers.exs @@ -0,0 +1,7 @@ +defmodule Pleroma.Repo.Migrations.CreateObanPeers do + use Ecto.Migration + + def up, do: Oban.Migrations.up(version: 11) + + def down, do: Oban.Migrations.down(version: 11) +end diff --git a/priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs b/priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs new file mode 100644 index 000000000..54e2503de --- /dev/null +++ b/priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs @@ -0,0 +1,26 @@ +defmodule Pleroma.Repo.Migrations.SwapPrimaryObanIndexes do + use Ecto.Migration + + @disable_ddl_transaction true + @disable_migration_lock true + + def change do + create_if_not_exists( + index( + :oban_jobs, + [:state, :queue, :priority, :scheduled_at, :id], + concurrently: true, + prefix: "public" + ) + ) + + drop_if_exists( + index( + :oban_jobs, + [:queue, :state, :priority, :scheduled_at, :id], + concurrently: true, + prefix: "public" + ) + ) + end +end diff --git a/priv/repo/migrations/20221111164213_deprecate_quack.exs b/priv/repo/migrations/20221111164213_deprecate_quack.exs new file mode 100644 index 000000000..d30fe8117 --- /dev/null +++ b/priv/repo/migrations/20221111164213_deprecate_quack.exs @@ -0,0 +1,24 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.DeprecateQuack do + use Ecto.Migration + alias Pleroma.ConfigDB + + def up do + :quack + |> ConfigDB.get_all_by_group() + |> Enum.each(&ConfigDB.delete/1) + + logger_config = ConfigDB.get_by_group_and_key(:logger, :backends) + + if not is_nil(logger_config) do + %{value: backends} = logger_config + new_backends = backends -- [Quack.Logger] + {:ok, _} = ConfigDB.update_or_create(%{group: :logger, key: :backends, value: new_backends}) + end + end + + def down, do: :ok +end diff --git a/priv/scrubbers/default.ex b/priv/scrubbers/default.ex index 79fa6dcdf..e10e3ec87 100644 --- a/priv/scrubbers/default.ex +++ b/priv/scrubbers/default.ex @@ -68,13 +68,14 @@ defmodule Pleroma.HTML.Scrubber.Default do @allow_inline_images Pleroma.Config.get([:markup, :allow_inline_images]) if @allow_inline_images do + Meta.allow_tag_with_this_attribute_values(:img, "class", ["emoji"]) + # restrict img tags to http/https only, because of MediaProxy. Meta.allow_tag_with_uri_attributes(:img, ["src"], ["http", "https"]) Meta.allow_tag_with_these_attributes(:img, [ "width", "height", - "class", "title", "alt" ]) diff --git a/priv/scrubbers/twitter_text.ex b/priv/scrubbers/twitter_text.ex index a121a8209..6e23b3efb 100644 --- a/priv/scrubbers/twitter_text.ex +++ b/priv/scrubbers/twitter_text.ex @@ -45,13 +45,14 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do # allow inline images for custom emoji if Pleroma.Config.get([:markup, :allow_inline_images]) do + Meta.allow_tag_with_this_attribute_values(:img, "class", ["emoji"]) + # restrict img tags to http/https only, because of MediaProxy. Meta.allow_tag_with_uri_attributes(:img, ["src"], ["http", "https"]) Meta.allow_tag_with_these_attributes(:img, [ "width", "height", - "class", "title", "alt" ]) diff --git a/priv/static/instance/static.css b/priv/static/instance/static.css index 487e1ec27..48c74c125 100644 Binary files a/priv/static/instance/static.css and b/priv/static/instance/static.css differ diff --git a/priv/static/schemas/litepub-0.1.jsonld b/priv/static/schemas/litepub-0.1.jsonld index 946099a6e..650118475 100644 --- a/priv/static/schemas/litepub-0.1.jsonld +++ b/priv/static/schemas/litepub-0.1.jsonld @@ -36,7 +36,8 @@ "@id": "as:alsoKnownAs", "@type": "@id" }, - "vcard": "http://www.w3.org/2006/vcard/ns#" + "vcard": "http://www.w3.org/2006/vcard/ns#", + "formerRepresentations": "litepub:formerRepresentations" } ] } diff --git a/priv/templates/sample_config.eex b/priv/templates/sample_config.eex index 0068969ac..d44c324ca 100644 --- a/priv/templates/sample_config.eex +++ b/priv/templates/sample_config.eex @@ -3,11 +3,7 @@ # NOTE: This file should not be committed to a repo or otherwise made public # without removing sensitive information. -<%= if Code.ensure_loaded?(Config) or not Code.ensure_loaded?(Mix.Config) do - "import Config" -else - "use Mix.Config" -end %> +import Config config :pleroma, Pleroma.Web.Endpoint, url: [host: "<%= domain %>", scheme: "https", port: <%= port %>], diff --git a/restarter/lib/pleroma.ex b/restarter/lib/pleroma.ex index 149a569ce..a7186cec4 100644 --- a/restarter/lib/pleroma.ex +++ b/restarter/lib/pleroma.ex @@ -61,6 +61,12 @@ def handle_cast(:refresh, _state) do {:noreply, @init_state} end + # Don't actually restart during tests. + # We just check if the correct call has been done. + # If we actually restart, we get errors during the tests like + # (RuntimeError) could not lookup Ecto repo Pleroma.Repo because it was not started or + # it does not exist + # See tests in Pleroma.Config.TransferTaskTest def handle_cast({:restart, :test, _}, state) do Logger.debug("pleroma manually restarted") {:noreply, Map.put(state, :need_reboot, false)} @@ -74,6 +80,12 @@ def handle_cast({:restart, _, delay}, state) do def handle_cast({:after_boot, _}, %{after_boot: true} = state), do: {:noreply, state} + # Don't actually restart during tests. + # We just check if the correct call has been done. + # If we actually restart, we get errors during the tests like + # (RuntimeError) could not lookup Ecto repo Pleroma.Repo because it was not started or + # it does not exist + # See tests in Pleroma.Config.TransferTaskTest def handle_cast({:after_boot, :test}, state) do Logger.debug("pleroma restarted after boot") state = %{state | after_boot: true, rebooted: true} diff --git a/restarter/mix.exs b/restarter/mix.exs index b0908aece..4bb9b76e2 100644 --- a/restarter/mix.exs +++ b/restarter/mix.exs @@ -5,7 +5,7 @@ def project do [ app: :restarter, version: "0.1.0", - elixir: "~> 1.8", + elixir: "~> 1.10", start_permanent: Mix.env() == :prod, deps: deps() ] @@ -13,7 +13,8 @@ def project do def application do [ - mod: {Restarter, []} + mod: {Restarter, []}, + extra_applications: [:logger] ] end diff --git a/test/fixtures/config/temp.secret.exs b/test/fixtures/config/temp.secret.exs index d4140d0c4..e5709ba6f 100644 --- a/test/fixtures/config/temp.secret.exs +++ b/test/fixtures/config/temp.secret.exs @@ -8,8 +8,6 @@ config :pleroma, :second_setting, key: "value2", key2: ["Activity"] -config :quack, level: :info - config :pleroma, Pleroma.Repo, pool: Ecto.Adapters.SQL.Sandbox config :postgrex, :json_library, Poison diff --git a/test/fixtures/create-pleroma-reply-to-misskey-thread.json b/test/fixtures/create-pleroma-reply-to-misskey-thread.json new file mode 100644 index 000000000..0c31efa76 --- /dev/null +++ b/test/fixtures/create-pleroma-reply-to-misskey-thread.json @@ -0,0 +1,61 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://p.helene.moe/schemas/litepub-0.1.jsonld", + { + "@language": "und" + } + ], + "actor": "https://p.helene.moe/users/helene", + "attachment": [], + "attributedTo": "https://p.helene.moe/users/helene", + "cc": [ + "https://p.helene.moe/users/helene/followers" + ], + "context": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d", + "conversation": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d", + "directMessage": false, + "id": "https://p.helene.moe/activities/5f80db86-a9bb-4883-9845-fbdbd1478f3a", + "object": { + "actor": "https://p.helene.moe/users/helene", + "attachment": [], + "attributedTo": "https://p.helene.moe/users/helene", + "cc": [ + "https://p.helene.moe/users/helene/followers" + ], + "content": "@mametsuko meow", + "context": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d", + "conversation": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d", + "id": "https://p.helene.moe/objects/fd5910ac-d9dc-412e-8d1d-914b203296c4", + "inReplyTo": "https://mk.absturztau.be/notes/93e7nm8wqg", + "published": "2022-08-02T13:46:58.403996Z", + "sensitive": null, + "source": "@mametsuko@mk.absturztau.be meow", + "summary": "", + "tag": [ + { + "href": "https://mk.absturztau.be/users/8ozbzjs3o8", + "name": "@mametsuko@mk.absturztau.be", + "type": "Mention" + } + ], + "to": [ + "https://mk.absturztau.be/users/8ozbzjs3o8", + "https://www.w3.org/ns/activitystreams#Public" + ], + "type": "Note" + }, + "published": "2022-08-02T13:46:58.403883Z", + "tag": [ + { + "href": "https://mk.absturztau.be/users/8ozbzjs3o8", + "name": "@mametsuko@mk.absturztau.be", + "type": "Mention" + } + ], + "to": [ + "https://mk.absturztau.be/users/8ozbzjs3o8", + "https://www.w3.org/ns/activitystreams#Public" + ], + "type": "Create" +} \ No newline at end of file diff --git a/test/fixtures/owncast-note-with-attachment.json b/test/fixtures/owncast-note-with-attachment.json new file mode 100644 index 000000000..68cb6bbf7 --- /dev/null +++ b/test/fixtures/owncast-note-with-attachment.json @@ -0,0 +1,31 @@ +{ + "attachment": { + "content": "Live stream preview", + "type": "Image", + "url": "https://owncast.localhost.localdomain/preview.gif?us=KjfNX387gm" + }, + "attributedTo": "https://owncast.localhost.localdomain/federation/user/streamer", + "audience": "https://www.w3.org/ns/activitystreams#Public", + "content": "

I've gone live!

#owncast #streaming

https://owncast.localhost.localdomain", + "id": "https://owncast.localhost.localdomain/federation/KjBNuq8ng", + "published": "2022-04-17T15:42:03Z", + "tag": [ + { + "href": "https://directory.owncast.online/tags/owncast", + "name": "#owncast", + "type": "Hashtag" + }, + { + "href": "https://directory.owncast.online/tags/streaming", + "name": "#streaming", + "type": "Hashtag" + }, + { + "href": "https://directory.owncast.online/tags/owncast", + "name": "#owncast", + "type": "Hashtag" + } + ], + "to": "https://www.w3.org/ns/activitystreams#Public", + "type": "Note" +} diff --git a/test/fixtures/rsa_keys/key_1.pem b/test/fixtures/rsa_keys/key_1.pem new file mode 100644 index 000000000..3da357500 --- /dev/null +++ b/test/fixtures/rsa_keys/key_1.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA2gdPJM5bWarGZ6QujfQ296l1yEQohS5fdtnxYQc+RXuS1gqZ +R/jVGHG25o4tmwyCLClyREU1CBTOCQBsg+BSehXlxNR9fiB4KaVQW9MMNa2vhHuG +f7HLdILiC+SPPTV1Bi8LCpxJowiSpnFPP4BDDeRKib7nOxll9Ln9gEpUueKKabsQ +EQKCmEJYhIz/8g5R0Qz+6VjASdejDjTEdZbr/rwyldRRjIklyeZ3lBzB/c8/51wn +HT2Dt0r9NiapxYC3oNhbE2A+4FU9pZTqS8yc3KqWZAy74snaRO9QQSednKlOJpXP +V3vwWo5CxuSNLttV7zRcrqeYOkIVNF4dQ/bHzQIDAQABAoIBADTCfglnEj4BkF92 +IHnjdgW6cTEUJUYNMba+CKY1LYF85Mx85hi/gzmWEu95yllxznJHWUpiAPJCrpUJ +EDldaDf44pAd53xE+S8CvQ5rZNH8hLOnfKWb7aL1JSRBm9PxAq+LZL2dkkgsg+hZ +FRdFv3Q2IT9x/dyUSdLNyyVnV1dfoya/7zOFc7+TwqlofznzrlBgNoAe8Lb4AN/q +itormPxskqATiq11XtP4F6eQ556eRgHCBxmktx/rRDl6f9G9dvjRQOA2qZlHQdFq +kjOZsrvItL46LdVoLPOdCYG+3HFeKoDUR1NNXEkt66eqmEhLY4MgzGUT1wqXWk7N +XowZc9UCgYEA+L5h4PhANiY5Kd+PkRI8zTlJMv8hFqLK17Q0p9eL+mAyOgXjH9so +QutJf4wU+h6ESDxH+1tCjCN307uUqT7YnT2zHf3b6GcmA+t6ewxfxOY2nJ82HENq +hK1aodnPTvRRRqCGfrx9qUHRTarTzi+2u86zH+KoMHSiuzn4VpQhg4MCgYEA4GOL +1tLR9+hyfYuMFo2CtQjp3KpJeGNKEqc33vFD05xJQX+m5THamBv8vzdVlVrMh/7j +iV85mlA7HaaP+r5DGwtonw9bqY76lYRgJJprsS5lHcRnXsDmU4Ne8RdB3dHNsT5P +n4P6v8y4jaT638iJ/qLt4e8itOBlZwS//VIglm8CgYEA7KXD3RKRlHK9A7drkOs2 +6VBM8bWEN1LdhGYvilcpFyUZ49XiBVatcS0EGdKdym/qDgc7vElQgJ7ly4y0nGfs +EXy3whrYcrxfkG8hcZuOKXeUEWHvSuhgmKWMilr8PfN2t6jVDBIrwzGY/Tk+lPUT +9o1qITW0KZVtlI5MU6JOWB0CgYAHwwnETZibxbuoIhqfcRezYXKNgop2EqEuUgB5 +wsjA2igijuLcDMRt/JHan3RjbTekAKooR1X7w4i39toGJ2y008kzr1lRXTPH1kNp +ILpW767pv7B/s5aEDwhKuK47mRVPa0Nf1jXnSpKbu7g943b6ivJFnXsK3LRFQwHN +JnkgGwKBgGUleQVd2GPr1dkqLVOF/s2aNB/+h2b1WFWwq0YTnW81OLwAcUVE4p58 +3GQgz8PCsWbNdTb9yFY5fq0fXgi0+T54FEoZWH09DrOepA433llAwI6sq7egrFdr +kKQttZMzs6ST9q/IOF4wgqSnBjjTC06vKSkNAlXJz+LMvIRMeBr0 +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/rsa_keys/key_2.pem b/test/fixtures/rsa_keys/key_2.pem new file mode 100644 index 000000000..7a8e8e670 --- /dev/null +++ b/test/fixtures/rsa_keys/key_2.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAwu0VqVGRVDW09V3zZ0+08K9HMKivIzIInO0xim3jbfVcg8r1 +sR7vNLorYAB6TDDlXYAWKx1OxUMZusbOigrpQd+5wy8VdCogDD7qk4bbZ+NjXkuD +ETzrQsGWUXe+IdeH8L0Zh0bGjbarCuA0qAeY1TEteGl+Qwo2dsrBUH7yKmWO6Mz9 +XfPshrIDOGo4QNyVfEBNGq2K9eRrQUHeAPcM2/qu4ZAZRK+VCifDZrF8ZNpoAsnS +R2mJDhOBUMvI/ZaxOc2ry4EzwcS4uBaM2wONkGWDaqO6jNAQflaX7vtzOAeJB7Dt +VKXUUcZAGN7uI3c2mG5IKGMhTYUtUdrzmqmtZwIDAQABAoIBAQCHBJfTf3dt4AGn +T9twfSp06MQj9UPS2i5THI0LONCm8qSReX0zoZzJZgbzaYFM0zWczUMNvDA6vR7O +XDTmM2acxW4zv6JZo3Ata0sqwuepDz1eLGnt/8dppxQK/ClL4bH8088h/6k6sgPJ +9cEjfpejXHwFgvT9VM6i/BBpRHVTXWuJqwpDtg+bleQNN3L3RapluDd7BGiKoCwQ +cCTKd+lxTu9gVJkbRTI/Jn3kV+rnedYxHTxVp5cU1qIabsJWBcdDz25mRHupxQsn +JbQR4+ZnRLeAsC6WJZtEJz2KjXgBaYroHbGZY3KcGW95ILqiCJoJJugbW1eABKnN +Q5k8XVspAoGBAPzGJBZuX3c0quorhMIpREmGq2vS6VCQwLhH5qayYYH1LiPDfpdq +69lOROxZodzLxBgTf5z/a5kBF+eNKvOqfZJeRTxmllxxO1MuJQuRLi/b7BHHLuyN +Eea+YwtehA0T0CbD2hydefARNDruor2BLvt/kt6qEoIFiPauTsMfXP39AoGBAMVp +8argtnB+vsk5Z7rpQ4b9gF5QxfNbA0Hpg5wUUdYrUjFr50KWt1iowj6AOVp/EYgr +xRfvOQdYODDH7R5cjgMbwvtpHo39Zwq7ewaiT1sJXnpGmCDVh+pdTHePC5OOXnxN +0USK3M4KjltjVqJo7xPPElgJvCejudD47mtHMaQzAoGBAIFQ/PVc0goyL55NVUXf +xse21cv7wtEsvOuKHT361FegD1LMmN7uHGq32BryYBSNSmzmzMqNAYbtQEV9uxOd +jVBsWg9kjFgOtcMAQIOCapahdExEEoWCRj49+H3AhN4L3Nl4KQWqqs9efdIIc8lv +ZZHU2lZ/u6g5HLDWzASW7wQhAoGAdERPRrqN+HdNWinrA9Q6JxjKL8IWs5rYsksb +biMxh5eAEwdf7oHhfd/2duUB4mCQLMjKjawgxEia33AAIS+VnBMPpQ5mJm4l79Y3 +QNL7Nbyw3gcRtdTM9aT5Ujj3MnJZB5C1PU8jeF4TNZOuBH0UwW/ld+BT5myxFXhm +wtvtSq0CgYEA19b0/7il4Em6uiLOmYUuqaUoFhUPqzjaS6OM/lRAw12coWv/8/1P +cwaNZHNMW9Me/bNH3zcOTz0lxnYp2BeRehjFYVPRuS1GU7uwqKtlL2wCPptTfAhN +aJWIplzUCTg786u+sdNZ0umWRuCLoUpsKTgP/yt4RglzEcfxAuBDljk= +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/rsa_keys/key_3.pem b/test/fixtures/rsa_keys/key_3.pem new file mode 100644 index 000000000..fbd25c80f --- /dev/null +++ b/test/fixtures/rsa_keys/key_3.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA0GvzqZ3r78GLa7guGn+palKRLGru4D4jnriHgfrUAJrdLyZ5 +9d0zAA4qnS2L6YAMoPPBhBUtIV5e2sn1+rwTClWU3dm3FyBAeqdeIBKN+04AyrUc +HXYaZtOPJXCTeytzoSQE359Tq6+xwgoHlUWSWxQF51/z/PDQcUvqFjJqAtdiDchd +3CiFRtdjegyxXGnqvPmBix+vEjDytcVydfch+R1Twf6f5EL7a1jFVWNGcratYBEl +nqOWKI2fBu/WA8QlrcVW5zmtZo9aJ6IrFddQgQTxPk/mEHgCzv8tbCRI9TxiXeYH +YqxZFYBW40xbZQwGRjaYHJlIRYp9+TOynW9OZQIDAQABAoIBAQC97cIMDbdVsyAk +N6D70N5H35ofygqJGtdG6o3B6xuKuZVaREvbu4mgQUigF0Nqs5/OhJMSlGGeCOuT +oXug1Abd4gNY7++jCWb43tAtlfsAyaJ7FvPZ/SguEBhgW+hp07z5WWN/jSeoSuFI +G++xHcczbFm88XncRG8O78kQFTz5/DlQYkFXfbqpuS3BqxnrACpDCUfrUwZNYFIp +CUNq21jdifhHwlS0K3PX8A5HdOYeVnVHaE78LGE4oJVHwcokELv+PYqarWZq/a6L +vKU3yn2+4pj2WO490iGQaRKVM35vrtjdVxiWEIUiFc3Jg5fKZA3wuHXoF1N1DpPO +BO6Att55AoGBAP/nC2szmDcnU5Sh8LDeQbL+FpSBwOmFnmel5uqbjKnDzf9emPQu +NFUls1N9OGgyUq08TnmcY/7wLZzcu7Y9XOUURuYtx9nGRs4RmE2VEBhK1r7CkDIx +oOb+NtdqnPtQASAxCHszoGCFxpuV7UVoo2SRgc+M4ceX128arvBUtvdrAoGBANCA +RuO3eelkXaJoCeogEUVWXZ6QmPeYzbMD4vg2DM0ynUbReyuEIIhn+SR7tehlj5ie +4T3ixVdur6k+YUdiFhUYgXaHBJWHoHl1lrU3ZON8n7AeEk9ft6gg4L07ouj78UMZ +sArJIlU5mLnW02zbV9XryU39dIgpQREqC0bIOtVvAoGBAORv1JKq6Rt7ALJy6VCJ +5y4ogfGp7pLHk8NEpuERYDz/rLllMbbwNAk6cV17L8pb+c/pQMhwohcnQiCALxUc +q/tW4X+CqJ+vzu8PZ90Bzu9Qh2iceGpGQTNTBZPA+UeigI7DFqYcTPM9GDE1YiyO +nyUcezvSsI4i7s6gjD+/7+DnAoGABm3+QaV1z/m1XX3B2IN2pOG971bcML54kW2s +QSVBjc5ixT1OhBAGBM7YAwUBnhILtJQptAPbPBAAwMJYs5/VuH7R9zrArG/LRhOX +Oy1jIhTEw+SZgfMcscWZyJwfMPob/Yq8QAjl0yT8jbaPPIsjEUi9I3eOcWh8RjA6 +ussP7WcCgYEAm3yvJR9z6QGoQQwtDbwjyZPYOSgK9wFS/65aupi6cm/Qk2N1YaLY +q2amNrzNsIc9vQwYGEHUwogn4MieHk96V7m2f0Hx9EHCMwizU9EiS6oyiLVowTG6 +YsBgSzcpnt0Vkgil4CQks5uQoan0tubEUQ5DI79lLnb02n4o46iAYK0= +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/rsa_keys/key_4.pem b/test/fixtures/rsa_keys/key_4.pem new file mode 100644 index 000000000..f72b29fb1 --- /dev/null +++ b/test/fixtures/rsa_keys/key_4.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAw6MLRbP/henX2JxwdMkQlskKghBoMyUPu9kZpUQ9yYfIm9I4 +a3gEfzef75jKLOSf+BkZulvEUGjC+VnkpV3s+OZCSq81Ykv5PHuTqbj8Cn/dEt/g +lBXxPcOBKWqa+1cDX6QVIVJsBihLB/1b64H3U96Yu9+knmXvT1Az5MFA2KtSq7HJ +O+GJNn0EMI7xwPz/atUGlMLrhzwS4UDpw9CAaRPojplJYl4K1JMCFTgTt3hJILXZ +tw1MKTeeyWzNiuQRBQJuCnqfvsBYsasIlHWfqIL/uBzcGHHCIK5ZW9luntJXyLVj +zzaF7etIJk1uddM2wnqOOaVyqbssZXGt7Tb9IQIDAQABAoIBAH5QJRUKFK8Xvp9C +0nD06NsSTtCPW1e6VCBLGf3Uw7f9DY9d+cOZp/2jooYGNnMp4gdD3ZKvcV8hZNGu +Mqx6qmhB8wdZfLRMrU1Z1Is+vqzgxZJMLiouyKXCNwDQreQd2DXGMUZkew62sUsl +UFYMge4KyL50tUr4Mb0Z4YePJxk804tcqgw0n+D0lR7ZKhSqoQpoMqEiO+27Yw7E +Txj/MKH8f/ZJ6LBLRISOdBOrxonHqqeYWchczykCwojOZc3bIlWZGhg727dFTHDC +yrj3/zsZ2hy+TQsucCFY0RljIbacmHvrF/VqfhTIhg98H0F27V/jiPGsdKhptyst +E9iQVMkCgYEA42ge4H2Wl42sRh61GOrOgzzr0WZS54bF5skMxiGGnLwnb82rwUBt +xw94PRORJbV9l+2fkxbfiW0uzornfN8OBHSB64Pcjzzbl5Qm+eaDOiuTLtakYOWQ +/ipGqw8iE4J9iRteZCo8GnMxWbTkYCporTlFDTeYguXmwR4yCXtlCbMCgYEA3DxM +7R5HMUWRe64ucdekMh742McS8q/X5jdN9iFGy0M8P1WTyspSlaPDXgjaO4XqpRqg +djkL993kCDvOAiDl6Tpdiu1iFcOaRLb19Tj1pm8sKdk6X4d10U9lFri4NVYCmvVi +yOahUYFK/k5bA+1o+KU9Pi82H36H3WNeF4evC9sCgYEAs1zNdc04uQKiTZAs0KFr +DzI+4aOuYjT35ObQr3mD/h2dkV6MSNmzfF1kPfAv/KkgjXN7+H0DBRbb40bF/MTF +/peSXZtcnJGote7Bqzu4Z2o1Ja1ga5jF+uKHaKZ//xleQIUYtzJkw4v18cZulrb8 +ZxyTrTAbl6sTjWBuoPH1qGcCgYEAsQNahR9X81dKJpGKTQAYvhw8wOfI5/zD2ArN +g62dXBRPYUxkPJM/q3xzs6oD1eG+BjQPktYpM3FKLf/7haRxhnLd6qL/uiR8Ywx3 +RkEg2EP0yDIMA+o5nSFmS8vuaxgVgf0HCBiuwnbcEuhhqRdxzp/pSIjjxI6LnzqV +zu3EmQ8CgYEAhq8Uhvw+79tK7q2PCjDbiucA0n/4a3aguuvRoEh7F93Pf6VGZmT+ +Yld54Cd4P5ATI3r5YdD+JBuvgNMOTVPCaD/WpjbJKnrpNEXtXRQD6LzAXZDNk0sF +IO9i4gjhBolRykWn10khoPdxw/34FWBP5SxU1JYk75NQXvI3TD+5xbU= +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/rsa_keys/key_5.pem b/test/fixtures/rsa_keys/key_5.pem new file mode 100644 index 000000000..49342b54e --- /dev/null +++ b/test/fixtures/rsa_keys/key_5.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA0jdKtMkgqnEGO3dn4OKxtggfFDzv+ddXToO0cdPXkUgPajCo +UGPunz+A1KmkAmLY0Vwk0tkOmKK8GFHek/5zQ+1N2FHBi19fbwlJk7hzh5OiYRhu +YZi0d6LsqEMKhDk6NqIeiFmOe2YHgklVvZV0hebvHlHLgzDhYrDltSPe33UZa3MS +g2Knf4WQAjLOo2BAb+oyj/UNXeAqaMGcOr6/kAHPcODW2EGhF3H3umFLv7t/Kq5i +WPBgarbCGPR5qq9SW5ZIjS3Sz0dl105Grw8wU23CC/2IBZ5vNiu+bkmLEoh/KpX2 +YBILoLmwtVX0Qxc15CrpOi12p+/4pLR8kuEowQIDAQABAoIBAQDMDQ3AJMdHisSQ +7pvvyDzWRFXesDQE4YmG1gNOxmImTLthyW9n8UjMXbjxNOXVxxtNRdMcs8MeWECa +nsWeBEzgr7VzeBCV9/LL9kjsUgwamyzwcOWcaL0ssAJmZgUMSfx+0akvkzbiAyzg +w8ytZSihXYPYe28/ni/5O1sOFI6feenOnJ9NSmVUA24c9TTJGNQs7XRUMZ8f9wt6 +KwRmYeNDKyqH7NvLmmKoDp6m7bMDQxWArVTAoRWTVApnj35iLQtmSi8DBdw6xSzQ +fKpUe/B4iQmMNxUW7KmolOvCIS5wcYZJE+/j7xshA2GGnOpx4aC+N+w2GSX4Bz/q +OnYSpGUBAoGBAOwnSeg17xlZqmd86qdiCxg0hRtAjwrd7btYq6nkK+t9woXgcV99 +FBS3nLbk/SIdXCW8vHFJTmld60j2q2kdestYBdHznwNZJ4Ee8JhamzcC64wY7O0x +RameO/6uoKS4C3VF+Zc9CCPfZOqYujkGvSqbTjFZWuFtDp0GHDk+qEIRAoGBAOPh ++PCB2QkGgiujSPmuCT5PTuNylAug3D4ZdMRKpQb9Rnzlia1Rpdrihq+PvB2vwa+S +mB6dgb0E7M2AyEMVu5buris0mVpRdmEeLCXR8mYJ48kOslIGArEStXDetfbRaXdK +7vf4APq2d78AQYldU2fYlo754Dh/3MZIguzpqMuxAoGBAIDJqG/AQiYkFV+c62ff +e0d3FQRYv+ngQE9Eu1HKwv0Jt7VFQu8din8F56yC013wfxmBhY+Ot/mUo8VF6RNJ +ZXdSCNKINzcfPwEW+4VLHIzyxbzAty1gCqrHRdbOK4PJb05EnCqTuUW/Bg0+v4hs +GWwMCKe3IG4CCM8vzuKVPjPRAoGBANYCQtJDb3q9ZQPsTb1FxyKAQprx4Lzm7c9Y +AsPRQhhFRaxHuLtPQU5FjK1VdBoBFAl5x2iBDPVhqa348pml0E0Xi/PBav9aH61n +M5i1CUrwoL4SEj9bq61133XHgeXwlnZUpgW0H99T+zMh32pMfea5jfNqETueQMzq +DiLF8SKRAoGBAOFlU0kRZmAx3Y4rhygp1ydPBt5+zfDaGINRWEN7QWjhX2QQan3C +SnXZlP3POXLessKxdCpBDq/RqVQhLea6KJMfP3F0YbohfWHt96WjiriJ0d0ZYVhu +34aUM2UGGG0Kia9OVvftESBaXk02vrY9zU3LAVAv0eLgIADm1kpj85v7 +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/tesla_mock/framatube.org_host_meta b/test/fixtures/tesla_mock/framatube.org_host_meta index 91516ff6d..02e25bd64 100644 --- a/test/fixtures/tesla_mock/framatube.org_host_meta +++ b/test/fixtures/tesla_mock/framatube.org_host_meta @@ -1,2 +1,2 @@ -framatube.orgResource Descriptor +framatube.orgResource Descriptor diff --git a/test/fixtures/tesla_mock/helene@p.helene.moe.json b/test/fixtures/tesla_mock/helene@p.helene.moe.json new file mode 100644 index 000000000..d7444817f --- /dev/null +++ b/test/fixtures/tesla_mock/helene@p.helene.moe.json @@ -0,0 +1,50 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://p.helene.moe/schemas/litepub-0.1.jsonld", + { + "@language": "und" + } + ], + "alsoKnownAs": [], + "attachment": [ + { + "name": "Timezone", + "type": "PropertyValue", + "value": "UTC+2 (Paris/Berlin)" + } + ], + "capabilities": { + "acceptsChatMessages": true + }, + "discoverable": true, + "endpoints": { + "oauthAuthorizationEndpoint": "https://p.helene.moe/oauth/authorize", + "oauthRegistrationEndpoint": "https://p.helene.moe/api/v1/apps", + "oauthTokenEndpoint": "https://p.helene.moe/oauth/token", + "sharedInbox": "https://p.helene.moe/inbox", + "uploadMedia": "https://p.helene.moe/api/ap/upload_media" + }, + "featured": "https://p.helene.moe/users/helene/collections/featured", + "followers": "https://p.helene.moe/users/helene/followers", + "following": "https://p.helene.moe/users/helene/following", + "icon": { + "type": "Image", + "url": "https://p.helene.moe/media/9a39209daa5a66b7ebb0547b08bf8360aa9d8d65a4ffba2603c6ffbe6aecb432.jpg" + }, + "id": "https://p.helene.moe/users/helene", + "inbox": "https://p.helene.moe/users/helene/inbox", + "manuallyApprovesFollowers": false, + "name": "Hélène", + "outbox": "https://p.helene.moe/users/helene/outbox", + "preferredUsername": "helene", + "publicKey": { + "id": "https://p.helene.moe/users/helene#main-key", + "owner": "https://p.helene.moe/users/helene", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtoSBPU/VS2Kx3f6ap3zv\nZVacJsgUfaoFb3c2ii/FRh9RmRVlarq8sJXcjsQt1e0oxWaWJaIDDwyKZPt6hXae\nrY/AiGGeNu+NA+BtY7l7+9Yu67HUyT62+1qAwYHKBXX3fLOPs/YmQI0Tt0c4wKAG\nKEkiYsRizghgpzUC6jqdKV71DJkUZ8yhckCGb2fLko1ajbWEssdaP51aLsyRMyC2\nuzeWrxtD4O/HG0ea4S6y5X6hnsAHIK4Y3nnyIQ6pn4tOsl3HgqkjXE9MmZSvMCFx\nBq89TfZrVXNa2gSZdZLdbbJstzEScQWNt1p6tA6rM+e4JXYGr+rMdF3G+jV7afI2\nFQIDAQAB\n-----END PUBLIC KEY-----\n\n" + }, + "summary": "I can speak: Français, English, Deutsch (nicht sehr gut), 日本語 (not very well)", + "tag": [], + "type": "Person", + "url": "https://p.helene.moe/users/helene" +} \ No newline at end of file diff --git a/test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml b/test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml new file mode 100644 index 000000000..b9e8dbbf5 --- /dev/null +++ b/test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml @@ -0,0 +1 @@ +acct:mewmew@lm.kazv.moehttps://lm.kazv.moe/users/mewmewhttps://lm.kazv.moe/users/testerhttps://lm.kazv.moe/users/testuser diff --git a/test/fixtures/tesla_mock/lm.kazv.moe_host_meta b/test/fixtures/tesla_mock/lm.kazv.moe_host_meta new file mode 100644 index 000000000..02e6f055e --- /dev/null +++ b/test/fixtures/tesla_mock/lm.kazv.moe_host_meta @@ -0,0 +1 @@ + diff --git a/test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json b/test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json new file mode 100644 index 000000000..d8c13f775 --- /dev/null +++ b/test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json @@ -0,0 +1,65 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "Hashtag": "as:Hashtag", + "quoteUrl": "as:quoteUrl", + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "featured": "toot:featured", + "discoverable": "toot:discoverable", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "misskey": "https://misskey-hub.net/ns#", + "_misskey_content": "misskey:_misskey_content", + "_misskey_quote": "misskey:_misskey_quote", + "_misskey_reaction": "misskey:_misskey_reaction", + "_misskey_votes": "misskey:_misskey_votes", + "_misskey_talk": "misskey:_misskey_talk", + "isCat": "misskey:isCat", + "vcard": "http://www.w3.org/2006/vcard/ns#" + } + ], + "type": "Person", + "id": "https://mk.absturztau.be/users/8ozbzjs3o8", + "inbox": "https://mk.absturztau.be/users/8ozbzjs3o8/inbox", + "outbox": "https://mk.absturztau.be/users/8ozbzjs3o8/outbox", + "followers": "https://mk.absturztau.be/users/8ozbzjs3o8/followers", + "following": "https://mk.absturztau.be/users/8ozbzjs3o8/following", + "featured": "https://mk.absturztau.be/users/8ozbzjs3o8/collections/featured", + "sharedInbox": "https://mk.absturztau.be/inbox", + "endpoints": { + "sharedInbox": "https://mk.absturztau.be/inbox" + }, + "url": "https://mk.absturztau.be/@mametsuko", + "preferredUsername": "mametsuko", + "name": "mametschko", + "summary": "

nya, ich bin eine Brotperson

", + "icon": { + "type": "Image", + "url": "https://mk.absturztau.be/files/webpublic-3b5594f4-fa52-4548-b4e3-c379ae2143ed", + "sensitive": false, + "name": null + }, + "image": { + "type": "Image", + "url": "https://mk.absturztau.be/files/webpublic-0d03b03d-b14b-4916-ac3d-8a137118ec84", + "sensitive": false, + "name": null + }, + "tag": [], + "manuallyApprovesFollowers": true, + "discoverable": false, + "publicKey": { + "id": "https://mk.absturztau.be/users/8ozbzjs3o8#main-key", + "type": "Key", + "owner": "https://mk.absturztau.be/users/8ozbzjs3o8", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuN/S1spBGmh8FXI1Bt16\nXB7Cc0QutBp7UPgmDNHjOfsq0zrF4g3L1UBxvrpU0XX77XPMCd9yPvGwAYURH2mv\ntIcYuE+R90VLDmBu5MTVthcG2D874eCZ2rD2YsEYmN5AjTX7QBIqCck+qDhVWkkM\nEZ6S5Ht6IJ5Of74eKffXElQI/C6QB+9uEDOmPk0jCzgI5gw7xvJqFj/DIF4kUUAu\nA89JqaFZzZlkrSrj4cr48bLN/YOmpdaHu0BKHaDSHct4+MqlixqovgdB6RboCEDw\ne4Aeav7+Q0Y9oGIvuggg0Q+nCubnVNnaPyzd817tpPVzyZmTts+DKyDuv90SX3nR\nsPaNa5Ty60eqplUk4b7X1gSvuzBJUFBxTVV84WnjwoeoydaS6rSyjCDPGLBjaByc\nFyWMMEb/zlQyhLZfBlvT7k96wRSsMszh2hDALWmgYIhq/jNwINvALJ1GKLNHHKZ4\nyz2LnxVpRm2rWrZzbvtcnSQOt3LaPSZn8Wgwv4buyHF02iuVuIamZVtKexsE1Ixl\nIi9qa3AKEc5gOzYXhRhvHaruzoCehUbb/UHC5c8Tto8L5G1xYzjLP3qj3PT9w/wM\n+k1Ra/4JhuAnVFROOoOmx9rIELLHH7juY2nhM7plGhyt1M5gysgqEloij8QzyQU2\nZK1YlAERG2XFO6br8omhcmECAwEAAQ==\n-----END PUBLIC KEY-----\n" + }, + "isCat": true, + "vcard:Address": "Vienna, Austria" +} \ No newline at end of file diff --git a/test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json b/test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json new file mode 100644 index 000000000..8d2c3e1e7 --- /dev/null +++ b/test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://lm.kazv.moe/schemas/litepub-0.1.jsonld",{"@language":"und"}],"alsoKnownAs":["https://lm.kazv.moe/users/tester","https://lm.kazv.moe/users/testuser"],"attachment":[],"capabilities":{"acceptsChatMessages":true},"discoverable":false,"endpoints":{"oauthAuthorizationEndpoint":"https://lm.kazv.moe/oauth/authorize","oauthRegistrationEndpoint":"https://lm.kazv.moe/api/v1/apps","oauthTokenEndpoint":"https://lm.kazv.moe/oauth/token","sharedInbox":"https://lm.kazv.moe/inbox","uploadMedia":"https://lm.kazv.moe/api/ap/upload_media"},"featured":"https://lm.kazv.moe/users/mewmew/collections/featured","followers":"https://lm.kazv.moe/users/mewmew/followers","following":"https://lm.kazv.moe/users/mewmew/following","id":"https://lm.kazv.moe/users/mewmew","inbox":"https://lm.kazv.moe/users/mewmew/inbox","manuallyApprovesFollowers":false,"name":"mew","outbox":"https://lm.kazv.moe/users/mewmew/outbox","preferredUsername":"mewmew","publicKey":{"id":"https://lm.kazv.moe/users/mewmew#main-key","owner":"https://lm.kazv.moe/users/mewmew","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0nT3IVUwx799FSJyJEOY\n5D2c5zgtt2Z+BD9417eVLmVQF5fJlWgcKS4pbFc76zkYoBkZtV7XbzvN9KTNulpa\nUGNOM0/UdEoQLB8xbVCMm0ABUU8vbTWoMTxp93bfVHBz+33FPYdH1JHX4TCU/mJF\nX4UJMvFmMn5BFjSQm9GG6Eq2j6SAUsaTa8+Rrd8FzS6zb/dk3N/Llz0tfsZYS0sq\nEy9OYhsKOQ6eegULFJOF3Hz04vzwftmeXFsbb3aO2zKz3uAMYZglWHNBYJAePBtJ\ng362kqdJwgT14TFnZ0K2ziDPbkRULG1Kke/lsqw2rPF6Q6P4PeO1shCEDthoDoID\newIDAQAB\n-----END PUBLIC KEY-----\n\n"},"summary":"","tag":[],"type":"Person","url":"https://lm.kazv.moe/users/mewmew"} diff --git a/test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json b/test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json new file mode 100644 index 000000000..b45ab78e4 --- /dev/null +++ b/test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","Hashtag":"as:Hashtag","quoteUrl":"as:quoteUrl","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","featured":"toot:featured","discoverable":"toot:discoverable","schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","misskey":"https://misskey-hub.net/ns#","_misskey_content":"misskey:_misskey_content","_misskey_quote":"misskey:_misskey_quote","_misskey_reaction":"misskey:_misskey_reaction","_misskey_votes":"misskey:_misskey_votes","_misskey_talk":"misskey:_misskey_talk","isCat":"misskey:isCat","vcard":"http://www.w3.org/2006/vcard/ns#"}],"id":"https://mk.absturztau.be/notes/93e7nm8wqg/activity","actor":"https://mk.absturztau.be/users/8ozbzjs3o8","type":"Create","published":"2022-08-01T11:06:49.568Z","object":{"id":"https://mk.absturztau.be/notes/93e7nm8wqg","type":"Note","attributedTo":"https://mk.absturztau.be/users/8ozbzjs3o8","summary":null,"content":"

meow

","_misskey_content":"meow","published":"2022-08-01T11:06:49.568Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mk.absturztau.be/users/8ozbzjs3o8/followers"],"inReplyTo":null,"attachment":[],"sensitive":false,"tag":[]},"to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mk.absturztau.be/users/8ozbzjs3o8/followers"]} \ No newline at end of file diff --git a/test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json b/test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json new file mode 100644 index 000000000..1b931a9a4 --- /dev/null +++ b/test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json @@ -0,0 +1,44 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "Hashtag": "as:Hashtag", + "quoteUrl": "as:quoteUrl", + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "featured": "toot:featured", + "discoverable": "toot:discoverable", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "misskey": "https://misskey-hub.net/ns#", + "_misskey_content": "misskey:_misskey_content", + "_misskey_quote": "misskey:_misskey_quote", + "_misskey_reaction": "misskey:_misskey_reaction", + "_misskey_votes": "misskey:_misskey_votes", + "_misskey_talk": "misskey:_misskey_talk", + "isCat": "misskey:isCat", + "vcard": "http://www.w3.org/2006/vcard/ns#" + } + ], + "id": "https://mk.absturztau.be/notes/93e7nm8wqg", + "type": "Note", + "attributedTo": "https://mk.absturztau.be/users/8ozbzjs3o8", + "summary": null, + "content": "

meow

", + "_misskey_content": "meow", + "published": "2022-08-01T11:06:49.568Z", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://mk.absturztau.be/users/8ozbzjs3o8/followers" + ], + "inReplyTo": null, + "attachment": [], + "sensitive": false, + "tag": [] +} \ No newline at end of file diff --git a/test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json b/test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json new file mode 100644 index 000000000..a1ef5e20b --- /dev/null +++ b/test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json @@ -0,0 +1,36 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://p.helene.moe/schemas/litepub-0.1.jsonld", + { + "@language": "und" + } + ], + "actor": "https://p.helene.moe/users/helene", + "attachment": [], + "attributedTo": "https://p.helene.moe/users/helene", + "cc": [ + "https://p.helene.moe/users/helene/followers" + ], + "content": "@mametsuko meow", + "context": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d", + "conversation": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d", + "id": "https://p.helene.moe/objects/fd5910ac-d9dc-412e-8d1d-914b203296c4", + "inReplyTo": "https://mk.absturztau.be/notes/93e7nm8wqg", + "published": "2022-08-02T13:46:58.403996Z", + "sensitive": null, + "source": "@mametsuko@mk.absturztau.be meow", + "summary": "", + "tag": [ + { + "href": "https://mk.absturztau.be/users/8ozbzjs3o8", + "name": "@mametsuko@mk.absturztau.be", + "type": "Mention" + } + ], + "to": [ + "https://mk.absturztau.be/users/8ozbzjs3o8", + "https://www.w3.org/ns/activitystreams#Public" + ], + "type": "Note" +} \ No newline at end of file diff --git a/test/fixtures/tesla_mock/status.alpicola.com_host_meta b/test/fixtures/tesla_mock/status.alpicola.com_host_meta index 6948c30ea..78155f644 100644 --- a/test/fixtures/tesla_mock/status.alpicola.com_host_meta +++ b/test/fixtures/tesla_mock/status.alpicola.com_host_meta @@ -1,2 +1,2 @@ -status.alpicola.comResource Descriptor \ No newline at end of file +status.alpicola.comResource Descriptor diff --git a/test/fixtures/webfinger/masto-host-meta.xml b/test/fixtures/webfinger/masto-host-meta.xml new file mode 100644 index 000000000..f432a27c3 --- /dev/null +++ b/test/fixtures/webfinger/masto-host-meta.xml @@ -0,0 +1,4 @@ + + + + diff --git a/test/fixtures/webfinger/masto-user.json b/test/fixtures/webfinger/masto-user.json new file mode 100644 index 000000000..1702de011 --- /dev/null +++ b/test/fixtures/webfinger/masto-user.json @@ -0,0 +1,92 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "toot": "http://joinmastodon.org/ns#", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "featuredTags": { + "@id": "toot:featuredTags", + "@type": "@id" + }, + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "IdentityProof": "toot:IdentityProof", + "discoverable": "toot:discoverable", + "Device": "toot:Device", + "Ed25519Signature": "toot:Ed25519Signature", + "Ed25519Key": "toot:Ed25519Key", + "Curve25519Key": "toot:Curve25519Key", + "EncryptedMessage": "toot:EncryptedMessage", + "publicKeyBase64": "toot:publicKeyBase64", + "deviceId": "toot:deviceId", + "claim": { + "@type": "@id", + "@id": "toot:claim" + }, + "fingerprintKey": { + "@type": "@id", + "@id": "toot:fingerprintKey" + }, + "identityKey": { + "@type": "@id", + "@id": "toot:identityKey" + }, + "devices": { + "@type": "@id", + "@id": "toot:devices" + }, + "messageFranking": "toot:messageFranking", + "messageType": "toot:messageType", + "cipherText": "toot:cipherText", + "suspended": "toot:suspended", + "focalPoint": { + "@container": "@list", + "@id": "toot:focalPoint" + } + } + ], + "id": "https://{{domain}}/users/{{nickname}}", + "type": "Person", + "following": "https://{{domain}}/users/{{nickname}}/following", + "followers": "https://{{domain}}/users/{{nickname}}/followers", + "inbox": "https://{{domain}}/users/{{nickname}}/inbox", + "outbox": "https://{{domain}}/users/{{nickname}}/outbox", + "featured": "https://{{domain}}/users/{{nickname}}/collections/featured", + "featuredTags": "https://{{domain}}/users/{{nickname}}/collections/tags", + "preferredUsername": "{{nickname}}", + "name": "Name Name", + "summary": "

Summary

", + "url": "https://{{domain}}/@{{nickname}}", + "manuallyApprovesFollowers": false, + "discoverable": false, + "devices": "https://{{domain}}/users/{{nickname}}/collections/devices", + "publicKey": { + "id": "https://{{domain}}/users/{{nickname}}#main-key", + "owner": "https://{{domain}}/users/{{nickname}}", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvwDujxmxoYHs64MyVB3L\nG5ZyBxV3ufaMRBFu42bkcTpISq1WwZ+3Zb6CI8zOO+nM+Q2llrVRYjZa4ZFnOLvM\nTq/Kf+Zf5wy2aCRer88gX+MsJOAtItSi412y0a/rKOuFaDYLOLeTkRvmGLgZWbsr\nZJOp+YWb3zQ5qsIOInkc5BwI172tMsGeFtsnbNApPV4lrmtTGaJ8RiM8MR7XANBO\nfOHggSt1+eAIKGIsCmINEMzs1mG9D75xKtC/sM8GfbvBclQcBstGkHAEj1VHPW0c\nh6Bok5/QQppicyb8UA1PAA9bznSFtKlYE4xCH8rlCDSDTBRtdnBWHKcj619Ujz4Q\nawIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "tag": [], + "attachment": [], + "endpoints": { + "sharedInbox": "https://{{domain}}/inbox" + }, + "icon": { + "type": "Image", + "mediaType": "image/jpeg", + "url": "https://s3.wasabisys.com/merp/accounts/avatars/000/000/001/original/6fdd3eee632af247.jpg" + } +} diff --git a/test/fixtures/webfinger/masto-webfinger.json b/test/fixtures/webfinger/masto-webfinger.json new file mode 100644 index 000000000..561be3fff --- /dev/null +++ b/test/fixtures/webfinger/masto-webfinger.json @@ -0,0 +1,23 @@ +{ + "subject": "acct:{{nickname}}@{{domain}}", + "aliases": [ + "https://{{subdomain}}/@{{nickname}}", + "https://{{subdomain}}/users/{{nickname}}" + ], + "links": [ + { + "rel": "http://webfinger.net/rel/profile-page", + "type": "text/html", + "href": "https://{{subdomain}}/@{{nickname}}" + }, + { + "rel": "self", + "type": "application/activity+json", + "href": "https://{{subdomain}}/users/{{nickname}}" + }, + { + "rel": "http://ostatus.org/schema/1.0/subscribe", + "template": "https://{{subdomain}}/authorize_interaction?uri={uri}" + } + ] +} diff --git a/test/fixtures/webfinger/pleroma-host-meta.xml b/test/fixtures/webfinger/pleroma-host-meta.xml new file mode 100644 index 000000000..88c274a1a --- /dev/null +++ b/test/fixtures/webfinger/pleroma-host-meta.xml @@ -0,0 +1 @@ + diff --git a/test/fixtures/webfinger/pleroma-user.json b/test/fixtures/webfinger/pleroma-user.json new file mode 100644 index 000000000..b822db46c --- /dev/null +++ b/test/fixtures/webfinger/pleroma-user.json @@ -0,0 +1,58 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://{{domain}}/schemas/litepub-0.1.jsonld", + { + "@language": "und" + } + ], + "alsoKnownAs": [], + "attachment": [], + "capabilities": { + "acceptsChatMessages": true + }, + "discoverable": true, + "endpoints": { + "oauthAuthorizationEndpoint": "https://{{domain}}/oauth/authorize", + "oauthRegistrationEndpoint": "https://{{domain}}/api/v1/apps", + "oauthTokenEndpoint": "https://{{domain}}/oauth/token", + "sharedInbox": "https://{{domain}}/inbox", + "uploadMedia": "https://{{domain}}/api/ap/upload_media" + }, + "followers": "https://{{domain}}/users/{{nickname}}/followers", + "following": "https://{{domain}}/users/{{nickname}}/following", + "icon": { + "type": "Image", + "url": "https://{{domain}}/media/a932a27f158b63c3a97e3a57d5384f714a82249274c6fc66c9eca581b4fd8af2.jpg" + }, + "id": "https://{{domain}}/users/{{nickname}}", + "image": { + "type": "Image", + "url": "https://{{domain}}/media/db15f476d0ad14488db4762b7800479e6ef67b1824f8b9ea5c1fa05b7525c5b7.jpg" + }, + "inbox": "https://{{domain}}/users/{{nickname}}/inbox", + "manuallyApprovesFollowers": false, + "name": "{{nickname}} :verified:", + "outbox": "https://{{domain}}/users/{{nickname}}/outbox", + "preferredUsername": "{{nickname}}", + "publicKey": { + "id": "https://{{domain}}/users/{{nickname}}#main-key", + "owner": "https://{{domain}}/users/{{nickname}}", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4XOAopC4nRIxNlHlt60\n//nCicuedu5wvLGIoQ+KUM2u7/PhLrrTDEqr1A7yQL95S0X8ryYtALgFLI5A54ww\nqjMIbIGAs44lEmDLMEd+XI+XxREE8wdsFpb4QQzWug0DTyqlMouTU25k0tfKh1rF\n4PMJ3uBSjDTAGgFvLNyFWTiVVgChbTNgGOmrEBucRl4NmKzQ69/FIUwENV88oQSU\n3bWvQTEH9rWH1rCLpkmQwdRiWfnhFX/4EUqXukfgoskvenKR8ff3nYhElDqFoE0e\nqUnIW1OZceyl8JewVLcL6m0/wdKeosTsfrcWc8DKfnRYQcBGNoBEq9GrOHDU0q2v\nyQIDAQAB\n-----END PUBLIC KEY-----\n\n" + }, + "summary": "Pleroma BE dev", + "tag": [ + { + "icon": { + "type": "Image", + "url": "https://{{domain}}/emoji/mine/6143373a807b1ae7.png" + }, + "id": "https://{{domain}}/emoji/mine/6143373a807b1ae7.png", + "name": ":verified:", + "type": "Emoji", + "updated": "1970-01-01T00:00:00Z" + } + ], + "type": "Person", + "url": "https://{{domain}}/users/{{nickname}}" +} diff --git a/test/fixtures/webfinger/pleroma-webfinger.json b/test/fixtures/webfinger/pleroma-webfinger.json new file mode 100644 index 000000000..8f075eaaf --- /dev/null +++ b/test/fixtures/webfinger/pleroma-webfinger.json @@ -0,0 +1,27 @@ +{ + "aliases": [ + "https://{{subdomain}}/users/{{nickname}}" + ], + "links": [ + { + "href": "https://{{subdomain}}/users/{{nickname}}", + "rel": "http://webfinger.net/rel/profile-page", + "type": "text/html" + }, + { + "href": "https://{{subdomain}}/users/{{nickname}}", + "rel": "self", + "type": "application/activity+json" + }, + { + "href": "https://{{subdomain}}/users/{{nickname}}", + "rel": "self", + "type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + }, + { + "rel": "http://ostatus.org/schema/1.0/subscribe", + "template": "https://{{subdomain}}/ostatus_subscribe?acct={uri}" + } + ], + "subject": "acct:{{nickname}}@{{domain}}" +} diff --git a/test/mix/tasks/pleroma/config_test.exs b/test/mix/tasks/pleroma/config_test.exs index f90ef8804..cf6d74907 100644 --- a/test/mix/tasks/pleroma/config_test.exs +++ b/test/mix/tasks/pleroma/config_test.exs @@ -49,7 +49,6 @@ test "error if file with custom settings doesn't exist" do describe "migrate_to_db/1" do setup do clear_config(:configurable_from_database, true) - clear_config([:quack, :level]) end @tag capture_log: true @@ -72,14 +71,12 @@ test "filtered settings are migrated to db" do config1 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":first_setting"}) config2 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":second_setting"}) - config3 = ConfigDB.get_by_params(%{group: ":quack", key: ":level"}) refute ConfigDB.get_by_params(%{group: ":pleroma", key: "Pleroma.Repo"}) refute ConfigDB.get_by_params(%{group: ":postgrex", key: ":json_library"}) refute ConfigDB.get_by_params(%{group: ":pleroma", key: ":database"}) assert config1.value == [key: "value", key2: [Repo]] assert config2.value == [key: "value2", key2: ["Activity"]] - assert config3.value == :info end test "config table is truncated before migration" do @@ -108,7 +105,6 @@ test "config table is truncated before migration" do test "settings are migrated to file and deleted from db", %{temp_file: temp_file} do insert_config_record(:pleroma, :setting_first, key: "value", key2: ["Activity"]) insert_config_record(:pleroma, :setting_second, key: "value2", key2: [Repo]) - insert_config_record(:quack, :level, :info) MixTask.run(["migrate_from_db", "--env", "temp", "-d"]) @@ -117,7 +113,6 @@ test "settings are migrated to file and deleted from db", %{temp_file: temp_file file = File.read!(temp_file) assert file =~ "config :pleroma, :setting_first," assert file =~ "config :pleroma, :setting_second," - assert file =~ "config :quack, :level, :info" end test "load a settings with large values and pass to file", %{temp_file: temp_file} do @@ -199,7 +194,6 @@ test "load a settings with large values and pass to file", %{temp_file: temp_fil setup do insert_config_record(:pleroma, :setting_first, key: "value", key2: ["Activity"]) insert_config_record(:pleroma, :setting_second, key: "value2", key2: [Repo]) - insert_config_record(:quack, :level, :info) path = "test/instance_static" file_path = Path.join(path, "temp.exported_from_db.secret.exs") @@ -215,7 +209,6 @@ test "with path parameter", %{file_path: file_path} do file = File.read!(file_path) assert file =~ "config :pleroma, :setting_first," assert file =~ "config :pleroma, :setting_second," - assert file =~ "config :quack, :level, :info" end test "release", %{file_path: file_path} do @@ -227,7 +220,6 @@ test "release", %{file_path: file_path} do file = File.read!(file_path) assert file =~ "config :pleroma, :setting_first," assert file =~ "config :pleroma, :setting_second," - assert file =~ "config :quack, :level, :info" end end diff --git a/test/pleroma/activity/ir/topics_test.exs b/test/pleroma/activity/ir/topics_test.exs index 311f85dea..d299fea63 100644 --- a/test/pleroma/activity/ir/topics_test.exs +++ b/test/pleroma/activity/ir/topics_test.exs @@ -13,6 +13,29 @@ defmodule Pleroma.Activity.Ir.TopicsTest do import Mock + describe "chat message" do + test "Create produces no topics" do + activity = %Activity{ + object: %Object{data: %{"type" => "ChatMessage"}}, + data: %{"type" => "Create"} + } + + assert [] == Topics.get_activity_topics(activity) + end + + test "Delete produces user and user:pleroma_chat" do + activity = %Activity{ + object: %Object{data: %{"type" => "ChatMessage"}}, + data: %{"type" => "Delete"} + } + + topics = Topics.get_activity_topics(activity) + assert [_, _] = topics + assert "user" in topics + assert "user:pleroma_chat" in topics + end + end + describe "poll answer" do test "produce no topics" do activity = %Activity{object: %Object{data: %{"type" => "Answer"}}} @@ -35,7 +58,7 @@ test "always add user and list topics" do setup do activity = %Activity{ object: %Object{data: %{"type" => "Note"}}, - data: %{"to" => [Pleroma.Constants.as_public()]} + data: %{"to" => [Pleroma.Constants.as_public()], "type" => "Create"} } {:ok, activity: activity} @@ -114,6 +137,55 @@ test "local action doesn't produce public:remote topic", %{activity: activity} d end end + describe "public visibility Announces" do + setup do + activity = %Activity{ + object: %Object{data: %{"attachment" => []}}, + data: %{"type" => "Announce", "to" => [Pleroma.Constants.as_public()]} + } + + {:ok, activity: activity} + end + + test "does not generate public topics", %{activity: activity} do + topics = Topics.get_activity_topics(activity) + + refute "public" in topics + refute "public:remote" in topics + refute "public:local" in topics + end + end + + describe "local-public visibility create events" do + setup do + activity = %Activity{ + object: %Object{data: %{"attachment" => []}}, + data: %{"type" => "Create", "to" => [Pleroma.Web.ActivityPub.Utils.as_local_public()]} + } + + {:ok, activity: activity} + end + + test "doesn't produce public topics", %{activity: activity} do + topics = Topics.get_activity_topics(activity) + + refute Enum.member?(topics, "public") + end + + test "produces public:local topics", %{activity: activity} do + topics = Topics.get_activity_topics(activity) + + assert Enum.member?(topics, "public:local") + end + + test "with no attachments doesn't produce public:media topics", %{activity: activity} do + topics = Topics.get_activity_topics(activity) + + refute Enum.member?(topics, "public:media") + refute Enum.member?(topics, "public:local:media") + end + end + describe "public visibility create events with attachments" do setup do activity = %Activity{ @@ -152,9 +224,36 @@ test "non-local action produces public:remote:media topic", %{activity: activity end end + describe "local-public visibility create events with attachments" do + setup do + activity = %Activity{ + object: %Object{data: %{"attachment" => ["foo"]}}, + data: %{"type" => "Create", "to" => [Pleroma.Web.ActivityPub.Utils.as_local_public()]} + } + + {:ok, activity: activity} + end + + test "do not produce public:media topics", %{activity: activity} do + topics = Topics.get_activity_topics(activity) + + refute Enum.member?(topics, "public:media") + end + + test "produces public:local:media topics", %{activity: activity} do + topics = Topics.get_activity_topics(activity) + + assert Enum.member?(topics, "public:local:media") + end + end + describe "non-public visibility" do test "produces direct topic" do - activity = %Activity{object: %Object{data: %{"type" => "Note"}}, data: %{"to" => []}} + activity = %Activity{ + object: %Object{data: %{"type" => "Note"}}, + data: %{"to" => [], "type" => "Create"} + } + topics = Topics.get_activity_topics(activity) assert Enum.member?(topics, "direct") diff --git a/test/pleroma/activity/search_test.exs b/test/pleroma/activity/search_test.exs index b8096fe73..3b5fd2c3c 100644 --- a/test/pleroma/activity/search_test.exs +++ b/test/pleroma/activity/search_test.exs @@ -18,6 +18,23 @@ test "it finds something" do assert result.id == post.id end + test "it finds local-only posts for authenticated users" do + user = insert(:user) + reader = insert(:user) + {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"}) + + [result] = Search.search(reader, "wednesday") + + assert result.id == post.id + end + + test "it does not find local-only posts for anonymous users" do + user = insert(:user) + {:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"}) + + assert [] = Search.search(nil, "wednesday") + end + test "using plainto_tsquery on postgres < 11" do old_version = :persistent_term.get({Pleroma.Repo, :postgres_version}) :persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0) diff --git a/test/pleroma/activity_test.exs b/test/pleroma/activity_test.exs index b5bb4bafe..a48a68837 100644 --- a/test/pleroma/activity_test.exs +++ b/test/pleroma/activity_test.exs @@ -145,6 +145,7 @@ test "when association is not loaded" do setup do: clear_config([:instance, :limit_to_local_content]) + @tag :skip_on_mac test "finds utf8 text in statuses", %{ japanese_activity: japanese_activity, user: user @@ -278,4 +279,78 @@ test "add_by_params_query/3" do assert Repo.aggregate(Activity, :count, :id) == 2 end + + describe "associated_object_id() sql function" do + test "with json object" do + %{rows: [[object_id]]} = + Ecto.Adapters.SQL.query!( + Pleroma.Repo, + """ + select associated_object_id('{"object": {"id":"foobar"}}'::jsonb); + """ + ) + + assert object_id == "foobar" + end + + test "with string object" do + %{rows: [[object_id]]} = + Ecto.Adapters.SQL.query!( + Pleroma.Repo, + """ + select associated_object_id('{"object": "foobar"}'::jsonb); + """ + ) + + assert object_id == "foobar" + end + + test "with array object" do + %{rows: [[object_id]]} = + Ecto.Adapters.SQL.query!( + Pleroma.Repo, + """ + select associated_object_id('{"object": ["foobar", {}]}'::jsonb); + """ + ) + + assert object_id == "foobar" + end + + test "invalid" do + %{rows: [[object_id]]} = + Ecto.Adapters.SQL.query!( + Pleroma.Repo, + """ + select associated_object_id('{"object": {}}'::jsonb); + """ + ) + + assert is_nil(object_id) + end + + test "invalid object id" do + %{rows: [[object_id]]} = + Ecto.Adapters.SQL.query!( + Pleroma.Repo, + """ + select associated_object_id('{"object": {"id": 123}}'::jsonb); + """ + ) + + assert is_nil(object_id) + end + + test "no object field" do + %{rows: [[object_id]]} = + Ecto.Adapters.SQL.query!( + Pleroma.Repo, + """ + select associated_object_id('{}'::jsonb); + """ + ) + + assert is_nil(object_id) + end + end end diff --git a/test/pleroma/config/loader_test.exs b/test/pleroma/config/loader_test.exs index 095067e61..784817d49 100644 --- a/test/pleroma/config/loader_test.exs +++ b/test/pleroma/config/loader_test.exs @@ -11,7 +11,6 @@ test "read/1" do config = Loader.read("test/fixtures/config/temp.secret.exs") assert config[:pleroma][:first_setting][:key] == "value" assert config[:pleroma][:first_setting][:key2] == [Pleroma.Repo] - assert config[:quack][:level] == :info end test "filter_group/2" do diff --git a/test/pleroma/config/transfer_task_test.exs b/test/pleroma/config/transfer_task_test.exs index 927744add..6295fa888 100644 --- a/test/pleroma/config/transfer_task_test.exs +++ b/test/pleroma/config/transfer_task_test.exs @@ -15,13 +15,11 @@ defmodule Pleroma.Config.TransferTaskTest do test "transfer config values from db to env" do refute Application.get_env(:pleroma, :test_key) refute Application.get_env(:idna, :test_key) - refute Application.get_env(:quack, :test_key) refute Application.get_env(:postgrex, :test_key) initial = Application.get_env(:logger, :level) insert(:config, key: :test_key, value: [live: 2, com: 3]) insert(:config, group: :idna, key: :test_key, value: [live: 15, com: 35]) - insert(:config, group: :quack, key: :test_key, value: [:test_value1, :test_value2]) insert(:config, group: :postgrex, key: :test_key, value: :value) insert(:config, group: :logger, key: :level, value: :debug) @@ -29,36 +27,32 @@ test "transfer config values from db to env" do assert Application.get_env(:pleroma, :test_key) == [live: 2, com: 3] assert Application.get_env(:idna, :test_key) == [live: 15, com: 35] - assert Application.get_env(:quack, :test_key) == [:test_value1, :test_value2] assert Application.get_env(:logger, :level) == :debug assert Application.get_env(:postgrex, :test_key) == :value on_exit(fn -> Application.delete_env(:pleroma, :test_key) Application.delete_env(:idna, :test_key) - Application.delete_env(:quack, :test_key) Application.delete_env(:postgrex, :test_key) Application.put_env(:logger, :level, initial) end) end test "transfer config values for 1 group and some keys" do - level = Application.get_env(:quack, :level) - meta = Application.get_env(:quack, :meta) + level = Application.get_env(:somegroup, :level) + meta = Application.get_env(:somegroup, :meta) - insert(:config, group: :quack, key: :level, value: :info) - insert(:config, group: :quack, key: :meta, value: [:none]) + insert(:config, group: :somegroup, key: :level, value: :info) + insert(:config, group: :somegroup, key: :meta, value: [:none]) TransferTask.start_link([]) - assert Application.get_env(:quack, :level) == :info - assert Application.get_env(:quack, :meta) == [:none] - default = Pleroma.Config.Holder.default_config(:quack, :webhook_url) - assert Application.get_env(:quack, :webhook_url) == default + assert Application.get_env(:somegroup, :level) == :info + assert Application.get_env(:somegroup, :meta) == [:none] on_exit(fn -> - Application.put_env(:quack, :level, level) - Application.put_env(:quack, :meta, meta) + Application.put_env(:somegroup, :level, level) + Application.put_env(:somegroup, :meta, meta) end) end @@ -79,35 +73,70 @@ test "transfer config values with full subkey update" do describe "pleroma restart" do setup do - on_exit(fn -> Restarter.Pleroma.refresh() end) + on_exit(fn -> + Restarter.Pleroma.refresh() + + # Restarter.Pleroma.refresh/0 is an asynchronous call. + # A GenServer will first finish the previous call before starting a new one. + # Here we do a synchronous call. + # That way we are sure that the previous call has finished before we continue. + # See https://stackoverflow.com/questions/51361856/how-to-use-task-await-with-genserver + Restarter.Pleroma.rebooted?() + end) end - @tag :erratic test "don't restart if no reboot time settings were changed" do clear_config(:emoji) insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]]) refute String.contains?( - capture_log(fn -> TransferTask.start_link([]) end), + capture_log(fn -> + TransferTask.start_link([]) + + # TransferTask.start_link/1 is an asynchronous call. + # A GenServer will first finish the previous call before starting a new one. + # Here we do a synchronous call. + # That way we are sure that the previous call has finished before we continue. + Restarter.Pleroma.rebooted?() + end), "pleroma restarted" ) end - @tag :erratic test "on reboot time key" do clear_config(:shout) insert(:config, key: :shout, value: [enabled: false]) - assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted" + + # Note that we don't actually restart Pleroma. + # See module Restarter.Pleroma + assert capture_log(fn -> + TransferTask.start_link([]) + + # TransferTask.start_link/1 is an asynchronous call. + # A GenServer will first finish the previous call before starting a new one. + # Here we do a synchronous call. + # That way we are sure that the previous call has finished before we continue. + Restarter.Pleroma.rebooted?() + end) =~ "pleroma restarted" end - @tag :erratic test "on reboot time subkey" do clear_config(Pleroma.Captcha) insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60]) - assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted" + + # Note that we don't actually restart Pleroma. + # See module Restarter.Pleroma + assert capture_log(fn -> + TransferTask.start_link([]) + + # TransferTask.start_link/1 is an asynchronous call. + # A GenServer will first finish the previous call before starting a new one. + # Here we do a synchronous call. + # That way we are sure that the previous call has finished before we continue. + Restarter.Pleroma.rebooted?() + end) =~ "pleroma restarted" end - @tag :erratic test "don't restart pleroma on reboot time key and subkey if there is false flag" do clear_config(:shout) clear_config(Pleroma.Captcha) @@ -116,7 +145,15 @@ test "don't restart pleroma on reboot time key and subkey if there is false flag insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60]) refute String.contains?( - capture_log(fn -> TransferTask.load_and_update_env([], false) end), + capture_log(fn -> + TransferTask.load_and_update_env([], false) + + # TransferTask.start_link/1 is an asynchronous call. + # A GenServer will first finish the previous call before starting a new one. + # Here we do a synchronous call. + # That way we are sure that the previous call has finished before we continue. + Restarter.Pleroma.rebooted?() + end), "pleroma restarted" ) end diff --git a/test/pleroma/config_db_test.exs b/test/pleroma/config_db_test.exs index ba7c615e2..8eb0ab4cf 100644 --- a/test/pleroma/config_db_test.exs +++ b/test/pleroma/config_db_test.exs @@ -16,13 +16,13 @@ test "get_by_params/1" do test "get_all_as_keyword/0" do saved = insert(:config) - insert(:config, group: ":quack", key: ":level", value: :info) - insert(:config, group: ":quack", key: ":meta", value: [:none]) + insert(:config, group: ":goose", key: ":level", value: :info) + insert(:config, group: ":goose", key: ":meta", value: [:none]) insert(:config, - group: ":quack", + group: ":goose", key: ":webhook_url", - value: "https://hooks.slack.com/services/KEY/some_val" + value: "https://gander.com/" ) config = ConfigDB.get_all_as_keyword() @@ -31,9 +31,9 @@ test "get_all_as_keyword/0" do {saved.key, saved.value} ] - assert config[:quack][:level] == :info - assert config[:quack][:meta] == [:none] - assert config[:quack][:webhook_url] == "https://hooks.slack.com/services/KEY/some_val" + assert config[:goose][:level] == :info + assert config[:goose][:meta] == [:none] + assert config[:goose][:webhook_url] == "https://gander.com/" end describe "update_or_create/1" do @@ -267,10 +267,6 @@ test "ExSyslogger module" do assert ConfigDB.to_elixir_types("ExSyslogger") == ExSyslogger end - test "Quack.Logger module" do - assert ConfigDB.to_elixir_types("Quack.Logger") == Quack.Logger - end - test "Swoosh.Adapters modules" do assert ConfigDB.to_elixir_types("Swoosh.Adapters.SMTP") == Swoosh.Adapters.SMTP assert ConfigDB.to_elixir_types("Swoosh.Adapters.AmazonSES") == Swoosh.Adapters.AmazonSES diff --git a/test/pleroma/conversation/participation_test.exs b/test/pleroma/conversation/participation_test.exs index 6f71cc040..a84437677 100644 --- a/test/pleroma/conversation/participation_test.exs +++ b/test/pleroma/conversation/participation_test.exs @@ -122,11 +122,11 @@ test "recreating an existing participations sets it to unread" do end test "it marks a participation as read" do - participation = insert(:participation, %{read: false}) + participation = insert(:participation, %{updated_at: ~N[2017-07-17 17:09:58], read: false}) {:ok, updated_participation} = Participation.mark_as_read(participation) assert updated_participation.read - assert updated_participation.updated_at == participation.updated_at + assert :gt = NaiveDateTime.compare(updated_participation.updated_at, participation.updated_at) end test "it marks a participation as unread" do diff --git a/test/pleroma/docs/translator/compiler_test.exs b/test/pleroma/docs/translator/compiler_test.exs new file mode 100644 index 000000000..d6c3cdd40 --- /dev/null +++ b/test/pleroma/docs/translator/compiler_test.exs @@ -0,0 +1,90 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Docs.Translator.CompilerTest do + use ExUnit.Case, async: true + + alias Pleroma.Docs.Translator.Compiler + + @descriptions [ + %{ + key: "1", + label: "1", + description: "2", + children: [ + %{ + key: "3", + label: "3", + description: "4" + }, + %{ + key: "5", + label: "5", + description: "6" + } + ] + }, + %{ + key: "7", + label: "7", + description: "8", + children: [ + %{ + key: "9", + description: "9", + children: [ + %{ + key: "10", + description: "10", + children: [ + %{key: "11", description: "11"}, + %{description: "12"} + ] + } + ] + }, + %{ + label: "13" + } + ] + }, + %{ + group: "14", + label: "14" + }, + %{ + group: "15", + key: "15", + label: "15" + }, + %{ + group: {":subgroup", "16"}, + label: "16" + } + ] + + describe "extract_strings/1" do + test "it extracts all labels and descriptions" do + strings = Compiler.extract_strings(@descriptions) + assert length(strings) == 16 + + assert {["1"], "label", "1"} in strings + assert {["1"], "description", "2"} in strings + assert {["1", "3"], "label", "3"} in strings + assert {["1", "3"], "description", "4"} in strings + assert {["1", "5"], "label", "5"} in strings + assert {["1", "5"], "description", "6"} in strings + assert {["7"], "label", "7"} in strings + assert {["7"], "description", "8"} in strings + assert {["7", "9"], "description", "9"} in strings + assert {["7", "9", "10"], "description", "10"} in strings + assert {["7", "9", "10", "11"], "description", "11"} in strings + assert {["7", "9", "10", nil], "description", "12"} in strings + assert {["7", nil], "label", "13"} in strings + assert {["14"], "label", "14"} in strings + assert {["15-15"], "label", "15"} in strings + assert {["16"], "label", "16"} in strings + end + end +end diff --git a/test/pleroma/html_test.exs b/test/pleroma/html_test.exs index 970baf63b..b99689903 100644 --- a/test/pleroma/html_test.exs +++ b/test/pleroma/html_test.exs @@ -17,6 +17,7 @@ defmodule Pleroma.HTMLTest do this is a link with allowed "rel" attribute: this is a link with not allowed "rel" attribute: example.com this is an image:
+ this is an inline emoji:
""" @@ -24,6 +25,10 @@ defmodule Pleroma.HTMLTest do """ + @html_stillimage_sample """ + + """ + @html_span_class_sample """ hi """ @@ -45,6 +50,7 @@ test "works as expected" do this is a link with allowed "rel" attribute: example.com this is a link with not allowed "rel" attribute: example.com this is an image: + this is an inline emoji: alert('hacked') """ @@ -67,6 +73,7 @@ test "normalizes HTML as expected" do this is a link with allowed "rel" attribute: this is a link with not allowed "rel" attribute: example.com this is an image:
+ this is an inline emoji:
alert('hacked') """ @@ -90,6 +97,15 @@ test "does not allow spans with invalid classes" do HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.TwitterText) end + test "does not allow images with invalid classes" do + expected = """ + + """ + + assert expected == + HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText) + end + test "does allow microformats" do expected = """ @foo @@ -121,6 +137,7 @@ test "normalizes HTML as expected" do this is a link with allowed "rel" attribute: this is a link with not allowed "rel" attribute: example.com this is an image:
+ this is an inline emoji:
alert('hacked') """ @@ -143,6 +160,15 @@ test "does not allow spans with invalid classes" do assert expected == HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.Default) end + test "does not allow images with invalid classes" do + expected = """ + + """ + + assert expected == + HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText) + end + test "does allow microformats" do expected = """ @foo diff --git a/test/pleroma/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs index 2d4c7f63b..9be0445c0 100644 --- a/test/pleroma/integration/mastodon_websocket_test.exs +++ b/test/pleroma/integration/mastodon_websocket_test.exs @@ -33,16 +33,18 @@ def start_socket(qs \\ nil, headers \\ []) do test "refuses invalid requests" do capture_log(fn -> - assert {:error, {404, _}} = start_socket() - assert {:error, {404, _}} = start_socket("?stream=ncjdk") + assert {:error, %WebSockex.RequestError{code: 404}} = start_socket() + assert {:error, %WebSockex.RequestError{code: 404}} = start_socket("?stream=ncjdk") Process.sleep(30) end) end test "requires authentication and a valid token for protected streams" do capture_log(fn -> - assert {:error, {401, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa") - assert {:error, {401, _}} = start_socket("?stream=user") + assert {:error, %WebSockex.RequestError{code: 401}} = + start_socket("?stream=user&access_token=aaaaaaaaaaaa") + + assert {:error, %WebSockex.RequestError{code: 401}} = start_socket("?stream=user") Process.sleep(30) end) end @@ -91,7 +93,7 @@ test "receives well formatted events" do {:ok, token} = OAuth.Token.exchange_token(app, auth) - %{user: user, token: token} + %{app: app, user: user, token: token} end test "accepts valid tokens", state do @@ -102,7 +104,7 @@ test "accepts the 'user' stream", %{token: token} = _state do assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}") capture_log(fn -> - assert {:error, {401, _}} = start_socket("?stream=user") + assert {:error, %WebSockex.RequestError{code: 401}} = start_socket("?stream=user") Process.sleep(30) end) end @@ -111,7 +113,9 @@ test "accepts the 'user:notification' stream", %{token: token} = _state do assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}") capture_log(fn -> - assert {:error, {401, _}} = start_socket("?stream=user:notification") + assert {:error, %WebSockex.RequestError{code: 401}} = + start_socket("?stream=user:notification") + Process.sleep(30) end) end @@ -120,11 +124,27 @@ test "accepts valid token on Sec-WebSocket-Protocol header", %{token: token} do assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}]) capture_log(fn -> - assert {:error, {401, _}} = + assert {:error, %WebSockex.RequestError{code: 401}} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}]) Process.sleep(30) end) end + + test "disconnect when token is revoked", %{app: app, user: user, token: token} do + assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}") + assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}") + + {:ok, auth} = OAuth.Authorization.create_authorization(app, user) + + {:ok, token2} = OAuth.Token.exchange_token(app, auth) + assert {:ok, _} = start_socket("?stream=user&access_token=#{token2.token}") + + OAuth.Token.Strategy.Revoke.revoke(token) + + assert_receive {:close, _} + assert_receive {:close, _} + refute_receive {:close, _} + end end end diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index d0f34113b..255097ed0 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -133,6 +133,28 @@ test "does not create a notification for subscribed users if status is a reply" subscriber_notifications = Notification.for_user(subscriber) assert Enum.empty?(subscriber_notifications) end + + test "it sends edited notifications to those who repeated a status" do + user = insert(:user) + repeated_user = insert(:user) + other_user = insert(:user) + + {:ok, activity_one} = + CommonAPI.post(user, %{ + status: "hey @#{other_user.nickname}!" + }) + + {:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user) + + {:ok, _edit_activity} = + CommonAPI.update(user, activity_one, %{ + status: "hey @#{other_user.nickname}! mew mew" + }) + + assert [%{type: "reblog"}] = Notification.for_user(user) + assert [%{type: "update"}] = Notification.for_user(repeated_user) + assert [%{type: "mention"}] = Notification.for_user(other_user) + end end test "create_poll_notifications/1" do @@ -826,6 +848,30 @@ test "it returns following domain-blocking recipient in enabled recipients list" assert [other_user] == enabled_receivers assert [] == disabled_receivers end + + test "it sends edited notifications to those who repeated a status" do + user = insert(:user) + repeated_user = insert(:user) + other_user = insert(:user) + + {:ok, activity_one} = + CommonAPI.post(user, %{ + status: "hey @#{other_user.nickname}!" + }) + + {:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user) + + {:ok, edit_activity} = + CommonAPI.update(user, activity_one, %{ + status: "hey @#{other_user.nickname}! mew mew" + }) + + {enabled_receivers, _disabled_receivers} = + Notification.get_notified_from_activity(edit_activity) + + assert repeated_user in enabled_receivers + assert other_user not in enabled_receivers + end end describe "notification lifecycle" do diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs index 98130f434..c8ad66ddb 100644 --- a/test/pleroma/object/fetcher_test.exs +++ b/test/pleroma/object/fetcher_test.exs @@ -6,6 +6,7 @@ defmodule Pleroma.Object.FetcherTest do use Pleroma.DataCase alias Pleroma.Activity + alias Pleroma.Instances alias Pleroma.Object alias Pleroma.Object.Fetcher @@ -159,6 +160,17 @@ test "it does not fetch a spoofed object uploaded on an instance as an attachmen "https://patch.cx/media/03ca3c8b4ac3ddd08bf0f84be7885f2f88de0f709112131a22d83650819e36c2.json" ) end + + test "it resets instance reachability on successful fetch" do + id = "http://mastodon.example.org/@admin/99541947525187367" + Instances.set_consistently_unreachable(id) + refute Instances.reachable?(id) + + {:ok, _object} = + Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367") + + assert Instances.reachable?(id) + end end describe "implementation quirks" do @@ -269,4 +281,271 @@ test "it can refetch pruned objects" do refute called(Pleroma.Signature.sign(:_, :_)) end end + + describe "refetching" do + setup do + object1 = %{ + "id" => "https://mastodon.social/1", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "type" => "Note", + "content" => "test 1", + "bcc" => [], + "bto" => [], + "cc" => [], + "to" => [], + "summary" => "" + } + + object2 = %{ + "id" => "https://mastodon.social/2", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "type" => "Note", + "content" => "test 2", + "bcc" => [], + "bto" => [], + "cc" => [], + "to" => [], + "summary" => "", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "type" => "Note", + "content" => "orig 2", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "bcc" => [], + "bto" => [], + "cc" => [], + "to" => [], + "summary" => "" + } + ], + "totalItems" => 1 + } + } + + mock(fn + %{ + method: :get, + url: "https://mastodon.social/1" + } -> + %Tesla.Env{ + status: 200, + headers: [{"content-type", "application/activity+json"}], + body: Jason.encode!(object1) + } + + %{ + method: :get, + url: "https://mastodon.social/2" + } -> + %Tesla.Env{ + status: 200, + headers: [{"content-type", "application/activity+json"}], + body: Jason.encode!(object2) + } + + %{ + method: :get, + url: "https://mastodon.social/users/emelie/collections/featured" + } -> + %Tesla.Env{ + status: 200, + headers: [{"content-type", "application/activity+json"}], + body: + Jason.encode!(%{ + "id" => "https://mastodon.social/users/emelie/collections/featured", + "type" => "OrderedCollection", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "orderedItems" => [], + "totalItems" => 0 + }) + } + + env -> + apply(HttpRequestMock, :request, [env]) + end) + + %{object1: object1, object2: object2} + end + + test "it keeps formerRepresentations if remote does not have this attr", %{object1: object1} do + full_object1 = + object1 + |> Map.merge(%{ + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "type" => "Note", + "content" => "orig 2", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "bcc" => [], + "bto" => [], + "cc" => [], + "to" => [], + "summary" => "" + } + ], + "totalItems" => 1 + } + }) + + {:ok, o} = Object.create(full_object1) + + assert {:ok, refetched} = Fetcher.refetch_object(o) + + assert %{"formerRepresentations" => %{"orderedItems" => [%{"content" => "orig 2"}]}} = + refetched.data + end + + test "it uses formerRepresentations from remote if possible", %{object2: object2} do + {:ok, o} = Object.create(object2) + + assert {:ok, refetched} = Fetcher.refetch_object(o) + + assert %{"formerRepresentations" => %{"orderedItems" => [%{"content" => "orig 2"}]}} = + refetched.data + end + + test "it replaces formerRepresentations with the one from remote", %{object2: object2} do + full_object2 = + object2 + |> Map.merge(%{ + "content" => "mew mew #def", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{"type" => "Note", "content" => "mew mew 2"} + ], + "totalItems" => 1 + } + }) + + {:ok, o} = Object.create(full_object2) + + assert {:ok, refetched} = Fetcher.refetch_object(o) + + assert %{ + "content" => "test 2", + "formerRepresentations" => %{"orderedItems" => [%{"content" => "orig 2"}]} + } = refetched.data + end + + test "it adds to formerRepresentations if the remote does not have one and the object has changed", + %{object1: object1} do + full_object1 = + object1 + |> Map.merge(%{ + "content" => "mew mew #def", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{"type" => "Note", "content" => "mew mew 1"} + ], + "totalItems" => 1 + } + }) + + {:ok, o} = Object.create(full_object1) + + assert {:ok, refetched} = Fetcher.refetch_object(o) + + assert %{ + "content" => "test 1", + "formerRepresentations" => %{ + "orderedItems" => [ + %{"content" => "mew mew #def"}, + %{"content" => "mew mew 1"} + ], + "totalItems" => 2 + } + } = refetched.data + end + end + + describe "fetch with history" do + setup do + object2 = %{ + "id" => "https://mastodon.social/2", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "type" => "Note", + "content" => "test 2", + "bcc" => [], + "bto" => [], + "cc" => ["https://mastodon.social/users/emelie/followers"], + "to" => [], + "summary" => "", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "type" => "Note", + "content" => "orig 2", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "bcc" => [], + "bto" => [], + "cc" => ["https://mastodon.social/users/emelie/followers"], + "to" => [], + "summary" => "" + } + ], + "totalItems" => 1 + } + } + + mock(fn + %{ + method: :get, + url: "https://mastodon.social/2" + } -> + %Tesla.Env{ + status: 200, + headers: [{"content-type", "application/activity+json"}], + body: Jason.encode!(object2) + } + + %{ + method: :get, + url: "https://mastodon.social/users/emelie/collections/featured" + } -> + %Tesla.Env{ + status: 200, + headers: [{"content-type", "application/activity+json"}], + body: + Jason.encode!(%{ + "id" => "https://mastodon.social/users/emelie/collections/featured", + "type" => "OrderedCollection", + "actor" => "https://mastodon.social/users/emelie", + "attributedTo" => "https://mastodon.social/users/emelie", + "orderedItems" => [], + "totalItems" => 0 + }) + } + + env -> + apply(HttpRequestMock, :request, [env]) + end) + + %{object2: object2} + end + + test "it gets history", %{object2: object2} do + {:ok, object} = Fetcher.fetch_object_from_id(object2["id"]) + + assert %{ + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [%{}] + } + } = object.data + end + end end diff --git a/test/pleroma/object/updater_test.exs b/test/pleroma/object/updater_test.exs new file mode 100644 index 000000000..7e9b44823 --- /dev/null +++ b/test/pleroma/object/updater_test.exs @@ -0,0 +1,76 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Object.UpdaterTest do + use Pleroma.DataCase + use Oban.Testing, repo: Pleroma.Repo + + import Pleroma.Factory + + alias Pleroma.Object.Updater + + describe "make_update_object_data/3" do + setup do + note = insert(:note) + %{original_data: note.data} + end + + test "it makes an updated field", %{original_data: original_data} do + new_data = Map.put(original_data, "content", "new content") + + date = Pleroma.Web.ActivityPub.Utils.make_date() + update_object_data = Updater.make_update_object_data(original_data, new_data, date) + assert %{"updated" => ^date} = update_object_data + end + + test "it creates formerRepresentations", %{original_data: original_data} do + new_data = Map.put(original_data, "content", "new content") + + date = Pleroma.Web.ActivityPub.Utils.make_date() + update_object_data = Updater.make_update_object_data(original_data, new_data, date) + + history_item = original_data |> Map.drop(["id", "formerRepresentations"]) + + assert %{ + "formerRepresentations" => %{ + "totalItems" => 1, + "orderedItems" => [^history_item] + } + } = update_object_data + end + end + + describe "make_new_object_data_from_update_object/2" do + test "it reuses formerRepresentations if it exists" do + %{data: original_data} = insert(:note) + + new_data = + original_data + |> Map.put("content", "edited") + + date = Pleroma.Web.ActivityPub.Utils.make_date() + update_object_data = Updater.make_update_object_data(original_data, new_data, date) + + history = update_object_data["formerRepresentations"]["orderedItems"] + + update_object_data = + update_object_data + |> put_in( + ["formerRepresentations", "orderedItems"], + history ++ [Map.put(original_data, "summary", "additional summary")] + ) + |> put_in(["formerRepresentations", "totalItems"], length(history) + 1) + + %{ + updated_data: updated_data, + updated: updated, + used_history_in_new_object?: used_history_in_new_object? + } = Updater.make_new_object_data_from_update_object(original_data, update_object_data) + + assert updated + assert used_history_in_new_object? + assert updated_data["formerRepresentations"] == update_object_data["formerRepresentations"] + end + end +end diff --git a/test/pleroma/signature_test.exs b/test/pleroma/signature_test.exs index 92d05f26c..b849cbee7 100644 --- a/test/pleroma/signature_test.exs +++ b/test/pleroma/signature_test.exs @@ -109,6 +109,11 @@ test "it properly deduces the actor id for mastodon and pleroma" do {:ok, "https://example.com/users/1234"} end + test "it deduces the actor id for gotoSocial" do + assert Signature.key_id_to_actor_id("https://example.com/users/1234/main-key") == + {:ok, "https://example.com/users/1234"} + end + test "it calls webfinger for 'acct:' accounts" do with_mock(Pleroma.Web.WebFinger, finger: fn _ -> %{"ap_id" => "https://gensokyo.2hu/users/raymoo"} end diff --git a/test/pleroma/upload_test.exs b/test/pleroma/upload_test.exs index f2795f985..6584c2def 100644 --- a/test/pleroma/upload_test.exs +++ b/test/pleroma/upload_test.exs @@ -49,20 +49,22 @@ def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__) test "it returns file" do File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg") - assert Upload.store(@upload_file) == - {:ok, - %{ - "name" => "image.jpg", - "type" => "Document", - "mediaType" => "image/jpeg", - "url" => [ - %{ - "href" => "http://localhost:4001/media/post-process-file.jpg", - "mediaType" => "image/jpeg", - "type" => "Link" - } - ] - }} + assert {:ok, result} = Upload.store(@upload_file) + + assert result == + %{ + "id" => result["id"], + "name" => "image.jpg", + "type" => "Document", + "mediaType" => "image/jpeg", + "url" => [ + %{ + "href" => "http://localhost:4001/media/post-process-file.jpg", + "mediaType" => "image/jpeg", + "type" => "Link" + } + ] + } Task.await(Agent.get(TestUploaderSuccess, fn task_pid -> task_pid end)) end diff --git a/test/pleroma/user/backup_test.exs b/test/pleroma/user/backup_test.exs index 6441c5ba8..5c9b94000 100644 --- a/test/pleroma/user/backup_test.exs +++ b/test/pleroma/user/backup_test.exs @@ -22,15 +22,15 @@ defmodule Pleroma.User.BackupTest do clear_config([Pleroma.Emails.Mailer, :enabled], true) end - test "it requries enabled email" do + test "it does not requrie enabled email" do clear_config([Pleroma.Emails.Mailer, :enabled], false) user = insert(:user) - assert {:error, "Backups require enabled email"} == Backup.create(user) + assert {:ok, _} = Backup.create(user) end - test "it requries user's email" do + test "it does not require user's email" do user = insert(:user, %{email: nil}) - assert {:error, "Email is required"} == Backup.create(user) + assert {:ok, _} = Backup.create(user) end test "it creates a backup record and an Oban job" do @@ -75,6 +75,43 @@ test "it process a backup record" do ) end + test "it does not send an email if the user does not have an email" do + clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) + %{id: user_id} = user = insert(:user, %{email: nil}) + + assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user) + assert {:ok, backup} = perform_job(BackupWorker, args) + assert backup.file_size > 0 + assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup + + assert_no_email_sent() + end + + test "it does not send an email if mailer is not on" do + clear_config([Pleroma.Emails.Mailer, :enabled], false) + clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) + %{id: user_id} = user = insert(:user) + + assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user) + assert {:ok, backup} = perform_job(BackupWorker, args) + assert backup.file_size > 0 + assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup + + assert_no_email_sent() + end + + test "it does not send an email if the user has an empty email" do + clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) + %{id: user_id} = user = insert(:user, %{email: ""}) + + assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user) + assert {:ok, backup} = perform_job(BackupWorker, args) + assert backup.file_size > 0 + assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup + + assert_no_email_sent() + end + test "it removes outdated backups after creating a fresh one" do clear_config([Backup, :limit_days], -1) clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) diff --git a/test/pleroma/user_relationship_test.exs b/test/pleroma/user_relationship_test.exs index 2811aff4c..7d205a746 100644 --- a/test/pleroma/user_relationship_test.exs +++ b/test/pleroma/user_relationship_test.exs @@ -5,8 +5,9 @@ defmodule Pleroma.UserRelationshipTest do alias Pleroma.UserRelationship - use Pleroma.DataCase, async: true + use Pleroma.DataCase, async: false + import Mock import Pleroma.Factory describe "*_exists?/2" do @@ -79,7 +80,12 @@ test "creates user relationship record if it doesn't exist", %{users: [user1, us end test "if record already exists, returns it", %{users: [user1, user2]} do - user_block = UserRelationship.create_block(user1, user2) + user_block = + with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do + {:ok, %{inserted_at: ~N[2017-03-17 17:09:58]}} = + UserRelationship.create_block(user1, user2) + end + assert user_block == UserRelationship.create_block(user1, user2) end end diff --git a/test/pleroma/user_search_test.exs b/test/pleroma/user_search_test.exs index 9b94f421d..1deab6888 100644 --- a/test/pleroma/user_search_test.exs +++ b/test/pleroma/user_search_test.exs @@ -65,6 +65,14 @@ test "excludes invisible users from results" do assert found_user.id == user.id end + test "excludes deactivated users from results" do + user = insert(:user, %{nickname: "john t1000"}) + insert(:user, %{is_active: false, nickname: "john t800"}) + + [found_user] = User.search("john") + assert found_user.id == user.id + end + # Note: as in Mastodon, `is_discoverable` doesn't anyhow relate to user searchability test "includes non-discoverable users in results" do insert(:user, %{nickname: "john 3000", is_discoverable: false}) diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 4c11a5f43..c16312a65 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -310,7 +310,7 @@ test "local users do not automatically follow local locked accounts" do describe "unfollow/2" do setup do: clear_config([:instance, :external_user_synchronization]) - test "unfollow with syncronizes external user" do + test "unfollow with synchronizes external user" do clear_config([:instance, :external_user_synchronization], true) followed = @@ -585,6 +585,21 @@ test "it fails gracefully with invalid email config" do refute_email_sent() end + test "it works when the registering user does not provide an email" do + clear_config([Pleroma.Emails.Mailer, :enabled], false) + clear_config([:instance, :account_activation_required], false) + clear_config([:instance, :account_approval_required], true) + + cng = User.register_changeset(%User{}, @full_user_data |> Map.put(:email, "")) + + # The user is still created + assert {:ok, %User{nickname: "nick"}} = User.register(cng) + + # No emails are sent + ObanHelpers.perform_all() + refute_email_sent() + end + test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do clear_config([:instance, :account_activation_required], true) @@ -671,14 +686,14 @@ test "it blocks blacklisted email domains" do assert changeset.valid? end - test "it sets the password_hash and ap_id" do + test "it sets the password_hash, ap_id, private key and followers collection address" do changeset = User.register_changeset(%User{}, @full_user_data) assert changeset.valid? assert is_binary(changeset.changes[:password_hash]) + assert is_binary(changeset.changes[:keys]) assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname}) - assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers" end @@ -844,6 +859,123 @@ test "gets an existing user by ap_id" do freshed_user = refresh_record(user) assert freshed_user == fetched_user end + + test "gets an existing user by nickname starting with http" do + user = insert(:user, nickname: "httpssome") + {:ok, fetched_user} = User.get_or_fetch("httpssome") + + assert user == fetched_user + end + end + + describe "get_or_fetch/1 remote users with tld, while BE is runned on subdomain" do + setup do: clear_config([Pleroma.Web.WebFinger, :update_nickname_on_user_fetch], true) + + test "for mastodon" do + Tesla.Mock.mock(fn + %{url: "https://example.com/.well-known/host-meta"} -> + %Tesla.Env{ + status: 302, + headers: [{"location", "https://sub.example.com/.well-known/host-meta"}] + } + + %{url: "https://sub.example.com/.well-known/host-meta"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/webfinger/masto-host-meta.xml" + |> File.read!() + |> String.replace("{{domain}}", "sub.example.com") + } + + %{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/webfinger/masto-webfinger.json" + |> File.read!() + |> String.replace("{{nickname}}", "a") + |> String.replace("{{domain}}", "example.com") + |> String.replace("{{subdomain}}", "sub.example.com"), + headers: [{"content-type", "application/jrd+json"}] + } + + %{url: "https://sub.example.com/users/a"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/webfinger/masto-user.json" + |> File.read!() + |> String.replace("{{nickname}}", "a") + |> String.replace("{{domain}}", "sub.example.com"), + headers: [{"content-type", "application/activity+json"}] + } + + %{url: "https://sub.example.com/users/a/collections/featured"} -> + %Tesla.Env{ + status: 200, + body: + File.read!("test/fixtures/users_mock/masto_featured.json") + |> String.replace("{{domain}}", "sub.example.com") + |> String.replace("{{nickname}}", "a"), + headers: [{"content-type", "application/activity+json"}] + } + end) + + ap_id = "a@example.com" + {:ok, fetched_user} = User.get_or_fetch(ap_id) + + assert fetched_user.ap_id == "https://sub.example.com/users/a" + assert fetched_user.nickname == "a@example.com" + end + + test "for pleroma" do + Tesla.Mock.mock(fn + %{url: "https://example.com/.well-known/host-meta"} -> + %Tesla.Env{ + status: 302, + headers: [{"location", "https://sub.example.com/.well-known/host-meta"}] + } + + %{url: "https://sub.example.com/.well-known/host-meta"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/webfinger/pleroma-host-meta.xml" + |> File.read!() + |> String.replace("{{domain}}", "sub.example.com") + } + + %{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/webfinger/pleroma-webfinger.json" + |> File.read!() + |> String.replace("{{nickname}}", "a") + |> String.replace("{{domain}}", "example.com") + |> String.replace("{{subdomain}}", "sub.example.com"), + headers: [{"content-type", "application/jrd+json"}] + } + + %{url: "https://sub.example.com/users/a"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/webfinger/pleroma-user.json" + |> File.read!() + |> String.replace("{{nickname}}", "a") + |> String.replace("{{domain}}", "sub.example.com"), + headers: [{"content-type", "application/activity+json"}] + } + end) + + ap_id = "a@example.com" + {:ok, fetched_user} = User.get_or_fetch(ap_id) + + assert fetched_user.ap_id == "https://sub.example.com/users/a" + assert fetched_user.nickname == "a@example.com" + end end describe "fetching a user from nickname or trying to build one" do @@ -1140,7 +1272,7 @@ test "expiring" do user = insert(:user) muted_user = insert(:user) - {:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60}) + {:ok, _user_relationships} = User.mute(user, muted_user, %{duration: 60}) assert User.mutes?(user, muted_user) worker = Pleroma.Workers.MuteExpireWorker @@ -2240,21 +2372,6 @@ test "Only includes users with no read notifications" do end end - describe "ensure_keys_present" do - test "it creates keys for a user and stores them in info" do - user = insert(:user) - refute is_binary(user.keys) - {:ok, user} = User.ensure_keys_present(user) - assert is_binary(user.keys) - end - - test "it doesn't create keys if there already are some" do - user = insert(:user, keys: "xxx") - {:ok, user} = User.ensure_keys_present(user) - assert user.keys == "xxx" - end - end - describe "get_ap_ids_by_nicknames" do test "it returns a list of AP ids for a given set of nicknames" do user = insert(:user) @@ -2369,7 +2486,7 @@ test "updates the counters normally on following/getting a follow when disabled" assert other_user.follower_count == 1 end - test "syncronizes the counters with the remote instance for the followed when enabled" do + test "synchronizes the counters with the remote instance for the followed when enabled" do clear_config([:instance, :external_user_synchronization], false) user = insert(:user) @@ -2391,7 +2508,7 @@ test "syncronizes the counters with the remote instance for the followed when en assert other_user.follower_count == 437 end - test "syncronizes the counters with the remote instance for the follower when enabled" do + test "synchronizes the counters with the remote instance for the follower when enabled" do clear_config([:instance, :external_user_synchronization], false) user = insert(:user) @@ -2691,6 +2808,82 @@ defp object_id_from_created_activity(user) do object_id end + describe "add_alias/2" do + test "should add alias for another user" do + user = insert(:user) + user2 = insert(:user) + + assert {:ok, user_updated} = user |> User.add_alias(user2) + + assert user_updated.also_known_as |> length() == 1 + assert user2.ap_id in user_updated.also_known_as + end + + test "should add multiple aliases" do + user = insert(:user) + user2 = insert(:user) + user3 = insert(:user) + + assert {:ok, user} = user |> User.add_alias(user2) + assert {:ok, user_updated} = user |> User.add_alias(user3) + + assert user_updated.also_known_as |> length() == 2 + assert user2.ap_id in user_updated.also_known_as + assert user3.ap_id in user_updated.also_known_as + end + + test "should not add duplicate aliases" do + user = insert(:user) + user2 = insert(:user) + + assert {:ok, user} = user |> User.add_alias(user2) + + assert {:ok, user_updated} = user |> User.add_alias(user2) + + assert user_updated.also_known_as |> length() == 1 + assert user2.ap_id in user_updated.also_known_as + end + end + + describe "alias_users/1" do + test "should get aliases for a user" do + user = insert(:user) + user2 = insert(:user, also_known_as: [user.ap_id]) + + aliases = user2 |> User.alias_users() + + assert aliases |> length() == 1 + + alias_user = aliases |> Enum.at(0) + + assert alias_user.ap_id == user.ap_id + end + end + + describe "delete_alias/2" do + test "should delete existing alias" do + user = insert(:user) + user2 = insert(:user, also_known_as: [user.ap_id]) + + assert {:ok, user_updated} = user2 |> User.delete_alias(user) + + assert user_updated.also_known_as == [] + end + + test "should report error on non-existing alias" do + user = insert(:user) + user2 = insert(:user) + user3 = insert(:user, also_known_as: [user.ap_id]) + + assert {:error, :no_such_alias} = user3 |> User.delete_alias(user2) + + user3_updated = User.get_cached_by_ap_id(user3.ap_id) + + assert user3_updated.also_known_as |> length() == 1 + assert user.ap_id in user3_updated.also_known_as + end + end + describe "account endorsements" do test "it pins people" do user = insert(:user) diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 1c5c40e84..ef91066c1 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -247,6 +247,27 @@ test "returns local-only objects when authenticated", %{conn: conn} do assert json_response(response, 200) == ObjectView.render("object.json", %{object: object}) end + test "does not return local-only objects for remote users", %{conn: conn} do + user = insert(:user) + reader = insert(:user, local: false) + + {:ok, post} = + CommonAPI.post(user, %{status: "test @#{reader.nickname}", visibility: "local"}) + + assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post) + + object = Object.normalize(post, fetch: false) + uuid = String.split(object.data["id"], "/") |> List.last() + + assert response = + conn + |> assign(:user, reader) + |> put_req_header("accept", "application/activity+json") + |> get("/objects/#{uuid}") + + json_response(response, 404) + end + test "it returns a json representation of the object with accept application/json", %{ conn: conn } do @@ -1297,6 +1318,35 @@ test "it returns 200 even if there're no activities", %{conn: conn} do assert outbox_endpoint == result["id"] end + test "it returns a local note activity when authenticated as local user", %{conn: conn} do + user = insert(:user) + reader = insert(:user) + {:ok, note_activity} = CommonAPI.post(user, %{status: "mew mew", visibility: "local"}) + ap_id = note_activity.data["id"] + + resp = + conn + |> assign(:user, reader) + |> put_req_header("accept", "application/activity+json") + |> get("/users/#{user.nickname}/outbox?page=true") + |> json_response(200) + + assert %{"orderedItems" => [%{"id" => ^ap_id}]} = resp + end + + test "it does not return a local note activity when unauthenticated", %{conn: conn} do + user = insert(:user) + {:ok, _note_activity} = CommonAPI.post(user, %{status: "mew mew", visibility: "local"}) + + resp = + conn + |> put_req_header("accept", "application/activity+json") + |> get("/users/#{user.nickname}/outbox?page=true") + |> json_response(200) + + assert %{"orderedItems" => []} = resp + end + test "it returns a note activity in a collection", %{conn: conn} do note_activity = insert(:note_activity) note_object = Object.normalize(note_activity, fetch: false) diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 8aa586f40..fc6fc039d 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -554,7 +554,6 @@ test "inserts a given map into the activity database, giving it an id if it has assert activity.data["ok"] == data["ok"] assert activity.data["id"] == given_id assert activity.data["context"] == "blabla" - assert activity.data["context_id"] end test "adds a context when none is there" do @@ -576,8 +575,6 @@ test "adds a context when none is there" do assert is_binary(activity.data["context"]) assert is_binary(object.data["context"]) - assert activity.data["context_id"] - assert object.data["context_id"] end test "adds an id to a given object if it lacks one and is a note and inserts it to the object database" do @@ -1507,6 +1504,7 @@ test "it filters broken threads" do reporter_ap_id = reporter.ap_id target_ap_id = target_account.ap_id activity_ap_id = activity.data["id"] + object_ap_id = activity.object.data["id"] activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id) @@ -1518,6 +1516,7 @@ test "it filters broken threads" do reported_activity: activity, content: content, activity_ap_id: activity_ap_id, + object_ap_id: object_ap_id, activity_with_object: activity_with_object, reporter_ap_id: reporter_ap_id, target_ap_id: target_ap_id @@ -1531,7 +1530,7 @@ test "it can create a Flag activity", target_account: target_account, reported_activity: reported_activity, content: content, - activity_ap_id: activity_ap_id, + object_ap_id: object_ap_id, activity_with_object: activity_with_object, reporter_ap_id: reporter_ap_id, target_ap_id: target_ap_id @@ -1547,7 +1546,7 @@ test "it can create a Flag activity", note_obj = %{ "type" => "Note", - "id" => activity_ap_id, + "id" => object_ap_id, "content" => content, "published" => activity_with_object.object.data["published"], "actor" => @@ -1571,6 +1570,7 @@ test "it can create a Flag activity", context: context, target_account: target_account, reported_activity: reported_activity, + object_ap_id: object_ap_id, content: content }, Utils, @@ -1585,8 +1585,7 @@ test "it can create a Flag activity", content: content }) - new_data = - put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]]) + new_data = put_in(activity.data, ["object"], [target_account.ap_id, object_ap_id]) assert_called(Utils.maybe_federate(%{activity | data: new_data})) end @@ -1612,7 +1611,7 @@ test "it can create a Flag activity", }) assert Repo.aggregate(Activity, :count, :id) == 1 - assert Repo.aggregate(Object, :count, :id) == 2 + assert Repo.aggregate(Object, :count, :id) == 1 assert Repo.aggregate(Notification, :count, :id) == 0 end end @@ -1665,7 +1664,7 @@ test "fetches only public posts for other users" do end describe "fetch_follow_information_for_user" do - test "syncronizes following/followers counters" do + test "synchronizes following/followers counters" do user = insert(:user, local: false, @@ -1836,9 +1835,12 @@ test "create" do "target" => ^new_ap_id, "type" => "Move" }, - local: true + local: true, + recipients: recipients } = activity + assert old_user.follower_address in recipients + params = %{ "op" => "move_following", "origin_id" => old_user.id, @@ -1869,6 +1871,42 @@ test "old user must be in the new user's `also_known_as` list" do assert {:error, "Target account must have the origin in `alsoKnownAs`"} = ActivityPub.move(old_user, new_user) end + + test "do not move remote user following relationships" do + %{ap_id: old_ap_id} = old_user = insert(:user) + %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id]) + follower_remote = insert(:user, local: false) + + User.follow(follower_remote, old_user) + + assert User.following?(follower_remote, old_user) + + assert {:ok, activity} = ActivityPub.move(old_user, new_user) + + assert %Activity{ + actor: ^old_ap_id, + data: %{ + "actor" => ^old_ap_id, + "object" => ^old_ap_id, + "target" => ^new_ap_id, + "type" => "Move" + }, + local: true + } = activity + + params = %{ + "op" => "move_following", + "origin_id" => old_user.id, + "target_id" => new_user.id + } + + assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params) + + Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params}) + + assert User.following?(follower_remote, old_user) + refute User.following?(follower_remote, new_user) + end end test "doesn't retrieve replies activities with exclude_replies" do diff --git a/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs b/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs index 8c7d4de5c..303d7ca1e 100644 --- a/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do import Pleroma.Factory import ExUnit.CaptureLog + alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy @linkless_message %{ @@ -49,11 +50,23 @@ test "it disallows posts with links" do assert user.note_count == 0 - message = - @linkful_message - |> Map.put("actor", user.ap_id) + message = %{ + "type" => "Create", + "actor" => user.ap_id, + "object" => %{ + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "content" => "hi world!" + } + ] + }, + "content" => "mew" + } + } - {:reject, _} = AntiLinkSpamPolicy.filter(message) + {:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, message) end test "it allows posts with links for local users" do @@ -67,6 +80,18 @@ test "it allows posts with links for local users" do {:ok, _message} = AntiLinkSpamPolicy.filter(message) end + + test "it disallows posts with links in history" do + user = insert(:user, local: false) + + assert user.note_count == 0 + + message = + @linkful_message + |> Map.put("actor", user.ap_id) + + {:reject, _} = AntiLinkSpamPolicy.filter(message) + end end describe "with old user" do diff --git a/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs index bc2f09e29..859e6f1e9 100644 --- a/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs +++ b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do alias Pleroma.Activity alias Pleroma.Object + alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended describe "rewrites summary" do @@ -35,10 +36,58 @@ test "it adds `re:` to summary object when child summary containts re-subject of assert {:ok, res} = EnsureRePrepended.filter(message) assert res["object"]["summary"] == "re: object-summary" end + + test "it adds `re:` to history" do + message = %{ + "type" => "Create", + "object" => %{ + "summary" => "object-summary", + "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}, + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "summary" => "object-summary", + "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}} + } + ] + } + } + } + + assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message) + assert res["object"]["summary"] == "re: object-summary" + + assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] == + "re: object-summary" + end + + test "it accepts Updates" do + message = %{ + "type" => "Update", + "object" => %{ + "summary" => "object-summary", + "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}, + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "summary" => "object-summary", + "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}} + } + ] + } + } + } + + assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message) + assert res["object"]["summary"] == "re: object-summary" + + assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] == + "re: object-summary" + end end describe "skip filter" do - test "it skip if type isn't 'Create'" do + test "it skip if type isn't 'Create' or 'Update'" do message = %{ "type" => "Annotation", "object" => %{"summary" => "object-summary"} diff --git a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs index 125b14a59..b349a4bb7 100644 --- a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs +++ b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs @@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do alias Pleroma.Constants alias Pleroma.Object + alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent alias Pleroma.Web.CommonAPI @@ -161,4 +162,98 @@ test "with markdown formatting" do assert filtered == "

@luigi I'ma tired...

" end + + test "aware of history" do + mario = insert(:user, nickname: "mario") + wario = insert(:user, nickname: "wario") + + {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"}) + + activity = %{ + "type" => "Create", + "actor" => wario.ap_id, + "object" => %{ + "type" => "Note", + "actor" => wario.ap_id, + "content" => "WHA-HA!", + "to" => [ + mario.ap_id, + Constants.as_public() + ], + "inReplyTo" => post1.object.data["id"], + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "type" => "Note", + "actor" => wario.ap_id, + "content" => "WHA-HA!", + "to" => [ + mario.ap_id, + Constants.as_public() + ], + "inReplyTo" => post1.object.data["id"] + } + ] + } + } + } + + expected = + "@mario WHA-HA!" + + assert {:ok, + %{ + "object" => %{ + "content" => ^expected, + "formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]} + } + }} = MRF.filter_one(ForceMentionsInContent, activity) + end + + test "works with Updates" do + mario = insert(:user, nickname: "mario") + wario = insert(:user, nickname: "wario") + + {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"}) + + activity = %{ + "type" => "Update", + "actor" => wario.ap_id, + "object" => %{ + "type" => "Note", + "actor" => wario.ap_id, + "content" => "WHA-HA!", + "to" => [ + mario.ap_id, + Constants.as_public() + ], + "inReplyTo" => post1.object.data["id"], + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "type" => "Note", + "actor" => wario.ap_id, + "content" => "WHA-HA!", + "to" => [ + mario.ap_id, + Constants.as_public() + ], + "inReplyTo" => post1.object.data["id"] + } + ] + } + } + } + + expected = + "@mario WHA-HA!" + + assert {:ok, + %{ + "object" => %{ + "content" => ^expected, + "formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]} + } + }} = MRF.filter_one(ForceMentionsInContent, activity) + end end diff --git a/test/pleroma/web/activity_pub/mrf/hashtag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/hashtag_policy_test.exs index 7f2d78a4c..32991c966 100644 --- a/test/pleroma/web/activity_pub/mrf/hashtag_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/hashtag_policy_test.exs @@ -20,6 +20,76 @@ test "it sets the sensitive property with relevant hashtags" do assert modified["object"]["sensitive"] end + test "it is history-aware" do + activity = %{ + "type" => "Create", + "object" => %{ + "content" => "hey", + "tag" => [] + } + } + + activity_data = + activity + |> put_in( + ["object", "formerRepresentations"], + %{ + "type" => "OrderedCollection", + "orderedItems" => [ + Map.put( + activity["object"], + "tag", + [%{"type" => "Hashtag", "name" => "#nsfw"}] + ) + ] + } + ) + + {:ok, modified} = + Pleroma.Web.ActivityPub.MRF.filter_one( + Pleroma.Web.ActivityPub.MRF.HashtagPolicy, + activity_data + ) + + refute modified["object"]["sensitive"] + assert Enum.at(modified["object"]["formerRepresentations"]["orderedItems"], 0)["sensitive"] + end + + test "it works with Update" do + activity = %{ + "type" => "Update", + "object" => %{ + "content" => "hey", + "tag" => [] + } + } + + activity_data = + activity + |> put_in( + ["object", "formerRepresentations"], + %{ + "type" => "OrderedCollection", + "orderedItems" => [ + Map.put( + activity["object"], + "tag", + [%{"type" => "Hashtag", "name" => "#nsfw"}] + ) + ] + } + ) + + {:ok, modified} = + Pleroma.Web.ActivityPub.MRF.filter_one( + Pleroma.Web.ActivityPub.MRF.HashtagPolicy, + activity_data + ) + + refute modified["object"]["sensitive"] + assert Enum.at(modified["object"]["formerRepresentations"]["orderedItems"], 0)["sensitive"] + end + test "it doesn't sets the sensitive property with irrelevant hashtags" do user = insert(:user) diff --git a/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs b/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs index bfa8e8f59..a0e77d7b9 100644 --- a/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs @@ -79,6 +79,54 @@ test "rejects if regex matches in summary" do KeywordPolicy.filter(message) end) end + + test "rejects if string matches in history" do + clear_config([:mrf_keyword, :reject], ["pun"]) + + message = %{ + "type" => "Create", + "object" => %{ + "content" => "just a daily reminder that compLAINer is a good", + "summary" => "", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "content" => "just a daily reminder that compLAINer is a good pun", + "summary" => "" + } + ] + } + } + } + + assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} = + KeywordPolicy.filter(message) + end + + test "rejects Updates" do + clear_config([:mrf_keyword, :reject], ["pun"]) + + message = %{ + "type" => "Update", + "object" => %{ + "content" => "just a daily reminder that compLAINer is a good", + "summary" => "", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "content" => "just a daily reminder that compLAINer is a good pun", + "summary" => "" + } + ] + } + } + } + + assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} = + KeywordPolicy.filter(message) + end end describe "delisting from ftl based on keywords" do @@ -157,6 +205,31 @@ test "delists if regex matches in summary" do not (["https://www.w3.org/ns/activitystreams#Public"] == result["to"]) end) end + + test "delists if string matches in history" do + clear_config([:mrf_keyword, :federated_timeline_removal], ["pun"]) + + message = %{ + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "type" => "Create", + "object" => %{ + "content" => "just a daily reminder that compLAINer is a good", + "summary" => "", + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "content" => "just a daily reminder that compLAINer is a good pun", + "summary" => "" + } + ] + } + } + } + + {:ok, result} = KeywordPolicy.filter(message) + assert ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"] + refute ["https://www.w3.org/ns/activitystreams#Public"] == result["to"] + end end describe "replacing keywords" do @@ -221,5 +294,63 @@ test "replaces keyword if regex matches in summary" do result == "ZFS is free software" end) end + + test "replaces keyword if string matches in history" do + clear_config([:mrf_keyword, :replace], [{"opensource", "free software"}]) + + message = %{ + "type" => "Create", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "object" => %{ + "content" => "ZFS is opensource", + "summary" => "", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{"content" => "ZFS is opensource mew mew", "summary" => ""} + ] + } + } + } + + {:ok, + %{ + "object" => %{ + "content" => "ZFS is free software", + "formerRepresentations" => %{ + "orderedItems" => [%{"content" => "ZFS is free software mew mew"}] + } + } + }} = KeywordPolicy.filter(message) + end + + test "replaces keyword in Updates" do + clear_config([:mrf_keyword, :replace], [{"opensource", "free software"}]) + + message = %{ + "type" => "Update", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "object" => %{ + "content" => "ZFS is opensource", + "summary" => "", + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{"content" => "ZFS is opensource mew mew", "summary" => ""} + ] + } + } + } + + {:ok, + %{ + "object" => %{ + "content" => "ZFS is free software", + "formerRepresentations" => %{ + "orderedItems" => [%{"content" => "ZFS is free software mew mew"}] + } + } + }} = KeywordPolicy.filter(message) + end end end diff --git a/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs b/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs index 09301c6ca..6557c3a98 100644 --- a/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do use Pleroma.Tests.Helpers alias Pleroma.HTTP + alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy import Mock @@ -22,6 +23,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do } } + @message_with_history %{ + "type" => "Create", + "object" => %{ + "type" => "Note", + "content" => "content", + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "type" => "Note", + "content" => "content", + "attachment" => [ + %{"url" => [%{"href" => "http://example.com/image.jpg"}]} + ] + } + ] + } + } + } + setup do: clear_config([:media_proxy, :enabled], true) test "it prefetches media proxy URIs" do @@ -50,4 +70,28 @@ test "it does nothing when no attachments are present" do refute called(HTTP.get(:_, :_, :_)) end end + + test "history-aware" do + Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} -> + {:ok, %Tesla.Env{status: 200, body: ""}} + end) + + with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do + MRF.filter_one(MediaProxyWarmingPolicy, @message_with_history) + + assert called(HTTP.get(:_, :_, :_)) + end + end + + test "works with Updates" do + Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} -> + {:ok, %Tesla.Env{status: 200, body: ""}} + end) + + with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do + MRF.filter_one(MediaProxyWarmingPolicy, @message_with_history |> Map.put("type", "Update")) + + assert called(HTTP.get(:_, :_, :_)) + end + end end diff --git a/test/pleroma/web/activity_pub/mrf/no_empty_policy_test.exs b/test/pleroma/web/activity_pub/mrf/no_empty_policy_test.exs index fe4bb8f0a..386ed395f 100644 --- a/test/pleroma/web/activity_pub/mrf/no_empty_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/no_empty_policy_test.exs @@ -151,4 +151,27 @@ test "Notes with no content are denied" do assert NoEmptyPolicy.filter(message) == {:reject, "[NoEmptyPolicy]"} end + + test "works with Update" do + message = %{ + "actor" => "http://localhost:4001/users/testuser", + "cc" => ["http://localhost:4001/users/testuser/followers"], + "object" => %{ + "actor" => "http://localhost:4001/users/testuser", + "attachment" => [], + "cc" => ["http://localhost:4001/users/testuser/followers"], + "source" => "", + "to" => [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "type" => "Note" + }, + "to" => [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "type" => "Update" + } + + assert NoEmptyPolicy.filter(message) == {:reject, "[NoEmptyPolicy]"} + end end diff --git a/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs index acc7c3566..3533c2bc8 100644 --- a/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do use Pleroma.DataCase, async: true + alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy test "it clears content object" do @@ -20,6 +21,46 @@ test "it clears content object" do assert res["object"]["content"] == "" end + test "history-aware" do + message = %{ + "type" => "Create", + "object" => %{ + "content" => ".", + "attachment" => "image", + "formerRepresentations" => %{ + "orderedItems" => [%{"content" => ".", "attachment" => "image"}] + } + } + } + + assert {:ok, res} = MRF.filter_one(NoPlaceholderTextPolicy, message) + + assert %{ + "content" => "", + "formerRepresentations" => %{"orderedItems" => [%{"content" => ""}]} + } = res["object"] + end + + test "works with Updates" do + message = %{ + "type" => "Update", + "object" => %{ + "content" => ".", + "attachment" => "image", + "formerRepresentations" => %{ + "orderedItems" => [%{"content" => ".", "attachment" => "image"}] + } + } + } + + assert {:ok, res} = MRF.filter_one(NoPlaceholderTextPolicy, message) + + assert %{ + "content" => "", + "formerRepresentations" => %{"orderedItems" => [%{"content" => ""}]} + } = res["object"] + end + @messages [ %{ "type" => "Create", diff --git a/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs index 20176b63b..66a8f4e44 100644 --- a/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs +++ b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do use Pleroma.DataCase, async: true + alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF.NormalizeMarkup @html_sample """ @@ -16,24 +17,58 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do """ - test "it filter html tags" do - expected = """ - this is in bold -

this is a paragraph

- this is a linebreak
- this is a link with allowed "rel" attribute: - this is a link with not allowed "rel" attribute: example.com - this is an image:
- alert('hacked') - """ + @expected """ + this is in bold +

this is a paragraph

+ this is a linebreak
+ this is a link with allowed "rel" attribute: + this is a link with not allowed "rel" attribute: example.com + this is an image:
+ alert('hacked') + """ + test "it filter html tags" do message = %{"type" => "Create", "object" => %{"content" => @html_sample}} assert {:ok, res} = NormalizeMarkup.filter(message) - assert res["object"]["content"] == expected + assert res["object"]["content"] == @expected end - test "it skips filter if type isn't `Create`" do + test "history-aware" do + message = %{ + "type" => "Create", + "object" => %{ + "content" => @html_sample, + "formerRepresentations" => %{"orderedItems" => [%{"content" => @html_sample}]} + } + } + + assert {:ok, res} = MRF.filter_one(NormalizeMarkup, message) + + assert %{ + "content" => @expected, + "formerRepresentations" => %{"orderedItems" => [%{"content" => @expected}]} + } = res["object"] + end + + test "works with Updates" do + message = %{ + "type" => "Update", + "object" => %{ + "content" => @html_sample, + "formerRepresentations" => %{"orderedItems" => [%{"content" => @html_sample}]} + } + } + + assert {:ok, res} = MRF.filter_one(NormalizeMarkup, message) + + assert %{ + "content" => @expected, + "formerRepresentations" => %{"orderedItems" => [%{"content" => @expected}]} + } = res["object"] + end + + test "it skips filter if type isn't `Create` or `Update`" do message = %{"type" => "Note", "object" => %{}} assert {:ok, res} = NormalizeMarkup.filter(message) 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 f93537ed8..c7a62be18 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 @@ -5,6 +5,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest do use Pleroma.DataCase, async: true + alias Pleroma.Web.ActivityPub.ObjectValidator alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator alias Pleroma.Web.ActivityPub.Utils @@ -31,6 +32,54 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest test "a basic note validates", %{note: note} do %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note) end + + test "a note from factory validates" do + note = insert(:note) + %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note.data) + end + end + + describe "Note with history" do + setup do + user = insert(:user) + {:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"}) + {:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"}) + + {:ok, %{"object" => external_rep}} = + Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data) + + %{external_rep: external_rep} + end + + test "edited note", %{external_rep: external_rep} do + assert %{"formerRepresentations" => %{"orderedItems" => [%{"tag" => [_]}]}} = external_rep + + {:ok, validate_res, []} = ObjectValidator.validate(external_rep, []) + + assert %{"formerRepresentations" => %{"orderedItems" => [%{"emoji" => %{"dinosaur" => _}}]}} = + validate_res + end + + test "edited note, badly-formed formerRepresentations", %{external_rep: external_rep} do + external_rep = Map.put(external_rep, "formerRepresentations", %{}) + + assert {:error, _} = ObjectValidator.validate(external_rep, []) + end + + test "edited note, badly-formed history item", %{external_rep: external_rep} do + history_item = + Enum.at(external_rep["formerRepresentations"]["orderedItems"], 0) + |> Map.put("type", "Foo") + + external_rep = + put_in( + external_rep, + ["formerRepresentations", "orderedItems"], + [history_item] + ) + + assert {:error, _} = ObjectValidator.validate(external_rep, []) + end end test "a Note from Roadhouse validates" do @@ -43,4 +92,28 @@ test "a Note from Roadhouse validates" do %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note) end + + test "a note with an attachment should work", _ do + insert(:user, %{ap_id: "https://owncast.localhost.localdomain/federation/user/streamer"}) + + note = + "test/fixtures/owncast-note-with-attachment.json" + |> File.read!() + |> Jason.decode!() + + %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note) + end + + test "a Note without replies/first/items validates" do + insert(:user, ap_id: "https://mastodon.social/users/emelie") + + note = + "test/fixtures/tesla_mock/status.emelie.json" + |> File.read!() + |> Jason.decode!() + |> pop_in(["replies", "first", "items"]) + |> elem(1) + + %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note) + end end diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs index 9a17e277e..77f2044e9 100644 --- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs @@ -11,6 +11,19 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do import Pleroma.Factory describe "attachments" do + test "fails without url" do + attachment = %{ + "mediaType" => "", + "name" => "", + "summary" => "298p3RG7j27tfsZ9RQ.jpg", + "type" => "Document" + } + + assert {:error, _cng} = + AttachmentValidator.cast_and_validate(attachment) + |> Ecto.Changeset.apply_action(:insert) + end + test "works with honkerific attachments" do attachment = %{ "mediaType" => "", diff --git a/test/pleroma/web/activity_pub/object_validators/create_generic_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/create_generic_validator_test.exs index 0a5b44beb..e771260c9 100644 --- a/test/pleroma/web/activity_pub/object_validators/create_generic_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/create_generic_validator_test.exs @@ -23,10 +23,10 @@ test "a Create/Note from Roadhouse validates" do {:ok, object_data} = ObjectValidator.cast_and_apply(note_activity["object"]) meta = [object_data: ObjectValidator.stringify_keys(object_data)] - %{valid?: true} = CreateGenericValidator.cast_and_validate(note_activity, meta) + assert %{valid?: true} = CreateGenericValidator.cast_and_validate(note_activity, meta) end - test "a Create/Note with mismatched context is invalid" do + test "a Create/Note with mismatched context uses the Note's context" do user = insert(:user) note = %{ @@ -54,6 +54,9 @@ test "a Create/Note with mismatched context is invalid" do {:ok, object_data} = ObjectValidator.cast_and_apply(note_activity["object"]) meta = [object_data: ObjectValidator.stringify_keys(object_data)] - %{valid?: false} = CreateGenericValidator.cast_and_validate(note_activity, meta) + validated = CreateGenericValidator.cast_and_validate(note_activity, meta) + + assert validated.valid? + assert {:context, note["context"]} in validated.changes end end diff --git a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs index 94bc5a89b..a09dbf5c6 100644 --- a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs @@ -32,7 +32,7 @@ test "validates a basic object", %{valid_update: valid_update} do test "returns an error if the object can't be updated by the actor", %{ valid_update: valid_update } do - other_user = insert(:user) + other_user = insert(:user, local: false) update = valid_update @@ -40,5 +40,129 @@ test "returns an error if the object can't be updated by the actor", %{ assert {:error, _cng} = ObjectValidator.validate(update, []) end + + test "validates as long as the object is same-origin with the actor", %{ + valid_update: valid_update + } do + other_user = insert(:user) + + update = + valid_update + |> Map.put("actor", other_user.ap_id) + + assert {:ok, _update, []} = ObjectValidator.validate(update, []) + end + + test "validates if the object is not of an Actor type" do + note = insert(:note) + updated_note = note.data |> Map.put("content", "edited content") + other_user = insert(:user) + + {:ok, update, _} = Builder.update(other_user, updated_note) + + assert {:ok, _update, _} = ObjectValidator.validate(update, []) + end + end + + describe "update note" do + test "converts object into Pleroma's format" do + mastodon_tags = [ + %{ + "icon" => %{ + "mediaType" => "image/png", + "type" => "Image", + "url" => "https://somewhere.org/emoji/url/1.png" + }, + "id" => "https://somewhere.org/emoji/1", + "name" => ":some_emoji:", + "type" => "Emoji", + "updated" => "2021-04-07T11:00:00Z" + } + ] + + user = insert(:user) + note = insert(:note, user: user) + + updated_note = + note.data + |> Map.put("content", "edited content") + |> Map.put("tag", mastodon_tags) + + {:ok, update, _} = Builder.update(user, updated_note) + + assert {:ok, _update, meta} = ObjectValidator.validate(update, []) + + assert %{"emoji" => %{"some_emoji" => "https://somewhere.org/emoji/url/1.png"}} = + meta[:object_data] + end + + test "returns no object_data in meta for a local Update" do + user = insert(:user) + note = insert(:note, user: user) + + updated_note = + note.data + |> Map.put("content", "edited content") + + {:ok, update, _} = Builder.update(user, updated_note) + + assert {:ok, _update, meta} = ObjectValidator.validate(update, local: true) + assert is_nil(meta[:object_data]) + end + + test "returns object_data in meta for a remote Update" do + user = insert(:user) + note = insert(:note, user: user) + + updated_note = + note.data + |> Map.put("content", "edited content") + + {:ok, update, _} = Builder.update(user, updated_note) + + assert {:ok, _update, meta} = ObjectValidator.validate(update, local: false) + assert meta[:object_data] + + assert {:ok, _update, meta} = ObjectValidator.validate(update, []) + assert meta[:object_data] + end + end + + describe "update with history" do + setup do + user = insert(:user) + {:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"}) + {:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"}) + {:ok, external_rep} = Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data) + %{external_rep: external_rep} + end + + test "edited note", %{external_rep: external_rep} do + {:ok, _validate_res, meta} = ObjectValidator.validate(external_rep, []) + + assert %{"formerRepresentations" => %{"orderedItems" => [%{"emoji" => %{"dinosaur" => _}}]}} = + meta[:object_data] + end + + test "edited note, badly-formed formerRepresentations", %{external_rep: external_rep} do + external_rep = put_in(external_rep, ["object", "formerRepresentations"], %{}) + + assert {:error, _} = ObjectValidator.validate(external_rep, []) + end + + test "edited note, badly-formed history item", %{external_rep: external_rep} do + history_item = + Enum.at(external_rep["object"]["formerRepresentations"]["orderedItems"], 0) + |> Map.put("type", "Foo") + + external_rep = + put_in( + external_rep, + ["object", "formerRepresentations", "orderedItems"], + [history_item] + ) + + assert {:error, _} = ObjectValidator.validate(external_rep, []) + end end end diff --git a/test/pleroma/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs index 64c4a8c14..b24831e85 100644 --- a/test/pleroma/web/activity_pub/side_effects_test.exs +++ b/test/pleroma/web/activity_pub/side_effects_test.exs @@ -118,7 +118,10 @@ test "it blocks but does not unfollow if the relevant setting is set", %{ describe "update users" do setup do user = insert(:user, local: false) - {:ok, update_data, []} = Builder.update(user, %{"id" => user.ap_id, "name" => "new name!"}) + + {:ok, update_data, []} = + Builder.update(user, %{"id" => user.ap_id, "type" => "Person", "name" => "new name!"}) + {:ok, update, _meta} = ActivityPub.persist(update_data, local: true) %{user: user, update_data: update_data, update: update} @@ -140,6 +143,298 @@ test "it uses a given changeset to update", %{user: user, update: update} do end end + describe "update notes" do + setup do + make_time = fn -> + Pleroma.Web.ActivityPub.Utils.make_date() + end + + user = insert(:user) + note = insert(:note, user: user, data: %{"published" => make_time.()}) + _note_activity = insert(:note_activity, note: note) + + updated_note = + note.data + |> Map.put("summary", "edited summary") + |> Map.put("content", "edited content") + |> Map.put("updated", make_time.()) + + {:ok, update_data, []} = Builder.update(user, updated_note) + {:ok, update, _meta} = ActivityPub.persist(update_data, local: true) + + %{ + user: user, + note: note, + object_id: note.id, + update_data: update_data, + update: update, + updated_note: updated_note + } + end + + test "it updates the note", %{ + object_id: object_id, + update: update, + updated_note: updated_note + } do + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + updated_time = updated_note["updated"] + + new_note = Pleroma.Object.get_by_id(object_id) + + assert %{ + "summary" => "edited summary", + "content" => "edited content", + "updated" => ^updated_time + } = new_note.data + end + + test "it rejects updates with no updated attribute in object", %{ + object_id: object_id, + update: update, + updated_note: updated_note + } do + old_note = Pleroma.Object.get_by_id(object_id) + updated_note = Map.drop(updated_note, ["updated"]) + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + new_note = Pleroma.Object.get_by_id(object_id) + assert old_note.data == new_note.data + end + + test "it rejects updates with updated attribute older than what we have in the original object", + %{ + object_id: object_id, + update: update, + updated_note: updated_note + } do + old_note = Pleroma.Object.get_by_id(object_id) + {:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"]) + + updated_note = + Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, -10))) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + new_note = Pleroma.Object.get_by_id(object_id) + assert old_note.data == new_note.data + end + + test "it rejects updates with updated attribute older than the last Update", %{ + object_id: object_id, + update: update, + updated_note: updated_note + } do + old_note = Pleroma.Object.get_by_id(object_id) + {:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"]) + + updated_note = + Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, +10))) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + + old_note = Pleroma.Object.get_by_id(object_id) + {:ok, update_time, _} = DateTime.from_iso8601(old_note.data["updated"]) + + updated_note = + Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(update_time, -5))) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + + new_note = Pleroma.Object.get_by_id(object_id) + assert old_note.data == new_note.data + end + + test "it updates using object_data", %{ + object_id: object_id, + update: update, + updated_note: updated_note + } do + updated_note = Map.put(updated_note, "summary", "mew mew") + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + new_note = Pleroma.Object.get_by_id(object_id) + assert %{"summary" => "mew mew", "content" => "edited content"} = new_note.data + end + + test "it records the original note in formerRepresentations", %{ + note: note, + object_id: object_id, + update: update, + updated_note: updated_note + } do + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + %{data: new_note} = Pleroma.Object.get_by_id(object_id) + assert %{"summary" => "edited summary", "content" => "edited content"} = new_note + + assert [Map.drop(note.data, ["id", "formerRepresentations"])] == + new_note["formerRepresentations"]["orderedItems"] + + assert new_note["formerRepresentations"]["totalItems"] == 1 + end + + test "it puts the original note at the front of formerRepresentations", %{ + user: user, + note: note, + object_id: object_id, + update: update, + updated_note: updated_note + } do + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + %{data: first_edit} = Pleroma.Object.get_by_id(object_id) + + second_updated_note = + note.data + |> Map.put("summary", "edited summary 2") + |> Map.put("content", "edited content 2") + |> Map.put( + "updated", + first_edit["updated"] + |> DateTime.from_iso8601() + |> elem(1) + |> DateTime.add(10) + |> DateTime.to_iso8601() + ) + + {:ok, second_update_data, []} = Builder.update(user, second_updated_note) + {:ok, update, _meta} = ActivityPub.persist(second_update_data, local: true) + {:ok, _, _} = SideEffects.handle(update, object_data: second_updated_note) + %{data: new_note} = Pleroma.Object.get_by_id(object_id) + assert %{"summary" => "edited summary 2", "content" => "edited content 2"} = new_note + + original_version = Map.drop(note.data, ["id", "formerRepresentations"]) + first_edit = Map.drop(first_edit, ["id", "formerRepresentations"]) + + assert [first_edit, original_version] == + new_note["formerRepresentations"]["orderedItems"] + + assert new_note["formerRepresentations"]["totalItems"] == 2 + end + + test "it does not prepend to formerRepresentations if no actual changes are made", %{ + note: note, + object_id: object_id, + update: update, + updated_note: updated_note + } do + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + %{data: first_edit} = Pleroma.Object.get_by_id(object_id) + + updated_note = + updated_note + |> Map.put( + "updated", + first_edit["updated"] + |> DateTime.from_iso8601() + |> elem(1) + |> DateTime.add(10) + |> DateTime.to_iso8601() + ) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_note) + %{data: new_note} = Pleroma.Object.get_by_id(object_id) + assert %{"summary" => "edited summary", "content" => "edited content"} = new_note + + original_version = Map.drop(note.data, ["id", "formerRepresentations"]) + + assert [original_version] == + new_note["formerRepresentations"]["orderedItems"] + + assert new_note["formerRepresentations"]["totalItems"] == 1 + end + end + + describe "update questions" do + setup do + user = insert(:user) + + question = + insert(:question, + user: user, + data: %{"published" => Pleroma.Web.ActivityPub.Utils.make_date()} + ) + + %{user: user, data: question.data, id: question.id} + end + + test "allows updating choice count without generating edit history", %{ + user: user, + data: data, + id: id + } do + new_choices = + data["oneOf"] + |> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end) + + updated_question = + data + |> Map.put("oneOf", new_choices) + |> Map.put("updated", Pleroma.Web.ActivityPub.Utils.make_date()) + + {:ok, update_data, []} = Builder.update(user, updated_question) + {:ok, update, _meta} = ActivityPub.persist(update_data, local: true) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_question) + + %{data: new_question} = Pleroma.Object.get_by_id(id) + + assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] = + new_question["oneOf"] + + refute Map.has_key?(new_question, "formerRepresentations") + end + + test "allows updating choice count without updated field", %{ + user: user, + data: data, + id: id + } do + new_choices = + data["oneOf"] + |> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end) + + updated_question = + data + |> Map.put("oneOf", new_choices) + + {:ok, update_data, []} = Builder.update(user, updated_question) + {:ok, update, _meta} = ActivityPub.persist(update_data, local: true) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_question) + + %{data: new_question} = Pleroma.Object.get_by_id(id) + + assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] = + new_question["oneOf"] + + refute Map.has_key?(new_question, "formerRepresentations") + end + + test "allows updating choice count with updated field same as the creation date", %{ + user: user, + data: data, + id: id + } do + new_choices = + data["oneOf"] + |> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end) + + updated_question = + data + |> Map.put("oneOf", new_choices) + |> Map.put("updated", data["published"]) + + {:ok, update_data, []} = Builder.update(user, updated_question) + {:ok, update, _meta} = ActivityPub.persist(update_data, local: true) + + {:ok, _, _} = SideEffects.handle(update, object_data: updated_question) + + %{data: new_question} = Pleroma.Object.get_by_id(id) + + assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] = + new_question["oneOf"] + + refute Map.has_key?(new_question, "formerRepresentations") + end + end + describe "EmojiReact objects" do setup do poster = insert(:user) @@ -544,9 +839,7 @@ test "it streams out the announce", %{announce: announce} do ]) do {:ok, announce, _} = SideEffects.handle(announce) - assert called( - Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], announce) - ) + assert called(Pleroma.Web.Streamer.stream(["user", "list"], announce)) assert called(Pleroma.Web.Push.send(:_)) end diff --git a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs index ceedb185f..9d99df27c 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs @@ -37,6 +37,37 @@ test "it works for incoming emoji reactions" do assert match?([["👌", _]], object.data["reactions"]) end + test "it works for incoming unqualified emoji reactions" do + user = insert(:user) + other_user = insert(:user, local: false) + {:ok, activity} = CommonAPI.post(user, %{status: "hello"}) + + # woman detective emoji, unqualified + unqualified_emoji = [0x1F575, 0x200D, 0x2640] |> List.to_string() + + data = + File.read!("test/fixtures/emoji-reaction.json") + |> Jason.decode!() + |> Map.put("object", activity.data["object"]) + |> Map.put("actor", other_user.ap_id) + |> Map.put("content", unqualified_emoji) + + {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == other_user.ap_id + assert data["type"] == "EmojiReact" + assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2" + assert data["object"] == activity.data["object"] + # woman detective emoji, fully qualified + emoji = [0x1F575, 0xFE0F, 0x200D, 0x2640, 0xFE0F] |> List.to_string() + assert data["content"] == emoji + + object = Object.get_by_ap_id(data["object"]) + + assert object.data["reaction_count"] == 1 + assert match?([[emoji, _]], object.data["reactions"]) + end + test "it reject invalid emoji reactions" do user = insert(:user) other_user = insert(:user, local: false) diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index b00fd919b..7c406fbd0 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -707,4 +707,42 @@ test "take_emoji_tags/1" do } ] end + + test "the standalone note uses its own ID when context is missing" do + insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8") + + activity = + "test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json" + |> File.read!() + |> Jason.decode!() + + {:ok, %Activity{} = modified} = Transmogrifier.handle_incoming(activity) + object = Object.normalize(modified, fetch: false) + + assert object.data["context"] == object.data["id"] + assert modified.data["context"] == object.data["id"] + end + + test "the reply note uses its parent's ID when context is missing and reply is unreachable" do + insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8") + + activity = + "test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json" + |> File.read!() + |> Jason.decode!() + + object = + activity["object"] + |> Map.put("inReplyTo", "https://404.site/object/went-to-buy-milk") + + activity = + activity + |> Map.put("object", object) + + {:ok, %Activity{} = modified} = Transmogrifier.handle_incoming(activity) + object = Object.normalize(modified, fetch: false) + + assert object.data["context"] == object.data["inReplyTo"] + assert modified.data["context"] == object.data["inReplyTo"] + end end diff --git a/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs index d22ec400d..d31070546 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/question_handling_test.exs @@ -33,8 +33,6 @@ test "Mastodon Question activity" do assert object.data["context"] == "tag:mastodon.sdf.org,2019-05-10:objectId=15095122:objectType=Conversation" - assert object.data["context_id"] - assert object.data["anyOf"] == [] assert Enum.sort(object.data["oneOf"]) == @@ -68,7 +66,6 @@ test "Mastodon Question activity" do reply_object = Object.normalize(reply_activity, fetch: false) assert reply_object.data["context"] == object.data["context"] - assert reply_object.data["context_id"] == object.data["context_id"] end test "Mastodon Question activity with HTML tags in plaintext" do diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index 335fe1a30..6b4636d22 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -61,7 +61,7 @@ test "it accepts Flag activities" do note_obj = %{ "type" => "Note", - "id" => activity.data["id"], + "id" => activity.object.data["id"], "content" => "test post", "published" => object.data["published"], "actor" => AccountView.render("show.json", %{user: user, skip_visibility_check: true}) @@ -108,15 +108,20 @@ test "it accepts Move activities" do assert activity.data["type"] == "Move" end - test "a reply with mismatched context is rejected" do - insert(:user, ap_id: "https://macgirvin.com/channel/mike") + test "it fixes both the Create and object contexts in a reply" do + insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8") + insert(:user, ap_id: "https://p.helene.moe/users/helene") - note_activity = - "test/fixtures/roadhouse-create-activity.json" + create_activity = + "test/fixtures/create-pleroma-reply-to-misskey-thread.json" |> File.read!() |> Jason.decode!() - assert {:error, _} = Transmogrifier.handle_incoming(note_activity) + assert {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(create_activity) + + object = Object.normalize(activity, fetch: false) + + assert activity.data["context"] == object.data["context"] end end @@ -227,7 +232,6 @@ test "it strips internal fields" do assert is_nil(modified["object"]["like_count"]) assert is_nil(modified["object"]["announcements"]) assert is_nil(modified["object"]["announcement_count"]) - assert is_nil(modified["object"]["context_id"]) assert is_nil(modified["object"]["generator"]) end @@ -242,7 +246,6 @@ test "it strips internal fields of article" do assert is_nil(modified["object"]["like_count"]) assert is_nil(modified["object"]["announcements"]) assert is_nil(modified["object"]["announcement_count"]) - assert is_nil(modified["object"]["context_id"]) assert is_nil(modified["object"]["likes"]) end @@ -312,6 +315,28 @@ test "custom emoji urls are URI encoded" do assert url == "http://localhost:4001/emoji/dino%20walking.gif" end + + test "Updates of Notes are handled" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"}) + {:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew :blank:"}) + + {:ok, prepared} = Transmogrifier.prepare_outgoing(update.data) + + assert %{ + "content" => "mew mew :blank:", + "tag" => [%{"name" => ":blank:", "type" => "Emoji"}], + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "content" => "everybody do the dinosaur :dinosaur:", + "tag" => [%{"name" => ":dinosaur:", "type" => "Emoji"}] + } + ] + } + } = prepared["object"] + end end describe "user upgrade" do @@ -575,4 +600,43 @@ test "puts dimensions into attachment url field" do assert Transmogrifier.fix_attachments(object) == expected end end + + describe "prepare_object/1" do + test "it processes history" do + original = %{ + "formerRepresentations" => %{ + "orderedItems" => [ + %{ + "generator" => %{}, + "emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"} + } + ] + } + } + + processed = Transmogrifier.prepare_object(original) + + history_item = Enum.at(processed["formerRepresentations"]["orderedItems"], 0) + + refute Map.has_key?(history_item, "generator") + + assert [%{"name" => ":blobcat:"}] = history_item["tag"] + end + + test "it works when there is no or bad history" do + original = %{ + "formerRepresentations" => %{ + "items" => [ + %{ + "generator" => %{}, + "emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"} + } + ] + } + } + + processed = Transmogrifier.prepare_object(original) + assert processed["formerRepresentations"] == original["formerRepresentations"] + end + end end diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs index 447621718..e7d1e01c4 100644 --- a/test/pleroma/web/activity_pub/utils_test.exs +++ b/test/pleroma/web/activity_pub/utils_test.exs @@ -429,7 +429,6 @@ test "returns map with id and published data" do object = Object.normalize(note_activity, fetch: false) res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]}) assert res["context"] == object.data["id"] - assert res["context_id"] == object.id assert res["id"] assert res["published"] end @@ -437,7 +436,6 @@ test "returns map with id and published data" do test "returns map with fake id and published data" do assert %{ "context" => "pleroma:fakecontext", - "context_id" => -1, "id" => "pleroma:fakeid", "published" => _ } = Utils.lazy_put_activity_defaults(%{}, true) @@ -454,13 +452,11 @@ test "returns activity data with object" do }) assert res["context"] == object.data["id"] - assert res["context_id"] == object.id assert res["id"] assert res["published"] assert res["object"]["id"] assert res["object"]["published"] assert res["object"]["context"] == object.data["id"] - assert res["object"]["context_id"] == object.id end end @@ -477,7 +473,7 @@ test "returns map with Flag object" do content = "foobar" target_ap_id = target_account.ap_id - activity_ap_id = activity.data["id"] + object_ap_id = activity.object.data["id"] res = Utils.make_flag_data( @@ -493,7 +489,7 @@ test "returns map with Flag object" do note_obj = %{ "type" => "Note", - "id" => activity_ap_id, + "id" => object_ap_id, "content" => content, "published" => activity.object.data["published"], "actor" => @@ -508,6 +504,49 @@ test "returns map with Flag object" do "state" => "open" } = res end + + test "returns map with Flag object with a non-Create Activity" do + reporter = insert(:user) + posting_account = insert(:user) + target_account = insert(:user) + + {:ok, activity} = CommonAPI.post(posting_account, %{status: "foobar"}) + {:ok, like} = CommonAPI.favorite(target_account, activity.id) + context = Utils.generate_context_id() + content = "foobar" + + target_ap_id = target_account.ap_id + object_ap_id = activity.object.data["id"] + + res = + Utils.make_flag_data( + %{ + actor: reporter, + context: context, + account: target_account, + statuses: [%{"id" => like.data["id"]}], + content: content + }, + %{} + ) + + note_obj = %{ + "type" => "Note", + "id" => object_ap_id, + "content" => content, + "published" => activity.object.data["published"], + "actor" => + AccountView.render("show.json", %{user: posting_account, skip_visibility_check: true}) + } + + assert %{ + "type" => "Flag", + "content" => ^content, + "context" => ^context, + "object" => [^target_ap_id, ^note_obj], + "state" => "open" + } = res + end end describe "add_announce_to_object/2" do diff --git a/test/pleroma/web/activity_pub/views/object_view_test.exs b/test/pleroma/web/activity_pub/views/object_view_test.exs index 48a4b47c4..d94878e31 100644 --- a/test/pleroma/web/activity_pub/views/object_view_test.exs +++ b/test/pleroma/web/activity_pub/views/object_view_test.exs @@ -81,4 +81,18 @@ test "renders an announce activity" do assert result["object"] == object.data["id"] assert result["type"] == "Announce" end + + test "renders an undo announce activity" do + note = insert(:note_activity) + user = insert(:user) + + {:ok, announce} = CommonAPI.repeat(note.id, user) + {:ok, undo} = CommonAPI.unrepeat(note.id, user) + + result = ObjectView.render("object.json", %{object: undo}) + + assert result["id"] == undo.data["id"] + assert result["object"] == announce.data["id"] + assert result["type"] == "Undo" + end end diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs index 5cbfd8ab7..5f03c019e 100644 --- a/test/pleroma/web/activity_pub/views/user_view_test.exs +++ b/test/pleroma/web/activity_pub/views/user_view_test.exs @@ -12,7 +12,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do test "Renders a user, including the public key" do user = insert(:user) - {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) @@ -55,7 +54,6 @@ test "Renders with emoji tags" do test "Does not add an avatar image if the user hasn't set one" do user = insert(:user) - {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) refute result["icon"] @@ -67,8 +65,6 @@ test "Does not add an avatar image if the user hasn't set one" do banner: %{"url" => [%{"href" => "https://somebanner"}]} ) - {:ok, user} = User.ensure_keys_present(user) - result = UserView.render("user.json", %{user: user}) assert result["icon"]["url"] == "https://someurl" assert result["image"]["url"] == "https://somebanner" @@ -89,7 +85,6 @@ test "renders AKAs" do describe "endpoints" do test "local users have a usable endpoints structure" do user = insert(:user) - {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) @@ -105,7 +100,6 @@ test "local users have a usable endpoints structure" do test "remote users have an empty endpoints structure" do user = insert(:user, local: false) - {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) @@ -115,7 +109,6 @@ test "remote users have an empty endpoints structure" do test "instance users do not expose oAuth endpoints" do user = insert(:user, nickname: nil, local: true) - {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) diff --git a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs index aa47b74e8..1b5c31b7d 100644 --- a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs @@ -56,7 +56,7 @@ test "it deletes a message from the chat", %{conn: conn, admin: admin} do log_entry = Repo.one(ModerationLog) assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} deleted chat message ##{cm_ref.id}" + "@#{admin.nickname} deleted chat message ##{message.id}" assert result["id"] == cm_ref.id refute MessageReference.get_by_id(cm_ref.id) diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs index 6d014b65b..9ef7c0c46 100644 --- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/config_controller_test.exs @@ -317,14 +317,14 @@ test "create new config setting in db", %{conn: conn} do end test "save configs setting without explicit key", %{conn: conn} do - level = Application.get_env(:quack, :level) - meta = Application.get_env(:quack, :meta) - webhook_url = Application.get_env(:quack, :webhook_url) + adapter = Application.get_env(:http, :adapter) + send_user_agent = Application.get_env(:http, :send_user_agent) + user_agent = Application.get_env(:http, :user_agent) on_exit(fn -> - Application.put_env(:quack, :level, level) - Application.put_env(:quack, :meta, meta) - Application.put_env(:quack, :webhook_url, webhook_url) + Application.put_env(:http, :adapter, adapter) + Application.put_env(:http, :send_user_agent, send_user_agent) + Application.put_env(:http, :user_agent, user_agent) end) conn = @@ -333,19 +333,19 @@ test "save configs setting without explicit key", %{conn: conn} do |> post("/api/pleroma/admin/config", %{ configs: [ %{ - group: ":quack", - key: ":level", - value: ":info" + group: ":http", + key: ":adapter", + value: [":someval"] }, %{ - group: ":quack", - key: ":meta", - value: [":none"] + group: ":http", + key: ":send_user_agent", + value: true }, %{ - group: ":quack", - key: ":webhook_url", - value: "https://hooks.slack.com/services/KEY" + group: ":http", + key: ":user_agent", + value: [":default"] } ] }) @@ -353,30 +353,30 @@ test "save configs setting without explicit key", %{conn: conn} do assert json_response_and_validate_schema(conn, 200) == %{ "configs" => [ %{ - "group" => ":quack", - "key" => ":level", - "value" => ":info", - "db" => [":level"] + "group" => ":http", + "key" => ":adapter", + "value" => [":someval"], + "db" => [":adapter"] }, %{ - "group" => ":quack", - "key" => ":meta", - "value" => [":none"], - "db" => [":meta"] + "group" => ":http", + "key" => ":send_user_agent", + "value" => true, + "db" => [":send_user_agent"] }, %{ - "group" => ":quack", - "key" => ":webhook_url", - "value" => "https://hooks.slack.com/services/KEY", - "db" => [":webhook_url"] + "group" => ":http", + "key" => ":user_agent", + "value" => [":default"], + "db" => [":user_agent"] } ], "need_reboot" => false } - assert Application.get_env(:quack, :level) == :info - assert Application.get_env(:quack, :meta) == [:none] - assert Application.get_env(:quack, :webhook_url) == "https://hooks.slack.com/services/KEY" + assert Application.get_env(:http, :adapter) == [:someval] + assert Application.get_env(:http, :send_user_agent) == true + assert Application.get_env(:http, :user_agent) == [:default] end test "saving config with partial update", %{conn: conn} do diff --git a/test/pleroma/web/admin_api/controllers/instance_document_controller_test.exs b/test/pleroma/web/admin_api/controllers/instance_document_controller_test.exs index 2601a026f..9511dccea 100644 --- a/test/pleroma/web/admin_api/controllers/instance_document_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/instance_document_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.InstanceDocumentControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase import Pleroma.Factory @dir "test/tmp/instance_static" diff --git a/test/pleroma/web/admin_api/controllers/report_controller_test.exs b/test/pleroma/web/admin_api/controllers/report_controller_test.exs index b155cf01a..aee26d80a 100644 --- a/test/pleroma/web/admin_api/controllers/report_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/report_controller_test.exs @@ -68,6 +68,32 @@ test "returns report by its id", %{conn: conn} do assert notes["content"] == "this is an admin note" end + test "renders reported content even if the status is deleted", %{conn: conn} do + [reporter, target_user] = insert_pair(:user) + activity = insert(:note_activity, user: target_user) + activity = Activity.normalize(activity) + + {:ok, %{id: report_id}} = + CommonAPI.report(reporter, %{ + account_id: target_user.id, + comment: "I feel offended", + status_ids: [activity.id] + }) + + CommonAPI.delete(activity.id, target_user) + + response = + conn + |> get("/api/pleroma/admin/reports/#{report_id}") + |> json_response_and_validate_schema(:ok) + + assert response["id"] == report_id + + assert [status] = response["statuses"] + assert activity.object.data["id"] == status["uri"] + assert activity.object.data["content"] == status["content"] + end + test "returns 404 when report id is invalid", %{conn: conn} do conn = get(conn, "/api/pleroma/admin/reports/test") diff --git a/test/pleroma/web/common_api/utils_test.exs b/test/pleroma/web/common_api/utils_test.exs index 5b2019969..b538c5979 100644 --- a/test/pleroma/web/common_api/utils_test.exs +++ b/test/pleroma/web/common_api/utils_test.exs @@ -4,7 +4,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do alias Pleroma.Builders.UserBuilder - alias Pleroma.Object alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI.ActivityDraft alias Pleroma.Web.CommonAPI.Utils @@ -273,22 +272,6 @@ test "delegated renderers" do end end - describe "context_to_conversation_id" do - test "creates a mapping object" do - conversation_id = Utils.context_to_conversation_id("random context") - object = Object.get_by_ap_id("random context") - - assert conversation_id == object.id - end - - test "returns an existing mapping for an existing object" do - {:ok, object} = Object.context_mapping("random context") |> Repo.insert() - conversation_id = Utils.context_to_conversation_id("random context") - - assert conversation_id == object.id - end - end - describe "formats date to asctime" do test "when date is in ISO 8601 format" do date = DateTime.utc_now() |> DateTime.to_iso8601() @@ -517,17 +500,6 @@ test "returns empty string when date invalid" do end end - describe "conversation_id_to_context/1" do - test "returns id" do - object = insert(:note) - assert Utils.conversation_id_to_context(object.id) == object.data["id"] - end - - test "returns error if object not found" do - assert Utils.conversation_id_to_context("123") == {:error, "No such conversation"} - end - end - describe "maybe_notify_mentioned_recipients/2" do test "returns recipients when activity is not `Create`" do activity = insert(:like_activity) diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index 25743daae..44355c26d 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -61,9 +61,11 @@ test "it posts a poll" do describe "blocking" do setup do blocker = insert(:user) - blocked = insert(:user) - User.follow(blocker, blocked) - User.follow(blocked, blocker) + blocked = insert(:user, local: false) + CommonAPI.follow(blocker, blocked) + CommonAPI.follow(blocked, blocker) + CommonAPI.accept_follow_request(blocker, blocked) + CommonAPI.accept_follow_request(blocked, blocked) %{blocker: blocker, blocked: blocked} end @@ -72,6 +74,9 @@ test "it blocks and federates", %{blocker: blocker, blocked: blocked} do with_mock Pleroma.Web.Federator, publish: fn _ -> nil end do + assert User.get_follow_state(blocker, blocked) == :follow_accept + refute is_nil(Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked)) + assert {:ok, block} = CommonAPI.block(blocker, blocked) assert block.local @@ -79,6 +84,11 @@ test "it blocks and federates", %{blocker: blocker, blocked: blocked} do refute User.following?(blocker, blocked) refute User.following?(blocked, blocker) + refute User.get_follow_state(blocker, blocked) + + assert %{data: %{"state" => "reject"}} = + Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked) + assert called(Pleroma.Web.Federator.publish(block)) end end @@ -588,7 +598,7 @@ test "it filters out obviously bad tags when accepting a post as HTML" do object = Object.normalize(activity, fetch: false) assert object.data["content"] == "

2hu

alert('xss')" - assert object.data["source"] == post + assert object.data["source"]["content"] == post end test "it filters out obviously bad tags when accepting a post as Markdown" do @@ -605,7 +615,7 @@ test "it filters out obviously bad tags when accepting a post as Markdown" do object = Object.normalize(activity, fetch: false) assert object.data["content"] == "

2hu

" - assert object.data["source"] == post + assert object.data["source"]["content"] == post end test "it does not allow replies to direct messages that are not direct messages themselves" do @@ -1092,10 +1102,11 @@ test "creates a report" do target_user = insert(:user) {:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"}) + activity = Activity.normalize(activity) reporter_ap_id = reporter.ap_id target_ap_id = target_user.ap_id - activity_ap_id = activity.data["id"] + reported_object_ap_id = activity.object.data["id"] comment = "foobar" report_data = %{ @@ -1106,7 +1117,7 @@ test "creates a report" do note_obj = %{ "type" => "Note", - "id" => activity_ap_id, + "id" => reported_object_ap_id, "content" => "foobar", "published" => activity.object.data["published"], "actor" => AccountView.render("show.json", %{user: target_user}) @@ -1128,6 +1139,7 @@ test "creates a report" do test "updates report state" do [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) + object = Object.normalize(activity) {:ok, %Activity{id: report_id}} = CommonAPI.report(reporter, %{ @@ -1140,10 +1152,36 @@ test "updates report state" do assert report.data["state"] == "resolved" - [reported_user, activity_id] = report.data["object"] + [reported_user, object_id] = report.data["object"] assert reported_user == target_user.ap_id - assert activity_id == activity.data["id"] + assert object_id == object.data["id"] + end + + test "updates report state, don't strip when report_strip_status is false" do + clear_config([:instance, :report_strip_status], false) + + [reporter, target_user] = insert_pair(:user) + activity = insert(:note_activity, user: target_user) + + {:ok, %Activity{id: report_id, data: report_data}} = + CommonAPI.report(reporter, %{ + account_id: target_user.id, + comment: "I feel offended", + status_ids: [activity.id] + }) + + {:ok, report} = CommonAPI.update_report_state(report_id, "resolved") + + assert report.data["state"] == "resolved" + + [reported_user, reported_activity] = report.data["object"] + + assert reported_user == target_user.ap_id + assert is_map(reported_activity) + + assert reported_activity["content"] == + report_data["object"] |> Enum.at(1) |> Map.get("content") end test "does not update report state when state is unsupported" do @@ -1543,4 +1581,128 @@ test "unreact_with_emoji" do end end end + + describe "update/3" do + test "updates a post" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1"}) + + {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"}) + + updated_object = Object.normalize(updated) + assert updated_object.data["content"] == "updated 2" + assert Map.get(updated_object.data, "summary", "") == "" + assert Map.has_key?(updated_object.data, "updated") + end + + test "does not change visibility" do + user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1", visibility: "private"}) + + {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"}) + + updated_object = Object.normalize(updated) + assert updated_object.data["content"] == "updated 2" + assert Map.get(updated_object.data, "summary", "") == "" + assert Visibility.get_visibility(updated_object) == "private" + assert Visibility.get_visibility(updated) == "private" + end + + test "updates a post with emoji" do + [{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all() + + user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"}) + + {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"}) + + updated_object = Object.normalize(updated) + assert updated_object.data["content"] == "updated 2 :#{emoji2}:" + assert %{^emoji2 => _} = updated_object.data["emoji"] + end + + test "updates a post with emoji and federate properly" do + [{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all() + + user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"}) + + clear_config([:instance, :federating], true) + + with_mock Pleroma.Web.Federator, + publish: fn _p -> nil end do + {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"}) + + assert updated.data["object"]["content"] == "updated 2 :#{emoji2}:" + assert %{^emoji2 => _} = updated.data["object"]["emoji"] + + assert called(Pleroma.Web.Federator.publish(updated)) + end + end + + test "editing a post that copied a remote title with remote emoji should keep that emoji" do + remote_emoji_uri = "https://remote.org/emoji.png" + + note = + insert( + :note, + data: %{ + "summary" => ":remoteemoji:", + "emoji" => %{ + "remoteemoji" => remote_emoji_uri + }, + "tag" => [ + %{ + "type" => "Emoji", + "name" => "remoteemoji", + "icon" => %{"url" => remote_emoji_uri} + } + ] + } + ) + + note_activity = insert(:note_activity, note: note) + + user = insert(:user) + + {:ok, reply} = + CommonAPI.post(user, %{ + status: "reply", + spoiler_text: ":remoteemoji:", + in_reply_to_id: note_activity.id + }) + + assert reply.object.data["emoji"]["remoteemoji"] == remote_emoji_uri + + {:ok, edit} = + CommonAPI.update(user, reply, %{status: "reply mew mew", spoiler_text: ":remoteemoji:"}) + + edited_note = Pleroma.Object.normalize(edit) + + assert edited_note.data["emoji"]["remoteemoji"] == remote_emoji_uri + end + + test "respects MRF" do + user = insert(:user) + + clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy]) + clear_config([:mrf_keyword, :replace], [{"updated", "mewmew"}]) + + {:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "updated 1"}) + assert Object.normalize(activity).data["summary"] == "mewmew 1" + + {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"}) + + updated_object = Object.normalize(updated) + assert updated_object.data["content"] == "mewmew 2" + assert Map.get(updated_object.data, "summary", "") == "" + assert Map.has_key?(updated_object.data, "updated") + end + end end diff --git a/test/pleroma/web/federator_test.exs b/test/pleroma/web/federator_test.exs index 5120bf57c..41d1c5d5e 100644 --- a/test/pleroma/web/federator_test.exs +++ b/test/pleroma/web/federator_test.exs @@ -153,7 +153,7 @@ test "rejects incoming AP docs with incorrect origin" do } assert {:ok, job} = Federator.incoming_ap_doc(params) - assert {:error, :origin_containment_failed} = ObanHelpers.perform(job) + assert {:cancel, :origin_containment_failed} = ObanHelpers.perform(job) end test "it does not crash if MRF rejects the post" do @@ -169,7 +169,7 @@ test "it does not crash if MRF rejects the post" do |> Jason.decode!() assert {:ok, job} = Federator.incoming_ap_doc(params) - assert {:error, _} = ObanHelpers.perform(job) + assert {:cancel, _} = ObanHelpers.perform(job) end end end diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index effa2144f..958b7f76f 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do alias Pleroma.Repo alias Pleroma.Tests.ObanHelpers alias Pleroma.User + alias Pleroma.UserRelationship alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.InternalFetchActor alias Pleroma.Web.CommonAPI @@ -407,6 +408,20 @@ test "gets users statuses", %{conn: conn} do assert id_two == to_string(activity.id) end + test "gets local-only statuses for authenticated users", %{user: _user, conn: conn} do + user_one = insert(:user) + + {:ok, activity} = CommonAPI.post(user_one, %{status: "HI!!!", visibility: "local"}) + + resp = + conn + |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) + + assert [%{"id" => id}] = resp + assert id == to_string(activity.id) + end + test "gets an users media, excludes reblogs", %{conn: conn} do note = insert(:note_activity) user = User.get_cached_by_ap_id(note.data["actor"]) @@ -881,6 +896,12 @@ test "following without reblogs" do |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: true}) |> json_response_and_validate_schema(200) + assert %{"showing_reblogs" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "1"}) + |> json_response_and_validate_schema(200) + assert [%{"id" => ^reblog_id}] = conn |> get("/api/v1/timelines/home") @@ -910,6 +931,12 @@ test "following with reblogs" do |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false}) |> json_response_and_validate_schema(200) + assert %{"showing_reblogs" => false} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "0"}) + |> json_response_and_validate_schema(200) + assert [] == conn |> get("/api/v1/timelines/home") @@ -920,21 +947,23 @@ test "following with subscription and unsubscribing" do %{conn: conn} = oauth_access(["follow"]) followed = insert(:user) - ret_conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true}) + assert %{"subscribing" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true}) + |> json_response_and_validate_schema(200) - assert %{"id" => _id, "subscribing" => true} = - json_response_and_validate_schema(ret_conn, 200) + assert %{"subscribing" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: "1"}) + |> json_response_and_validate_schema(200) - ret_conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false}) - - assert %{"id" => _id, "subscribing" => false} = - json_response_and_validate_schema(ret_conn, 200) + assert %{"subscribing" => false} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false}) + |> json_response_and_validate_schema(200) end test "following / unfollowing errors", %{user: user, conn: conn} do @@ -1011,6 +1040,40 @@ test "without notifications", %{conn: conn} do assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = json_response_and_validate_schema(conn, 200) end + + test "expiring", %{conn: conn, user: user} do + other_user = insert(:user) + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts/#{other_user.id}/mute", %{"duration" => "86400"}) + + assert %{"id" => _id, "muting" => true} = json_response_and_validate_schema(conn, 200) + + mute_expires_at = UserRelationship.get_mute_expire_date(user, other_user) + + assert DateTime.diff( + mute_expires_at, + DateTime.utc_now() |> DateTime.add(24 * 60 * 60) + ) in -3..3 + end + + test "falls back to expires_in", %{conn: conn, user: user} do + other_user = insert(:user) + + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts/#{other_user.id}/mute", %{"expires_in" => "86400"}) + |> json_response_and_validate_schema(200) + + mute_expires_at = UserRelationship.get_mute_expire_date(user, other_user) + + assert DateTime.diff( + mute_expires_at, + DateTime.utc_now() |> DateTime.add(24 * 60 * 60) + ) in -3..3 + end end describe "pinned statuses" do @@ -1829,21 +1892,21 @@ test "getting a list of mutes" do |> get("/api/v1/mutes") |> json_response_and_validate_schema(200) - assert [id1, id2, id3] == Enum.map(result, & &1["id"]) + assert [id3, id2, id1] == Enum.map(result, & &1["id"]) result = conn |> get("/api/v1/mutes?limit=1") |> json_response_and_validate_schema(200) - assert [%{"id" => ^id1}] = result + assert [%{"id" => ^id3}] = result result = conn |> get("/api/v1/mutes?since_id=#{id1}") |> json_response_and_validate_schema(200) - assert [%{"id" => ^id2}, %{"id" => ^id3}] = result + assert [%{"id" => ^id3}, %{"id" => ^id2}] = result result = conn @@ -1857,7 +1920,7 @@ test "getting a list of mutes" do |> get("/api/v1/mutes?since_id=#{id1}&limit=1") |> json_response_and_validate_schema(200) - assert [%{"id" => ^id2}] = result + assert [%{"id" => ^id3}] = result end test "list of mutes with with_relationships parameter" do @@ -1876,7 +1939,7 @@ test "list of mutes with with_relationships parameter" do assert [ %{ - "id" => ^id1, + "id" => ^id3, "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}} }, %{ @@ -1884,7 +1947,7 @@ test "list of mutes with with_relationships parameter" do "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}} }, %{ - "id" => ^id3, + "id" => ^id1, "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}} } ] = @@ -1909,7 +1972,7 @@ test "getting a list of blocks" do |> get("/api/v1/blocks") |> json_response_and_validate_schema(200) - assert [id1, id2, id3] == Enum.map(result, & &1["id"]) + assert [id3, id2, id1] == Enum.map(result, & &1["id"]) result = conn @@ -1917,7 +1980,7 @@ test "getting a list of blocks" do |> get("/api/v1/blocks?limit=1") |> json_response_and_validate_schema(200) - assert [%{"id" => ^id1}] = result + assert [%{"id" => ^id3}] = result result = conn @@ -1925,7 +1988,7 @@ test "getting a list of blocks" do |> get("/api/v1/blocks?since_id=#{id1}") |> json_response_and_validate_schema(200) - assert [%{"id" => ^id2}, %{"id" => ^id3}] = result + assert [%{"id" => ^id3}, %{"id" => ^id2}] = result result = conn @@ -1941,7 +2004,31 @@ test "getting a list of blocks" do |> get("/api/v1/blocks?since_id=#{id1}&limit=1") |> json_response_and_validate_schema(200) - assert [%{"id" => ^id2}] = result + assert [%{"id" => ^id3}] = result + + conn_res = + conn + |> assign(:user, user) + |> get("/api/v1/blocks?limit=2") + + next_url = + ~r{<.+?(?/api[^>]+)>; rel=\"next\"} + |> Regex.named_captures(get_resp_header(conn_res, "link") |> Enum.at(0)) + |> Map.get("link") + + result = + conn_res + |> json_response_and_validate_schema(200) + + assert [%{"id" => ^id3}, %{"id" => ^id2}] = result + + result = + conn + |> assign(:user, user) + |> get(next_url) + |> json_response_and_validate_schema(200) + + assert [%{"id" => ^id1}] = result end test "account lookup", %{conn: conn} do @@ -2046,4 +2133,48 @@ test "max pinned accounts", %{user: user, conn: conn} do |> json_response_and_validate_schema(400) end end + + describe "remove from followers" do + setup do: oauth_access(["follow"]) + + test "removing user from followers", %{conn: conn, user: user} do + %{id: other_user_id} = other_user = insert(:user) + + CommonAPI.follow(other_user, user) + + assert %{"id" => ^other_user_id, "followed_by" => false} = + conn + |> post("/api/v1/accounts/#{other_user_id}/remove_from_followers") + |> json_response_and_validate_schema(200) + + refute User.following?(other_user, user) + end + + test "removing remote user from followers", %{conn: conn, user: user} do + %{id: other_user_id} = other_user = insert(:user, local: false) + + CommonAPI.follow(other_user, user) + + assert User.following?(other_user, user) + + assert %{"id" => ^other_user_id, "followed_by" => false} = + conn + |> post("/api/v1/accounts/#{other_user_id}/remove_from_followers") + |> json_response_and_validate_schema(200) + + refute User.following?(other_user, user) + end + + test "removing user from followers errors", %{user: user, conn: conn} do + # self remove + conn_res = post(conn, "/api/v1/accounts/#{user.id}/remove_from_followers") + + assert %{"error" => "Can not unfollow yourself"} = + json_response_and_validate_schema(conn_res, 400) + + # remove non existing user + conn_res = post(conn, "/api/v1/accounts/doesntexist/remove_from_followers") + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) + end + end end diff --git a/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs index ba4628fc5..faa35f199 100644 --- a/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs @@ -3,9 +3,10 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase, async: false use Oban.Testing, repo: Pleroma.Repo + import Mock import Pleroma.Factory alias Pleroma.Filter @@ -53,24 +54,19 @@ test "a filter with expires_in", %{conn: conn, user: user} do in_seconds = 600 response = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/filters", %{ - "phrase" => "knights", - context: ["home"], - expires_in: in_seconds - }) - |> json_response_and_validate_schema(200) + with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/filters", %{ + "phrase" => "knights", + context: ["home"], + expires_in: in_seconds + }) + |> json_response_and_validate_schema(200) + end assert response["irreversible"] == false - - expected_expiration = - NaiveDateTime.utc_now() - |> NaiveDateTime.add(in_seconds) - - {:ok, actual_expiration} = NaiveDateTime.from_iso8601(response["expires_at"]) - - assert abs(NaiveDateTime.diff(expected_expiration, actual_expiration)) <= 5 + assert response["expires_at"] == "2017-03-17T17:19:58.000Z" filter = Filter.get(response["id"], user) @@ -177,28 +173,25 @@ test "common" do assert response["whole_word"] == true end - @tag :erratic test "with adding expires_at", %{conn: conn, user: user} do filter = insert(:filter, user: user) in_seconds = 600 response = - conn - |> put_req_header("content-type", "application/json") - |> put("/api/v1/filters/#{filter.filter_id}", %{ - phrase: "nii", - context: ["public"], - expires_in: in_seconds, - irreversible: true - }) - |> json_response_and_validate_schema(200) + with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/filters/#{filter.filter_id}", %{ + phrase: "nii", + context: ["public"], + expires_in: in_seconds, + irreversible: true + }) + |> json_response_and_validate_schema(200) + end assert response["irreversible"] == true - - assert response["expires_at"] == - NaiveDateTime.utc_now() - |> NaiveDateTime.add(in_seconds) - |> Pleroma.Web.CommonAPI.Utils.to_masto_date() + assert response["expires_at"] == "2017-03-17T17:19:58.000Z" filter = Filter.get(response["id"], user) diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs index 696ac8bd9..1524df98f 100644 --- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs @@ -459,7 +459,7 @@ test "filters notifications using exclude_types" do assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200) end - test "filters notifications using include_types" do + test "filters notifications using types" do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) @@ -474,21 +474,21 @@ test "filters notifications using include_types" do reblog_notification_id = get_notification_id_by_activity(reblog_activity) follow_notification_id = get_notification_id_by_activity(follow_activity) - conn_res = get(conn, "/api/v1/notifications?include_types[]=follow") + conn_res = get(conn, "/api/v1/notifications?types[]=follow") assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200) - conn_res = get(conn, "/api/v1/notifications?include_types[]=mention") + conn_res = get(conn, "/api/v1/notifications?types[]=mention") assert [%{"id" => ^mention_notification_id}] = json_response_and_validate_schema(conn_res, 200) - conn_res = get(conn, "/api/v1/notifications?include_types[]=favourite") + conn_res = get(conn, "/api/v1/notifications?types[]=favourite") assert [%{"id" => ^favorite_notification_id}] = json_response_and_validate_schema(conn_res, 200) - conn_res = get(conn, "/api/v1/notifications?include_types[]=reblog") + conn_res = get(conn, "/api/v1/notifications?types[]=reblog") assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200) @@ -496,7 +496,7 @@ test "filters notifications using include_types" do assert length(result) == 4 - query = params_to_query(%{include_types: ["follow", "mention", "favourite", "reblog"]}) + query = params_to_query(%{types: ["follow", "mention", "favourite", "reblog"]}) result = conn @@ -506,6 +506,23 @@ test "filters notifications using include_types" do assert length(result) == 4 end + test "filtering falls back to include_types" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + other_user = insert(:user) + + {:ok, _activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"}) + {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"}) + {:ok, _activity} = CommonAPI.favorite(other_user, create_activity.id) + {:ok, _activity} = CommonAPI.repeat(create_activity.id, other_user) + {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user) + + follow_notification_id = get_notification_id_by_activity(follow_activity) + + conn_res = get(conn, "/api/v1/notifications?include_types[]=follow") + + assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200) + end + test "destroy multiple" do %{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"]) other_user = insert(:user) diff --git a/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs index 6d1a63334..c7aa76122 100644 --- a/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs @@ -5,6 +5,8 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do use Pleroma.Web.ConnCase, async: true + alias Pleroma.Activity + alias Pleroma.Repo alias Pleroma.Web.CommonAPI import Pleroma.Factory @@ -27,6 +29,41 @@ test "submit a basic report", %{conn: conn, target_user: target_user} do |> json_response_and_validate_schema(200) end + test "submit a report with a fake Create", %{ + conn: conn + } do + target_user = insert(:user) + + note = insert(:note, user: target_user) + + activity_params = %{ + "object" => note.data["id"], + "actor" => note.data["actor"], + "to" => note.data["to"] || [], + "cc" => note.data["cc"] || [], + "type" => "Create" + } + + {:ok, fake_activity} = + Repo.insert(%Activity{ + data: activity_params, + recipients: activity_params["to"] ++ activity_params["cc"], + local: true, + actor: activity_params["actor"] + }) + + assert %{"action_taken" => false, "id" => _} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/reports", %{ + "account_id" => target_user.id, + "status_ids" => [fake_activity.id], + "comment" => "bad status!", + "forward" => "false" + }) + |> json_response_and_validate_schema(200) + end + test "submit a report with statuses and comment", %{ conn: conn, target_user: target_user, diff --git a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs index 8753c7716..0a9240b70 100644 --- a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs @@ -37,6 +37,7 @@ test "it returns empty result if user or status search return undefined error", end end + @tag :skip_on_mac test "search", %{conn: conn} do user = insert(:user) user_two = insert(:user, %{nickname: "shp@shitposter.club"}) @@ -79,6 +80,51 @@ test "search", %{conn: conn} do assert status["id"] == to_string(activity.id) end + test "search local-only status as an authenticated user" do + user = insert(:user) + %{conn: conn} = oauth_access(["read:search"]) + + {:ok, activity} = + CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"}) + + results = + conn + |> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}") + |> json_response_and_validate_schema(200) + + [status] = results["statuses"] + assert status["id"] == to_string(activity.id) + end + + test "search local-only status as an unauthenticated user" do + user = insert(:user) + %{conn: conn} = oauth_access([]) + + {:ok, _activity} = + CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"}) + + results = + conn + |> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}") + |> json_response_and_validate_schema(200) + + assert [] = results["statuses"] + end + + test "search local-only status as an anonymous user" do + user = insert(:user) + + {:ok, _activity} = + CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"}) + + results = + build_conn() + |> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}") + |> json_response_and_validate_schema(200) + + assert [] = results["statuses"] + end + @tag capture_log: true test "constructs hashtags from search query", %{conn: conn} do results = 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 1d2bb3333..5bae2cd00 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do alias Pleroma.Activity alias Pleroma.Conversation.Participation + alias Pleroma.ModerationLog alias Pleroma.Object alias Pleroma.Repo alias Pleroma.ScheduledActivity @@ -262,6 +263,7 @@ test "posting a fake status", %{conn: conn} do |> Map.put("url", nil) |> Map.put("uri", nil) |> Map.put("created_at", nil) + |> Kernel.put_in(["pleroma", "context"], nil) |> Kernel.put_in(["pleroma", "conversation_id"], nil) fake_conn = @@ -285,6 +287,7 @@ test "posting a fake status", %{conn: conn} do |> Map.put("url", nil) |> Map.put("uri", nil) |> Map.put("created_at", nil) + |> Kernel.put_in(["pleroma", "context"], nil) |> Kernel.put_in(["pleroma", "conversation_id"], nil) assert real_status == fake_status @@ -971,16 +974,19 @@ test "when you didn't create it" do test "when you're privileged to", %{conn: conn} do clear_config([:instance, :moderator_privileges], [:messages_delete]) activity = insert(:note_activity) - moderator = insert(:user, is_moderator: true) + user = insert(:user, is_moderator: true) res_conn = conn - |> assign(:user, moderator) - |> assign(:token, insert(:oauth_token, user: moderator, scopes: ["write:statuses"])) + |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"])) |> delete("/api/v1/statuses/#{activity.id}") assert %{} = json_response_and_validate_schema(res_conn, 200) + assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() == + "@#{user.nickname} deleted status ##{activity.id}" + refute Activity.get_by_id(activity.id) end end @@ -1891,23 +1897,50 @@ test "expires_at is nil for another user" do |> json_response_and_validate_schema(:ok) end - test "posting a local only status" do - %{user: _user, conn: conn} = oauth_access(["write:statuses"]) + describe "local-only statuses" do + test "posting a local only status" do + %{user: _user, conn: conn} = oauth_access(["write:statuses"]) - conn_one = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/statuses", %{ - "status" => "cofe", - "visibility" => "local" - }) + conn_one = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ + "status" => "cofe", + "visibility" => "local" + }) - local = Utils.as_local_public() + local = Utils.as_local_public() - assert %{"content" => "cofe", "id" => id, "visibility" => "local"} = - json_response_and_validate_schema(conn_one, 200) + assert %{"content" => "cofe", "id" => id, "visibility" => "local"} = + json_response_and_validate_schema(conn_one, 200) - assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id) + assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id) + end + + test "other users can read local-only posts" do + user = insert(:user) + %{user: _reader, conn: conn} = oauth_access(["read:statuses"]) + + {:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"}) + + received = + conn + |> get("/api/v1/statuses/#{activity.id}") + |> json_response_and_validate_schema(:ok) + + assert received["id"] == activity.id + end + + test "anonymous users cannot see local-only posts" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"}) + + _received = + build_conn() + |> get("/api/v1/statuses/#{activity.id}") + |> json_response_and_validate_schema(:not_found) + end end describe "muted reactions" do @@ -1980,4 +2013,178 @@ test "show" do } = result end end + + describe "get status history" do + setup do + %{conn: build_conn()} + end + + test "unedited post", %{conn: conn} do + activity = insert(:note_activity) + + conn = get(conn, "/api/v1/statuses/#{activity.id}/history") + + assert [_] = json_response_and_validate_schema(conn, 200) + end + + test "edited post", %{conn: conn} do + note = + insert( + :note, + data: %{ + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "type" => "Note", + "content" => "mew mew 2", + "summary" => "title 2" + }, + %{ + "type" => "Note", + "content" => "mew mew 1", + "summary" => "title 1" + } + ], + "totalItems" => 2 + } + } + ) + + activity = insert(:note_activity, note: note) + + conn = get(conn, "/api/v1/statuses/#{activity.id}/history") + + assert [%{"spoiler_text" => "title 1"}, %{"spoiler_text" => "title 2"}, _] = + json_response_and_validate_schema(conn, 200) + end + end + + describe "get status source" do + setup do + %{conn: build_conn()} + end + + test "it returns the source", %{conn: conn} do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"}) + + conn = get(conn, "/api/v1/statuses/#{activity.id}/source") + + id = activity.id + + assert %{"id" => ^id, "text" => "mew mew #abc", "spoiler_text" => "#def"} = + json_response_and_validate_schema(conn, 200) + end + end + + describe "update status" do + setup do + oauth_access(["write:statuses"]) + end + + test "it updates the status" do + %{conn: conn, user: user} = oauth_access(["write:statuses", "read:statuses"]) + + {:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"}) + + conn + |> get("/api/v1/statuses/#{activity.id}") + |> json_response_and_validate_schema(200) + + response = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/statuses/#{activity.id}", %{ + "status" => "edited", + "spoiler_text" => "lol" + }) + |> json_response_and_validate_schema(200) + + assert response["content"] == "edited" + assert response["spoiler_text"] == "lol" + + response = + conn + |> get("/api/v1/statuses/#{activity.id}") + |> json_response_and_validate_schema(200) + + assert response["content"] == "edited" + assert response["spoiler_text"] == "lol" + end + + test "it updates the attachments", %{conn: conn, user: user} do + attachment = insert(:attachment, user: user) + attachment_id = to_string(attachment.id) + + {:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"}) + + response = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/statuses/#{activity.id}", %{ + "status" => "mew mew #abc", + "spoiler_text" => "#def", + "media_ids" => [attachment_id] + }) + |> json_response_and_validate_schema(200) + + assert [%{"id" => ^attachment_id}] = response["media_attachments"] + end + + test "it does not update visibility", %{conn: conn, user: user} do + {:ok, activity} = + CommonAPI.post(user, %{ + status: "mew mew #abc", + spoiler_text: "#def", + visibility: "private" + }) + + response = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/statuses/#{activity.id}", %{ + "status" => "edited", + "spoiler_text" => "lol" + }) + |> json_response_and_validate_schema(200) + + assert response["visibility"] == "private" + end + + test "it refuses to update when original post is not by the user", %{conn: conn} do + another_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(another_user, %{status: "mew mew #abc", spoiler_text: "#def"}) + + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/statuses/#{activity.id}", %{ + "status" => "edited", + "spoiler_text" => "lol" + }) + |> json_response_and_validate_schema(:forbidden) + end + + test "it returns 404 if the user cannot see the post", %{conn: conn} do + another_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(another_user, %{ + status: "mew mew #abc", + spoiler_text: "#def", + visibility: "private" + }) + + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/statuses/#{activity.id}", %{ + "status" => "edited", + "spoiler_text" => "lol" + }) + |> json_response_and_validate_schema(:not_found) + end + end end diff --git a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs index 2c7e78595..b13a8033b 100644 --- a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs @@ -367,6 +367,47 @@ test "muted emotions", %{conn: conn} do } ] = result end + + test "should return local-only posts for authenticated users" do + user = insert(:user) + %{user: _reader, conn: conn} = oauth_access(["read:statuses"]) + + {:ok, %{id: id}} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"}) + + result = + conn + |> get("/api/v1/timelines/public") + |> json_response_and_validate_schema(200) + + assert [%{"id" => ^id}] = result + end + + test "should not return local-only posts for users without read:statuses" do + user = insert(:user) + %{user: _reader, conn: conn} = oauth_access([]) + + {:ok, _activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"}) + + result = + conn + |> get("/api/v1/timelines/public") + |> json_response_and_validate_schema(200) + + assert [] = result + end + + test "should not return local-only posts for anonymous users" do + user = insert(:user) + + {:ok, _activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"}) + + result = + build_conn() + |> get("/api/v1/timelines/public") + |> json_response_and_validate_schema(200) + + assert [] = result + end end defp local_and_remote_activities do @@ -903,7 +944,7 @@ test "muted emotions", %{conn: conn} do end end - describe "hashtag timeline handling of :restrict_unauthenticated setting" do + describe "hashtag timeline handling of restrict_unauthenticated setting" do setup do user = insert(:user) {:ok, activity1} = CommonAPI.post(user, %{status: "test #tag1"}) diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index c2e4debc8..d5fac7e25 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -259,6 +259,34 @@ test "updates the user's avatar", %{user: user, conn: conn} do assert user.avatar == nil end + test "updates the user's avatar, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do + upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8 + + assert :ok == + File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>) + + new_avatar_oversized = %Plug.Upload{ + content_type: nil, + path: Path.absname("test/tmp/large_binary.data"), + filename: "large_binary.data" + } + + assert user.avatar == %{} + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar_oversized}) + + assert user_response = json_response_and_validate_schema(res, 413) + assert user_response["avatar"] != User.avatar_url(user) + + user = User.get_by_id(user.id) + assert user.avatar == %{} + + clear_config([:instance, :upload_limit], upload_limit) + + assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) + end + test "updates the user's banner", %{user: user, conn: conn} do new_header = %Plug.Upload{ content_type: "image/jpeg", @@ -278,6 +306,32 @@ test "updates the user's banner", %{user: user, conn: conn} do assert user.banner == nil end + test "updates the user's banner, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do + upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8 + + assert :ok == + File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>) + + new_header_oversized = %Plug.Upload{ + content_type: nil, + path: Path.absname("test/tmp/large_binary.data"), + filename: "large_binary.data" + } + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header_oversized}) + + assert user_response = json_response_and_validate_schema(res, 413) + assert user_response["header"] != User.banner_url(user) + + user = User.get_by_id(user.id) + assert user.banner == %{} + + clear_config([:instance, :upload_limit], upload_limit) + + assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) + end + test "updates the user's background", %{conn: conn, user: user} do new_header = %Plug.Upload{ content_type: "image/jpeg", @@ -301,6 +355,34 @@ test "updates the user's background", %{conn: conn, user: user} do assert user.background == nil end + test "updates the user's background, upload_limit, returns a HTTP 413", %{ + conn: conn, + user: user + } do + upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8 + + assert :ok == + File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>) + + new_background_oversized = %Plug.Upload{ + content_type: nil, + path: Path.absname("test/tmp/large_binary.data"), + filename: "large_binary.data" + } + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{ + "pleroma_background_image" => new_background_oversized + }) + + assert user_response = json_response_and_validate_schema(res, 413) + assert user.background == %{} + + clear_config([:instance, :upload_limit], upload_limit) + + assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) + end + test "requires 'write:accounts' permission" do token1 = insert(:oauth_token, scopes: ["read"]) token2 = insert(:oauth_token, scopes: ["write", "follow"]) @@ -390,6 +472,20 @@ test "updates the user's show_birthday status", %{conn: conn} do assert user_data["source"]["pleroma"]["show_birthday"] == true end + test "unsets birth date", %{conn: conn} do + patch(conn, "/api/v1/accounts/update_credentials", %{ + "birthday" => "2001-02-12" + }) + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{ + "birthday" => "" + }) + + assert user_data = json_response_and_validate_schema(res, 200) + assert user_data["pleroma"]["birthday"] == nil + end + test "emojis in fields labels", %{conn: conn} do fields = [ %{"name" => ":firefox:", "value" => "is best 2hu"}, diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs index 675c8409a..3bb4970ca 100644 --- a/test/pleroma/web/mastodon_api/views/account_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -779,4 +779,21 @@ test "uses mediaproxy urls when it's enabled (regardless of media preview proxy |> assert() end end + + test "renders mute expiration date" do + user = insert(:user) + other_user = insert(:user) + + {:ok, _user_relationships} = + User.mute(user, other_user, %{notifications: true, duration: 24 * 60 * 60}) + + %{ + mute_expires_at: mute_expires_at + } = AccountView.render("show.json", %{user: other_user, for: user, mutes: true}) + + assert DateTime.diff( + mute_expires_at, + DateTime.utc_now() |> DateTime.add(24 * 60 * 60) + ) in -3..3 + end end diff --git a/test/pleroma/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs index 594378be1..6ea894691 100644 --- a/test/pleroma/web/mastodon_api/views/notification_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/notification_view_test.exs @@ -239,6 +239,32 @@ test "Report notification" do test_notifications_rendering([notification], moderator_user, [expected]) end + test "Edit notification" do + user = insert(:user) + repeat_user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{status: "mew"}) + {:ok, _} = CommonAPI.repeat(activity.id, repeat_user) + {:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew"}) + + user = Pleroma.User.get_by_ap_id(user.ap_id) + activity = Pleroma.Activity.normalize(activity) + update = Pleroma.Activity.normalize(update) + + {:ok, [notification]} = Notification.create_notifications(update) + + expected = %{ + id: to_string(notification.id), + pleroma: %{is_seen: false, is_muted: false}, + type: "update", + account: AccountView.render("show.json", %{user: user, for: repeat_user}), + created_at: Utils.to_masto_date(notification.inserted_at), + status: StatusView.render("show.json", %{activity: activity, for: repeat_user}) + } + + test_notifications_rendering([notification], repeat_user, [expected]) + end + test "muted notification" do user = insert(:user) another_user = insert(:user) diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs index 5d81c92b9..f76b115b7 100644 --- a/test/pleroma/web/mastodon_api/views/status_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs @@ -14,10 +14,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do alias Pleroma.User alias Pleroma.UserRelationship alias Pleroma.Web.CommonAPI - alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.StatusView + require Bitwise + import Pleroma.Factory import Tesla.Mock import OpenApiSpex.TestAssertions @@ -226,7 +227,7 @@ test "a note activity" do object_data = Object.normalize(note, fetch: false).data user = User.get_cached_by_ap_id(note.data["actor"]) - convo_id = Utils.context_to_conversation_id(object_data["context"]) + convo_id = :erlang.crc32(object_data["context"]) |> Bitwise.band(Bitwise.bnot(0x8000_0000)) status = StatusView.render("show.json", %{activity: note}) @@ -246,6 +247,7 @@ test "a note activity" do content: HTML.filter_tags(object_data["content"]), text: nil, created_at: created_at, + edited_at: nil, reblogs_count: 0, replies_count: 0, favourites_count: 0, @@ -279,6 +281,7 @@ test "a note activity" do pleroma: %{ local: true, conversation_id: convo_id, + context: object_data["context"], in_reply_to_account_acct: nil, content: %{"text/plain" => HTML.strip_tags(object_data["content"])}, spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])}, @@ -708,4 +711,55 @@ test "has a field for parent visibility" do status = StatusView.render("show.json", activity: visible, for: poster) assert status.pleroma.parent_visible end + + test "it shows edited_at" do + poster = insert(:user) + + {:ok, post} = CommonAPI.post(poster, %{status: "hey"}) + + status = StatusView.render("show.json", activity: post) + refute status.edited_at + + {:ok, _} = CommonAPI.update(poster, post, %{status: "mew mew"}) + edited = Pleroma.Activity.normalize(post) + + status = StatusView.render("show.json", activity: edited) + assert status.edited_at + end + + test "with a source object" do + note = + insert(:note, + data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}} + ) + + activity = insert(:note_activity, note: note) + + status = StatusView.render("show.json", activity: activity, with_source: true) + assert status.text == "object source" + end + + describe "source.json" do + test "with a source object, renders both source and content type" do + note = + insert(:note, + data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}} + ) + + activity = insert(:note_activity, note: note) + + status = StatusView.render("source.json", activity: activity) + assert status.text == "object source" + assert status.content_type == "text/markdown" + end + + test "with a source string, renders source and put text/plain as the content type" do + note = insert(:note, data: %{"source" => "string source"}) + activity = insert(:note_activity, note: note) + + status = StatusView.render("source.json", activity: activity) + assert status.text == "string source" + assert status.content_type == "text/plain" + end + end end diff --git a/test/pleroma/web/media_proxy/invalidation/script_test.exs b/test/pleroma/web/media_proxy/invalidation/script_test.exs index 39ef365f4..3e8fd751d 100644 --- a/test/pleroma/web/media_proxy/invalidation/script_test.exs +++ b/test/pleroma/web/media_proxy/invalidation/script_test.exs @@ -10,11 +10,14 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do test "it logs error when script is not found" do assert capture_log(fn -> - assert Invalidation.Script.purge( - ["http://example.com/media/example.jpg"], - script_path: "./example" - ) == {:error, "%ErlangError{original: :enoent}"} - end) =~ "Error while cache purge: %ErlangError{original: :enoent}" + assert {:error, msg} = + Invalidation.Script.purge( + ["http://example.com/media/example.jpg"], + script_path: "./example" + ) + + assert msg =~ ~r/%ErlangError{original: :enoent(, reason: nil)?}/ + end) =~ ~r/Error while cache purge: %ErlangError{original: :enoent(, reason: nil)?}/ capture_log(fn -> assert Invalidation.Script.purge( diff --git a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs index 5ace2eee9..5246bf0c4 100644 --- a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs +++ b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs @@ -158,7 +158,7 @@ test "responds with 424 Failed Dependency if HEAD request to media proxy fails", media_proxy_url: media_proxy_url } do Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 500, body: ""} end) @@ -173,7 +173,7 @@ test "redirects to media proxy URI on unsupported content type", %{ media_proxy_url: media_proxy_url } do Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]} end) @@ -193,7 +193,7 @@ test "with `static=true` and GIF image preview requested, responds with JPEG ima clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000) Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{ status: 200, body: "", @@ -218,7 +218,7 @@ test "with GIF image preview requested and no `static` param, redirects to media media_proxy_url: media_proxy_url } do Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]} end) @@ -236,7 +236,7 @@ test "with `static` param and non-GIF image preview requested, " <> media_proxy_url: media_proxy_url } do Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]} end) @@ -256,7 +256,7 @@ test "with :min_content_length setting not matched by Content-Length header, " < clear_config([:media_preview_proxy, :min_content_length], 100_000) Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{ status: 200, body: "", @@ -278,7 +278,7 @@ test "thumbnails PNG images into PNG", %{ assert_dependencies_installed() Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]} %{method: :get, url: ^media_proxy_url} -> @@ -300,7 +300,7 @@ test "thumbnails JPEG images into JPEG", %{ assert_dependencies_installed() Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]} %{method: :get, url: ^media_proxy_url} -> @@ -320,7 +320,7 @@ test "redirects to media proxy URI in case of thumbnailing error", %{ media_proxy_url: media_proxy_url } do Tesla.Mock.mock(fn - %{method: "head", url: ^media_proxy_url} -> + %{method: "HEAD", url: ^media_proxy_url} -> %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]} %{method: :get, url: ^media_proxy_url} -> diff --git a/test/pleroma/web/metadata/providers/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs index 392496993..1a0cea9ce 100644 --- a/test/pleroma/web/metadata/providers/twitter_card_test.exs +++ b/test/pleroma/web/metadata/providers/twitter_card_test.exs @@ -39,6 +39,7 @@ test "it uses summary twittercard if post has no attachment" do "actor" => user.ap_id, "tag" => [], "id" => "https://pleroma.gov/objects/whatever", + "summary" => "", "content" => "pleroma in a nutshell" } }) @@ -54,6 +55,36 @@ test "it uses summary twittercard if post has no attachment" do ] == result end + test "it uses summary as description if post has one" do + user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994") + {:ok, activity} = CommonAPI.post(user, %{status: "HI"}) + + note = + insert(:note, %{ + data: %{ + "actor" => user.ap_id, + "tag" => [], + "id" => "https://pleroma.gov/objects/whatever", + "summary" => "Public service announcement on caffeine consumption", + "content" => "cofe" + } + }) + + result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id}) + + assert [ + {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, + [ + property: "twitter:description", + content: "Public service announcement on caffeine consumption" + ], []}, + {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"], + []}, + {:meta, [property: "twitter:card", content: "summary"], []} + ] == result + end + test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabled" do clear_config([Pleroma.Web.Metadata, :unfurl_nsfw], false) user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994") @@ -65,6 +96,7 @@ test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabl "actor" => user.ap_id, "tag" => [], "id" => "https://pleroma.gov/objects/whatever", + "summary" => "", "content" => "pleroma in a nutshell", "sensitive" => true, "attachment" => [ @@ -109,6 +141,7 @@ test "it renders supported types of attachments and skips unknown types" do "actor" => user.ap_id, "tag" => [], "id" => "https://pleroma.gov/objects/whatever", + "summary" => "", "content" => "pleroma in a nutshell", "attachment" => [ %{ diff --git a/test/pleroma/web/metadata/utils_test.exs b/test/pleroma/web/metadata/utils_test.exs index ce8ed5683..85ef6033a 100644 --- a/test/pleroma/web/metadata/utils_test.exs +++ b/test/pleroma/web/metadata/utils_test.exs @@ -3,12 +3,12 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.Metadata.UtilsTest do - use Pleroma.DataCase, async: true + use Pleroma.DataCase, async: false import Pleroma.Factory alias Pleroma.Web.Metadata.Utils describe "scrub_html_and_truncate/1" do - test "it returns text without encode HTML" do + test "it returns content text without encode HTML if summary is nil" do user = insert(:user) note = @@ -16,12 +16,60 @@ test "it returns text without encode HTML" do data: %{ "actor" => user.ap_id, "id" => "https://pleroma.gov/objects/whatever", + "summary" => nil, "content" => "Pleroma's really cool!" } }) assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!" end + + test "it returns context text without encode HTML if summary is empty" do + user = insert(:user) + + note = + insert(:note, %{ + data: %{ + "actor" => user.ap_id, + "id" => "https://pleroma.gov/objects/whatever", + "summary" => "", + "content" => "Pleroma's really cool!" + } + }) + + assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!" + end + + test "it returns summary text without encode HTML if summary is filled" do + user = insert(:user) + + note = + insert(:note, %{ + data: %{ + "actor" => user.ap_id, + "id" => "https://pleroma.gov/objects/whatever", + "summary" => "Public service announcement on caffeine consumption", + "content" => "cofe" + } + }) + + assert Utils.scrub_html_and_truncate(note) == + "Public service announcement on caffeine consumption" + end + + test "it does not return old content after editing" do + user = insert(:user) + + {:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew #def"}) + + object = Pleroma.Object.normalize(activity) + assert Utils.scrub_html_and_truncate(object) == "mew mew #def" + + {:ok, update} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "mew mew #abc"}) + update = Pleroma.Activity.normalize(update) + object = Pleroma.Object.normalize(update) + assert Utils.scrub_html_and_truncate(object) == "mew mew #abc" + end end describe "scrub_html_and_truncate/2" do diff --git a/test/pleroma/web/o_status/o_status_controller_test.exs b/test/pleroma/web/o_status/o_status_controller_test.exs index 5abbcfbdc..36e581f5e 100644 --- a/test/pleroma/web/o_status/o_status_controller_test.exs +++ b/test/pleroma/web/o_status/o_status_controller_test.exs @@ -343,54 +343,4 @@ test "does not require authentication on non-federating instances", %{ |> response(200) end end - - describe "notice compatibility routes" do - test "Soapbox FE", %{conn: conn} do - user = insert(:user) - note_activity = insert(:note_activity, user: user) - - resp = - conn - |> put_req_header("accept", "text/html") - |> get("/@#{user.nickname}/posts/#{note_activity.id}") - |> response(200) - - expected = - "" - - assert resp =~ expected - end - - test "Mastodon", %{conn: conn} do - user = insert(:user) - note_activity = insert(:note_activity, user: user) - - resp = - conn - |> put_req_header("accept", "text/html") - |> get("/@#{user.nickname}/#{note_activity.id}") - |> response(200) - - expected = - "" - - assert resp =~ expected - end - - test "Twitter", %{conn: conn} do - user = insert(:user) - note_activity = insert(:note_activity, user: user) - - resp = - conn - |> put_req_header("accept", "text/html") - |> get("/#{user.nickname}/status/#{note_activity.id}") - |> response(200) - - expected = - "" - - assert resp =~ expected - end - end end diff --git a/test/pleroma/web/pleroma_api/controllers/backup_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/backup_controller_test.exs index 650f3d80d..a758925b7 100644 --- a/test/pleroma/web/pleroma_api/controllers/backup_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/backup_controller_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do setup do clear_config([Pleroma.Upload, :uploader]) clear_config([Backup, :limit_days]) - oauth_access(["read:accounts"]) + oauth_access(["read:backups"]) end test "GET /api/v1/pleroma/backups", %{user: user, conn: conn} do @@ -82,4 +82,24 @@ test "POST /api/v1/pleroma/backups", %{user: _user, conn: conn} do |> post("/api/v1/pleroma/backups") |> json_response_and_validate_schema(400) end + + test "Backup without email address" do + user = Pleroma.Factory.insert(:user, email: nil) + %{conn: conn} = oauth_access(["read:backups"], user: user) + + assert is_nil(user.email) + + assert [ + %{ + "content_type" => "application/zip", + "url" => _url, + "file_size" => 0, + "processed" => false, + "inserted_at" => _ + } + ] = + conn + |> post("/api/v1/pleroma/backups") + |> json_response_and_validate_schema(:ok) + end end diff --git a/test/pleroma/web/pleroma_api/controllers/settings_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/settings_controller_test.exs new file mode 100644 index 000000000..e3c752d53 --- /dev/null +++ b/test/pleroma/web/pleroma_api/controllers/settings_controller_test.exs @@ -0,0 +1,126 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.SettingsControllerTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + + describe "GET /api/v1/pleroma/settings/:app" do + setup do + oauth_access(["read:accounts"]) + end + + test "it gets empty settings", %{conn: conn} do + response = + conn + |> get("/api/v1/pleroma/settings/pleroma-fe") + |> json_response_and_validate_schema(:ok) + + assert response == %{} + end + + test "it gets settings", %{conn: conn, user: user} do + response = + conn + |> assign( + :user, + struct(user, + pleroma_settings_store: %{ + "pleroma-fe" => %{ + "foo" => "bar" + } + } + ) + ) + |> get("/api/v1/pleroma/settings/pleroma-fe") + |> json_response_and_validate_schema(:ok) + + assert %{"foo" => "bar"} == response + end + end + + describe "POST /api/v1/pleroma/settings/:app" do + setup do + settings = %{ + "foo" => "bar", + "nested" => %{ + "1" => "2" + } + } + + user = + insert( + :user, + %{ + pleroma_settings_store: %{ + "pleroma-fe" => settings + } + } + ) + + %{conn: conn} = oauth_access(["write:accounts"], user: user) + + %{conn: conn, user: user, settings: settings} + end + + test "it adds keys", %{conn: conn} do + response = + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/v1/pleroma/settings/pleroma-fe", %{ + "foo" => "edited", + "bar" => "new", + "nested" => %{"3" => "4"} + }) + |> json_response_and_validate_schema(:ok) + + assert response == %{ + "foo" => "edited", + "bar" => "new", + "nested" => %{ + "1" => "2", + "3" => "4" + } + } + end + + test "it removes keys", %{conn: conn} do + response = + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/v1/pleroma/settings/pleroma-fe", %{ + "foo" => nil, + "bar" => nil, + "nested" => %{ + "1" => nil, + "3" => nil + } + }) + |> json_response_and_validate_schema(:ok) + + assert response == %{ + "nested" => %{} + } + end + + test "it does not override settings for other apps", %{ + conn: conn, + user: user, + settings: settings + } do + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/v1/pleroma/settings/admin-fe", %{"foo" => "bar"}) + |> json_response_and_validate_schema(:ok) + + user = Pleroma.User.get_by_id(user.id) + + assert user.pleroma_settings_store == %{ + "pleroma-fe" => settings, + "admin-fe" => %{"foo" => "bar"} + } + end + end +end diff --git a/test/pleroma/web/plugs/frontend_static_plug_test.exs b/test/pleroma/web/plugs/frontend_static_plug_test.exs index a91e24c49..ab31c5f22 100644 --- a/test/pleroma/web/plugs/frontend_static_plug_test.exs +++ b/test/pleroma/web/plugs/frontend_static_plug_test.exs @@ -86,8 +86,6 @@ test "api routes are detected correctly" do "objects", "activities", "notice", - "@:nickname", - ":nickname", "users", "tags", "mailer", diff --git a/test/pleroma/web/plugs/http_security_plug_test.exs b/test/pleroma/web/plugs/http_security_plug_test.exs index e1e97c1ce..c79170382 100644 --- a/test/pleroma/web/plugs/http_security_plug_test.exs +++ b/test/pleroma/web/plugs/http_security_plug_test.exs @@ -59,9 +59,9 @@ test "it sends `report-to` & `report-uri` CSP response headers", %{conn: conn} d assert csp =~ ~r|report-uri https://endpoint.com;report-to csp-endpoint;| - [reply_to] = Conn.get_resp_header(conn, "reply-to") + [report_to] = Conn.get_resp_header(conn, "report-to") - assert reply_to == + assert report_to == "{\"endpoints\":[{\"url\":\"https://endpoint.com\"}],\"group\":\"csp-endpoint\",\"max-age\":10886400}" end diff --git a/test/pleroma/web/plugs/rate_limiter_test.exs b/test/pleroma/web/plugs/rate_limiter_test.exs index b1ac76120..19cee8aee 100644 --- a/test/pleroma/web/plugs/rate_limiter_test.exs +++ b/test/pleroma/web/plugs/rate_limiter_test.exs @@ -48,38 +48,42 @@ test "it is enabled if remote_ip_found flag doesn't exist" do refute RateLimiter.disabled?(build_conn()) end - @tag :erratic test "it restricts based on config values" do limiter_name = :test_plug_opts scale = 80 limit = 5 - clear_config([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8}) + clear_config([Pleroma.Web.Endpoint, :http, :ip], {127, 0, 0, 1}) clear_config([:rate_limit, limiter_name], {scale, limit}) plug_opts = RateLimiter.init(name: limiter_name) conn = build_conn(:get, "/") - for i <- 1..5 do - conn = RateLimiter.call(conn, plug_opts) - assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts) - Process.sleep(10) + for _ <- 1..5 do + conn_limited = RateLimiter.call(conn, plug_opts) + + refute conn_limited.status == Conn.Status.code(:too_many_requests) + refute conn_limited.resp_body + refute conn_limited.halted end - conn = RateLimiter.call(conn, plug_opts) - assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests) - assert conn.halted + conn_limited = RateLimiter.call(conn, plug_opts) + assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests) + assert conn_limited.halted - Process.sleep(50) + expire_ttl(conn, limiter_name) - conn = build_conn(:get, "/") + for _ <- 1..5 do + conn_limited = RateLimiter.call(conn, plug_opts) - conn = RateLimiter.call(conn, plug_opts) - assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts) + refute conn_limited.status == Conn.Status.code(:too_many_requests) + refute conn_limited.resp_body + refute conn_limited.halted + end - refute conn.status == Conn.Status.code(:too_many_requests) - refute conn.resp_body - refute conn.halted + conn_limited = RateLimiter.call(conn, plug_opts) + assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests) + assert conn_limited.halted end describe "options" do @@ -263,4 +267,12 @@ test "doesn't crash due to a race condition when multiple requests are made at t refute {:err, :not_found} == RateLimiter.inspect_bucket(conn, limiter_name, opts) end + + def expire_ttl(%{remote_ip: remote_ip} = _conn, bucket_name_root) do + bucket_name = "anon:#{bucket_name_root}" |> String.to_atom() + key_name = "ip::#{remote_ip |> Tuple.to_list() |> Enum.join(".")}" + + {:ok, bucket_value} = Cachex.get(bucket_name, key_name) + Cachex.put(bucket_name, key_name, bucket_value, ttl: -1) + end end diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs index b8112cce5..2eee0acd9 100644 --- a/test/pleroma/web/push/impl_test.exs +++ b/test/pleroma/web/push/impl_test.exs @@ -202,6 +202,21 @@ test "renders title and body for pleroma:emoji_reaction activity" do "New Reaction" end + test "renders title and body for update activity" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{status: "lorem ipsum"}) + + {:ok, activity} = CommonAPI.update(user, activity, %{status: "edited status"}) + object = Object.normalize(activity, fetch: false) + + assert Impl.format_body(%{activity: activity, type: "update"}, user, object) == + "@#{user.nickname} edited a status" + + assert Impl.format_title(%{activity: activity, type: "update"}) == + "New Update" + end + test "renders title for create activity with direct visibility" do user = insert(:user, nickname: "Bob") diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs index 4d4fed070..8b0c84164 100644 --- a/test/pleroma/web/streamer_test.exs +++ b/test/pleroma/web/streamer_test.exs @@ -442,6 +442,31 @@ test "it sends follow relationships updates to the 'user' stream", %{ "state" => "follow_accept" } = Jason.decode!(payload) end + + test "it streams edits in the 'user' stream", %{user: user, token: oauth_token} do + sender = insert(:user) + {:ok, _, _, _} = CommonAPI.follow(user, sender) + + {:ok, activity} = CommonAPI.post(sender, %{status: "hey"}) + + Streamer.get_topic_and_add_socket("user", user, oauth_token) + {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"}) + create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"]) + + assert_receive {:render_with_user, _, "status_update.json", ^create} + refute Streamer.filtered_by_user?(user, edited) + end + + test "it streams own edits in the 'user' stream", %{user: user, token: oauth_token} do + {:ok, activity} = CommonAPI.post(user, %{status: "hey"}) + + Streamer.get_topic_and_add_socket("user", user, oauth_token) + {:ok, edited} = CommonAPI.update(user, activity, %{status: "mew mew"}) + create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"]) + + assert_receive {:render_with_user, _, "status_update.json", ^create} + refute Streamer.filtered_by_user?(user, edited) + end end describe "public streams" do @@ -484,6 +509,54 @@ test "handles deletions" do assert_receive {:text, event} assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event) end + + test "it streams edits in the 'public' stream" do + sender = insert(:user) + + Streamer.get_topic_and_add_socket("public", nil, nil) + {:ok, activity} = CommonAPI.post(sender, %{status: "hey"}) + assert_receive {:text, _} + + {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"}) + + edited = Pleroma.Activity.normalize(edited) + + %{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"]) + + assert_receive {:text, event} + assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event) + assert %{"id" => ^activity_id} = Jason.decode!(payload) + refute Streamer.filtered_by_user?(sender, edited) + end + + test "it streams multiple edits in the 'public' stream correctly" do + sender = insert(:user) + + Streamer.get_topic_and_add_socket("public", nil, nil) + {:ok, activity} = CommonAPI.post(sender, %{status: "hey"}) + assert_receive {:text, _} + + {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"}) + + edited = Pleroma.Activity.normalize(edited) + + %{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"]) + + assert_receive {:text, event} + assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event) + assert %{"id" => ^activity_id} = Jason.decode!(payload) + refute Streamer.filtered_by_user?(sender, edited) + + {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew 2"}) + + edited = Pleroma.Activity.normalize(edited) + + %{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"]) + assert_receive {:text, event} + assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event) + assert %{"id" => ^activity_id, "content" => "mew mew 2"} = Jason.decode!(payload) + refute Streamer.filtered_by_user?(sender, edited) + end end describe "thread_containment/2" do @@ -814,4 +887,105 @@ test "it sends conversation update to the 'direct' stream when a message is dele assert last_status["id"] == to_string(create_activity.id) end end + + describe "stop streaming if token got revoked" do + setup do + child_proc = fn start, finalize -> + fn -> + start.() + + receive do + {StreamerTest, :ready} -> + assert_receive {:render_with_user, _, "update.json", _} + + receive do + {StreamerTest, :revoked} -> finalize.() + end + end + end + end + + starter = fn user, token -> + fn -> Streamer.get_topic_and_add_socket("user", user, token) end + end + + hit = fn -> assert_receive :close end + miss = fn -> refute_receive :close end + + send_all = fn tasks, thing -> Enum.each(tasks, &send(&1.pid, thing)) end + + %{ + child_proc: child_proc, + starter: starter, + hit: hit, + miss: miss, + send_all: send_all + } + end + + test "do not revoke other tokens", %{ + child_proc: child_proc, + starter: starter, + hit: hit, + miss: miss, + send_all: send_all + } do + %{user: user, token: token} = oauth_access(["read"]) + %{token: token2} = oauth_access(["read"], user: user) + %{user: user2, token: user2_token} = oauth_access(["read"]) + + post_user = insert(:user) + CommonAPI.follow(user, post_user) + CommonAPI.follow(user2, post_user) + + tasks = [ + Task.async(child_proc.(starter.(user, token), hit)), + Task.async(child_proc.(starter.(user, token2), miss)), + Task.async(child_proc.(starter.(user2, user2_token), miss)) + ] + + {:ok, _} = + CommonAPI.post(post_user, %{ + status: "hi" + }) + + send_all.(tasks, {StreamerTest, :ready}) + + Pleroma.Web.OAuth.Token.Strategy.Revoke.revoke(token) + + send_all.(tasks, {StreamerTest, :revoked}) + + Enum.each(tasks, &Task.await/1) + end + + test "revoke all streams for this token", %{ + child_proc: child_proc, + starter: starter, + hit: hit, + send_all: send_all + } do + %{user: user, token: token} = oauth_access(["read"]) + + post_user = insert(:user) + CommonAPI.follow(user, post_user) + + tasks = [ + Task.async(child_proc.(starter.(user, token), hit)), + Task.async(child_proc.(starter.(user, token), hit)) + ] + + {:ok, _} = + CommonAPI.post(post_user, %{ + status: "hi" + }) + + send_all.(tasks, {StreamerTest, :ready}) + + Pleroma.Web.OAuth.Token.Strategy.Revoke.revoke(token) + + send_all.(tasks, {StreamerTest, :revoked}) + + Enum.each(tasks, &Task.await/1) + end + end end diff --git a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs index 2b57a42a4..1194e0afe 100644 --- a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs +++ b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: true alias Pleroma.MFA alias Pleroma.MFA.TOTP diff --git a/test/pleroma/web/twitter_api/util_controller_test.exs b/test/pleroma/web/twitter_api/util_controller_test.exs index c795fd501..a4da23635 100644 --- a/test/pleroma/web/twitter_api/util_controller_test.exs +++ b/test/pleroma/web/twitter_api/util_controller_test.exs @@ -233,6 +233,102 @@ test "it renders form with error when user not found", %{conn: conn} do end end + describe "POST /main/ostatus - remote_subscribe/2 - with statuses" do + setup do: clear_config([:instance, :federating], true) + + test "renders subscribe form", %{conn: conn} do + user = insert(:user) + status = insert(:note_activity, %{user: user}) + status_id = status.id + + assert is_binary(status_id) + + response = + conn + |> post("/main/ostatus", %{"status_id" => status_id, "profile" => ""}) + |> response(:ok) + + refute response =~ "Could not find status" + assert response =~ "Interacting with" + end + + test "renders subscribe form with error when status not found", %{conn: conn} do + response = + conn + |> post("/main/ostatus", %{"status_id" => "somerandomid", "profile" => ""}) + |> response(:ok) + + assert response =~ "Could not find status" + refute response =~ "Interacting with" + end + + test "it redirect to webfinger url", %{conn: conn} do + user = insert(:user) + status = insert(:note_activity, %{user: user}) + status_id = status.id + status_ap_id = status.data["object"] + + assert is_binary(status_id) + assert is_binary(status_ap_id) + + user2 = insert(:user, ap_id: "shp@social.heldscal.la") + + conn = + conn + |> post("/main/ostatus", %{ + "status" => %{"status_id" => status_id, "profile" => user2.ap_id} + }) + + assert redirected_to(conn) == + "https://social.heldscal.la/main/ostatussub?profile=#{status_ap_id}" + end + + test "it renders form with error when status not found", %{conn: conn} do + user2 = insert(:user, ap_id: "shp@social.heldscal.la") + + response = + conn + |> post("/main/ostatus", %{ + "status" => %{"status_id" => "somerandomid", "profile" => user2.ap_id} + }) + |> response(:ok) + + assert response =~ "Something went wrong." + end + end + + describe "GET /main/ostatus - show_subscribe_form/2" do + setup do: clear_config([:instance, :federating], true) + + test "it works with users", %{conn: conn} do + user = insert(:user) + + response = + conn + |> get("/main/ostatus", %{"nickname" => user.nickname}) + |> response(:ok) + + refute response =~ "Could not find user" + assert response =~ "Remotely follow #{user.nickname}" + end + + test "it works with statuses", %{conn: conn} do + user = insert(:user) + status = insert(:note_activity, %{user: user}) + status_id = status.id + + assert is_binary(status_id) + + response = + conn + |> get("/main/ostatus", %{"status_id" => status_id}) + |> response(:ok) + + refute response =~ "Could not find status" + assert response =~ "Interacting with" + end + end + test "it returns new captcha", %{conn: conn} do with_mock Pleroma.Captcha, new: fn -> "test_captcha" end do @@ -516,4 +612,371 @@ test "with proper permissions and valid password (JSON body)", %{conn: conn, use assert user.password_hash == nil end end + + describe "POST /api/pleroma/move_account" do + setup do: oauth_access(["write:accounts"]) + + test "without permissions", %{conn: conn} do + target_user = insert(:user) + target_nick = target_user |> User.full_nickname() + + conn = + conn + |> assign(:token, nil) + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "hi", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 403) == %{ + "error" => "Insufficient permissions: write:accounts." + } + end + + test "with proper permissions and invalid password", %{conn: conn} do + target_user = insert(:user) + target_nick = target_user |> User.full_nickname() + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "hi", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."} + end + + test "with proper permissions, valid password and target account does not alias it", + %{ + conn: conn + } do + target_user = insert(:user) + target_nick = target_user |> User.full_nickname() + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "test", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 200) == %{ + "error" => "Target account must have the origin in `alsoKnownAs`" + } + end + + test "with proper permissions, valid password and target account does not exist", + %{ + conn: conn + } do + target_nick = "not_found@mastodon.social" + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "test", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 404) == %{ + "error" => "Target account not found." + } + end + + test "with proper permissions, valid password, remote target account aliases it and local cache does not exist", + %{} do + user = insert(:user, ap_id: "https://lm.kazv.moe/users/testuser") + %{user: _user, conn: conn} = oauth_access(["write:accounts"], user: user) + + target_nick = "mewmew@lm.kazv.moe" + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "test", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} + end + + test "with proper permissions, valid password, remote target account aliases it and local cache does not aliases it", + %{} do + user = insert(:user, ap_id: "https://lm.kazv.moe/users/testuser") + %{user: _user, conn: conn} = oauth_access(["write:accounts"], user: user) + + target_user = + insert( + :user, + ap_id: "https://lm.kazv.moe/users/mewmew", + nickname: "mewmew@lm.kazv.moe", + local: false + ) + + target_nick = target_user |> User.full_nickname() + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "test", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} + end + + test "with proper permissions, valid password, remote target account does not aliases it and local cache aliases it", + %{ + user: user, + conn: conn + } do + target_user = + insert( + :user, + ap_id: "https://lm.kazv.moe/users/mewmew", + nickname: "mewmew@lm.kazv.moe", + local: false, + also_known_as: [user.ap_id] + ) + + target_nick = target_user |> User.full_nickname() + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/move_account", %{ + "password" => "test", + "target_account" => target_nick + }) + + assert json_response_and_validate_schema(conn, 200) == %{ + "error" => "Target account must have the origin in `alsoKnownAs`" + } + end + + test "with proper permissions, valid password and target account aliases it", %{ + conn: conn, + user: user + } do + target_user = insert(:user, also_known_as: [user.ap_id]) + target_nick = target_user |> User.full_nickname() + follower = insert(:user) + + User.follow(follower, user) + + assert User.following?(follower, user) + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post( + "/api/pleroma/move_account", + %{ + password: "test", + target_account: target_nick + } + ) + + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} + + params = %{ + "op" => "move_following", + "origin_id" => user.id, + "target_id" => target_user.id + } + + assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params) + + Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params}) + + refute User.following?(follower, user) + assert User.following?(follower, target_user) + end + + test "prefix nickname by @ should work", %{ + conn: conn, + user: user + } do + target_user = insert(:user, also_known_as: [user.ap_id]) + target_nick = target_user |> User.full_nickname() + follower = insert(:user) + + User.follow(follower, user) + + assert User.following?(follower, user) + + conn = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post( + "/api/pleroma/move_account", + %{ + password: "test", + target_account: "@" <> target_nick + } + ) + + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} + + params = %{ + "op" => "move_following", + "origin_id" => user.id, + "target_id" => target_user.id + } + + assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params) + + Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params}) + + refute User.following?(follower, user) + assert User.following?(follower, target_user) + end + end + + describe "GET /api/pleroma/aliases" do + setup do: oauth_access(["read:accounts"]) + + test "without permissions", %{conn: conn} do + conn = + conn + |> assign(:token, nil) + |> get("/api/pleroma/aliases") + + assert json_response_and_validate_schema(conn, 403) == %{ + "error" => "Insufficient permissions: read:accounts." + } + end + + test "with permissions", %{ + conn: conn + } do + assert %{"aliases" => []} = + conn + |> get("/api/pleroma/aliases") + |> json_response_and_validate_schema(200) + end + + test "with permissions and aliases", %{} do + user = insert(:user) + user2 = insert(:user) + + assert {:ok, user} = user |> User.add_alias(user2) + + %{user: _user, conn: conn} = oauth_access(["read:accounts"], user: user) + + assert %{"aliases" => aliases} = + conn + |> get("/api/pleroma/aliases") + |> json_response_and_validate_schema(200) + + assert aliases == [user2 |> User.full_nickname()] + end + end + + describe "PUT /api/pleroma/aliases" do + setup do: oauth_access(["write:accounts"]) + + test "without permissions", %{conn: conn} do + conn = + conn + |> assign(:token, nil) + |> put_req_header("content-type", "application/json") + |> put("/api/pleroma/aliases", %{alias: "none"}) + + assert json_response_and_validate_schema(conn, 403) == %{ + "error" => "Insufficient permissions: write:accounts." + } + end + + test "with permissions, no alias param", %{ + conn: conn + } do + conn = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/pleroma/aliases", %{}) + + assert %{"error" => "Missing field: alias."} = json_response_and_validate_schema(conn, 400) + end + + test "with permissions, with alias param", %{ + conn: conn + } do + user2 = insert(:user) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/pleroma/aliases", %{alias: user2 |> User.full_nickname()}) + + assert json_response_and_validate_schema(conn, 200) == %{ + "status" => "success" + } + end + end + + describe "DELETE /api/pleroma/aliases" do + setup do + alias_user = insert(:user) + non_alias_user = insert(:user) + user = insert(:user, also_known_as: [alias_user.ap_id]) + + oauth_access(["write:accounts"], user: user) + |> Map.put(:alias_user, alias_user) + |> Map.put(:non_alias_user, non_alias_user) + end + + test "without permissions", %{conn: conn} do + conn = + conn + |> assign(:token, nil) + |> put_req_header("content-type", "application/json") + |> delete("/api/pleroma/aliases", %{alias: "none"}) + + assert json_response_and_validate_schema(conn, 403) == %{ + "error" => "Insufficient permissions: write:accounts." + } + end + + test "with permissions, no alias param", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/pleroma/aliases", %{}) + + assert %{"error" => "Missing field: alias."} = json_response_and_validate_schema(conn, 400) + end + + test "with permissions, account does not have such alias", %{ + conn: conn, + non_alias_user: non_alias_user + } do + conn = + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/pleroma/aliases", %{alias: non_alias_user |> User.full_nickname()}) + + assert %{"error" => "Account has no such alias."} = + json_response_and_validate_schema(conn, 404) + end + + test "with permissions, account does have such alias", %{ + conn: conn, + alias_user: alias_user + } do + conn = + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/pleroma/aliases", %{alias: alias_user |> User.full_nickname()}) + + assert %{"status" => "success"} = json_response_and_validate_schema(conn, 200) + end + end end diff --git a/test/pleroma/web/web_finger/web_finger_controller_test.exs b/test/pleroma/web/web_finger/web_finger_controller_test.exs index b5be28e67..5e3ac26f9 100644 --- a/test/pleroma/web/web_finger/web_finger_controller_test.exs +++ b/test/pleroma/web/web_finger/web_finger_controller_test.exs @@ -48,6 +48,35 @@ test "Webfinger JRD" do ] end + test "reach user on tld, while pleroma is runned on subdomain" do + Pleroma.Web.Endpoint.config_change( + [{Pleroma.Web.Endpoint, url: [host: "sub.example.com"]}], + [] + ) + + clear_config([Pleroma.Web.Endpoint, :url, :host], "sub.example.com") + + clear_config([Pleroma.Web.WebFinger, :domain], "example.com") + + user = insert(:user, ap_id: "https://sub.example.com/users/bobby", nickname: "bobby") + + response = + build_conn() + |> put_req_header("accept", "application/jrd+json") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@example.com") + |> json_response(200) + + assert response["subject"] == "acct:#{user.nickname}@example.com" + assert response["aliases"] == ["https://sub.example.com/users/#{user.nickname}"] + + on_exit(fn -> + Pleroma.Web.Endpoint.config_change( + [{Pleroma.Web.Endpoint, url: [host: "localhost"]}], + [] + ) + end) + end + test "it returns 404 when user isn't found (JSON)" do result = build_conn() diff --git a/test/pleroma/web/web_finger_test.exs b/test/pleroma/web/web_finger_test.exs index 1cc6ae675..fafef54fe 100644 --- a/test/pleroma/web/web_finger_test.exs +++ b/test/pleroma/web/web_finger_test.exs @@ -47,7 +47,7 @@ test "returns error for nonsensical input" do test "returns error when there is no content-type header" do Tesla.Mock.mock(fn - %{url: "http://social.heldscal.la/.well-known/host-meta"} -> + %{url: "https://social.heldscal.la/.well-known/host-meta"} -> {:ok, %Tesla.Env{ status: 200, @@ -120,7 +120,7 @@ test "it gets the xrd endpoint for hubzilla" do test "it gets the xrd endpoint for statusnet" do {:ok, template} = WebFinger.find_lrdd_template("status.alpicola.com") - assert template == "http://status.alpicola.com/main/xrd?uri={uri}" + assert template == "https://status.alpicola.com/main/xrd?uri={uri}" end test "it works with idna domains as nickname" do @@ -147,7 +147,7 @@ test "respects json content-type" do headers: [{"content-type", "application/jrd+json"}] }} - %{url: "http://mastodon.social/.well-known/host-meta"} -> + %{url: "https://mastodon.social/.well-known/host-meta"} -> {:ok, %Tesla.Env{ status: 200, @@ -170,7 +170,7 @@ test "respects xml content-type" do headers: [{"content-type", "application/xrd+xml"}] }} - %{url: "http://pawoo.net/.well-known/host-meta"} -> + %{url: "https://pawoo.net/.well-known/host-meta"} -> {:ok, %Tesla.Env{ status: 200, diff --git a/test/pleroma/workers/publisher_worker_test.exs b/test/pleroma/workers/publisher_worker_test.exs new file mode 100644 index 000000000..13372bf49 --- /dev/null +++ b/test/pleroma/workers/publisher_worker_test.exs @@ -0,0 +1,40 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Workers.PublisherWorkerTest do + use Pleroma.DataCase, async: true + use Oban.Testing, repo: Pleroma.Repo + + import Pleroma.Factory + + alias Pleroma.Object + alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Builder + alias Pleroma.Web.CommonAPI + alias Pleroma.Web.Federator + + describe "Oban job priority:" do + setup do + user = insert(:user) + + {:ok, post} = CommonAPI.post(user, %{status: "Regrettable post"}) + object = Object.normalize(post, fetch: false) + {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"]) + {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true) + + %{ + post: post, + delete: delete + } + end + + test "Deletions are lower priority", %{delete: delete} do + assert {:ok, %Oban.Job{priority: 3}} = Federator.publish(delete) + end + + test "Creates are normal priority", %{post: post} do + assert {:ok, %Oban.Job{priority: 0}} = Federator.publish(post) + end + end +end diff --git a/test/pleroma/workers/receiver_worker_test.exs b/test/pleroma/workers/receiver_worker_test.exs new file mode 100644 index 000000000..283beee4d --- /dev/null +++ b/test/pleroma/workers/receiver_worker_test.exs @@ -0,0 +1,25 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Workers.ReceiverWorkerTest do + use Pleroma.DataCase, async: true + use Oban.Testing, repo: Pleroma.Repo + + import Mock + import Pleroma.Factory + + alias Pleroma.Workers.ReceiverWorker + + test "it ignores MRF reject" do + params = insert(:note).data + + with_mock Pleroma.Web.ActivityPub.Transmogrifier, + handle_incoming: fn _ -> {:reject, "MRF"} end do + assert {:cancel, "MRF"} = + ReceiverWorker.perform(%Oban.Job{ + args: %{"op" => "incoming_ap_doc", "params" => params} + }) + end + end +end diff --git a/test/support/factory.ex b/test/support/factory.ex index efbf3df2e..09f02458c 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -10,6 +10,15 @@ defmodule Pleroma.Factory do alias Pleroma.Object alias Pleroma.User + @rsa_keys [ + "test/fixtures/rsa_keys/key_1.pem", + "test/fixtures/rsa_keys/key_2.pem", + "test/fixtures/rsa_keys/key_3.pem", + "test/fixtures/rsa_keys/key_4.pem", + "test/fixtures/rsa_keys/key_5.pem" + ] + |> Enum.map(&File.read!/1) + def participation_factory do conversation = insert(:conversation) user = insert(:user) @@ -28,6 +37,8 @@ def conversation_factory do end def user_factory(attrs \\ %{}) do + pem = Enum.random(@rsa_keys) + user = %User{ name: sequence(:name, &"Test テスト User #{&1}"), email: sequence(:email, &"user#{&1}@example.com"), @@ -39,7 +50,8 @@ def user_factory(attrs \\ %{}) do last_refreshed_at: NaiveDateTime.utc_now(), notification_settings: %Pleroma.User.NotificationSetting{}, multi_factor_authentication_settings: %Pleroma.MFA.Settings{}, - ap_enabled: true + ap_enabled: true, + keys: pem } urls = @@ -111,6 +123,18 @@ def note_factory(attrs \\ %{}) do } end + def attachment_factory(attrs \\ %{}) do + user = attrs[:user] || insert(:user) + + data = + attachment_data(user.ap_id, nil) + |> Map.put("id", Pleroma.Web.ActivityPub.Utils.generate_object_id()) + + %Pleroma.Object{ + data: merge_attributes(data, Map.get(attrs, :data, %{})) + } + end + def attachment_note_factory(attrs \\ %{}) do user = attrs[:user] || insert(:user) {length, attrs} = Map.pop(attrs, :length, 1) diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index ad4925a5c..b0cf613ac 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -424,14 +424,6 @@ def get("http://mastodon.example.org/users/gargron", _, _, [ {:error, :nxdomain} end - def get("http://osada.macgirvin.com/.well-known/host-meta", _, _, _) do - {:ok, - %Tesla.Env{ - status: 404, - body: "" - }} - end - def get("https://osada.macgirvin.com/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{ @@ -725,6 +717,15 @@ def get( }} end + def get( + "https://mastodon.social/.well-known/webfinger?resource=acct:not_found@mastodon.social", + _, + _, + [{"accept", "application/xrd+xml,application/jrd+json"}] + ) do + {:ok, %Tesla.Env{status: 404}} + end + def get("http://gs.example.org/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{ @@ -756,7 +757,7 @@ def get( {:ok, %Tesla.Env{status: 406, body: ""}} end - def get("http://squeet.me/.well-known/host-meta", _, _, _) do + def get("https://squeet.me/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/squeet.me_host_meta")}} end @@ -797,7 +798,7 @@ def get( {:ok, %Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/jrd+json"}]}} end - def get("http://framatube.org/.well-known/host-meta", _, _, _) do + def get("https://framatube.org/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{ status: 200, @@ -806,7 +807,7 @@ def get("http://framatube.org/.well-known/host-meta", _, _, _) do end def get( - "http://framatube.org/main/xrd?uri=acct:framasoft@framatube.org", + "https://framatube.org/main/xrd?uri=acct:framasoft@framatube.org", _, _, [{"accept", "application/xrd+xml,application/jrd+json"}] @@ -841,7 +842,7 @@ def get( }} end - def get("http://status.alpicola.com/.well-known/host-meta", _, _, _) do + def get("https://status.alpicola.com/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{ status: 200, @@ -849,7 +850,7 @@ def get("http://status.alpicola.com/.well-known/host-meta", _, _, _) do }} end - def get("http://macgirvin.com/.well-known/host-meta", _, _, _) do + def get("https://macgirvin.com/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{ status: 200, @@ -857,7 +858,7 @@ def get("http://macgirvin.com/.well-known/host-meta", _, _, _) do }} end - def get("http://gerzilla.de/.well-known/host-meta", _, _, _) do + def get("https://gerzilla.de/.well-known/host-meta", _, _, _) do {:ok, %Tesla.Env{ status: 200, @@ -1075,6 +1076,14 @@ def get("http://404.site" <> _, _, _, _) do }} end + def get("https://404.site" <> _, _, _, _) do + {:ok, + %Tesla.Env{ + status: 404, + body: "" + }} + end + def get( "https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:lain@zetsubou.xn--q9jyb4c", _, @@ -1124,6 +1133,57 @@ def get( }} end + def get("http://lm.kazv.moe/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/lm.kazv.moe_host_meta") + }} + end + + def get("https://lm.kazv.moe/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/lm.kazv.moe_host_meta") + }} + end + + def get( + "https://lm.kazv.moe/.well-known/webfinger?resource=acct:mewmew@lm.kazv.moe", + _, + _, + [{"accept", "application/xrd+xml,application/jrd+json"}] + ) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml"), + headers: [{"content-type", "application/xrd+xml"}] + }} + end + + def get("https://lm.kazv.moe/users/mewmew", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json"), + headers: activitypub_object_headers() + }} + end + + def get("https://lm.kazv.moe/users/mewmew/collections/featured", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: + File.read!("test/fixtures/users_mock/masto_featured.json") + |> String.replace("{{domain}}", "lm.kazv.moe") + |> String.replace("{{nickname}}", "mewmew"), + headers: [{"content-type", "application/activity+json"}] + }} + end + def get("https://info.pleroma.site/activity.json", _, _, [ {"accept", "application/activity+json"} ]) do @@ -1341,6 +1401,51 @@ def get("https://gleasonator.com/users/macgirvin/collections/featured", _, _, _) }} end + def get("https://mk.absturztau.be/users/8ozbzjs3o8", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json"), + headers: activitypub_object_headers() + }} + end + + def get("https://p.helene.moe/users/helene", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/helene@p.helene.moe.json"), + headers: activitypub_object_headers() + }} + end + + def get("https://mk.absturztau.be/notes/93e7nm8wqg", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json"), + headers: activitypub_object_headers() + }} + end + + def get("https://mk.absturztau.be/notes/93e7nm8wqg/activity", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json"), + headers: activitypub_object_headers() + }} + end + + def get("https://p.helene.moe/objects/fd5910ac-d9dc-412e-8d1d-914b203296c4", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json"), + headers: activitypub_object_headers() + }} + end + def get(url, query, body, headers) do {:error, "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"} diff --git a/test/support/websocket_client.ex b/test/support/websocket_client.ex index d149b324e..7163bbd41 100644 --- a/test/support/websocket_client.ex +++ b/test/support/websocket_client.ex @@ -5,18 +5,17 @@ defmodule Pleroma.Integration.WebsocketClient do # https://github.com/phoenixframework/phoenix/blob/master/test/support/websocket_client.exs + use WebSockex + @doc """ Starts the WebSocket server for given ws URL. Received Socket.Message's are forwarded to the sender pid """ def start_link(sender, url, headers \\ []) do - :crypto.start() - :ssl.start() - - :websocket_client.start_link( - String.to_charlist(url), + WebSockex.start_link( + url, __MODULE__, - [sender], + %{sender: sender}, extra_headers: headers ) end @@ -36,27 +35,32 @@ def send_text(server_pid, msg) do end @doc false - def init([sender], _conn_state) do - {:ok, %{sender: sender}} - end - - @doc false - def websocket_handle(frame, _conn_state, state) do + @impl true + def handle_frame(frame, state) do send(state.sender, frame) {:ok, state} end + @impl true + def handle_disconnect(conn_status, state) do + send(state.sender, {:close, conn_status}) + {:ok, state} + end + @doc false - def websocket_info({:text, msg}, _conn_state, state) do + @impl true + def handle_info({:text, msg}, state) do {:reply, {:text, msg}, state} end - def websocket_info(:close, _conn_state, _state) do + @impl true + def handle_info(:close, _state) do {:close, <<>>, "done"} end @doc false - def websocket_terminate(_reason, _conn_state, _state) do + @impl true + def terminate(_reason, _state) do :ok end end