1
0
Fork 0
forked from mirrors/akkoma

Merge branch 'localization' into 'develop'

Error Localization

See merge request pleroma/pleroma!1396
This commit is contained in:
kaniini 2019-07-10 13:27:59 +00:00
commit f295b9fba9
31 changed files with 1544 additions and 243 deletions

View file

@ -3,6 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Captcha do defmodule Pleroma.Captcha do
import Pleroma.Web.Gettext
alias Calendar.DateTime alias Calendar.DateTime
alias Plug.Crypto.KeyGenerator alias Plug.Crypto.KeyGenerator
alias Plug.Crypto.MessageEncryptor alias Plug.Crypto.MessageEncryptor
@ -83,10 +85,11 @@ def handle_call({:validate, token, captcha, answer_data}, _from, state) do
with {:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret), with {:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret),
%{at: at, answer_data: answer_md5} <- :erlang.binary_to_term(data) do %{at: at, answer_data: answer_md5} <- :erlang.binary_to_term(data) do
try do try do
if DateTime.before?(at, valid_if_after), do: throw({:error, "CAPTCHA expired"}) if DateTime.before?(at, valid_if_after),
do: throw({:error, dgettext("errors", "CAPTCHA expired")})
if not is_nil(Cachex.get!(:used_captcha_cache, token)), if not is_nil(Cachex.get!(:used_captcha_cache, token)),
do: throw({:error, "CAPTCHA already used"}) do: throw({:error, dgettext("errors", "CAPTCHA already used")})
res = method().validate(token, captcha, answer_md5) res = method().validate(token, captcha, answer_md5)
# Throw if an error occurs # Throw if an error occurs
@ -101,7 +104,7 @@ def handle_call({:validate, token, captcha, answer_data}, _from, state) do
:throw, e -> e :throw, e -> e
end end
else else
_ -> {:error, "Invalid answer data"} _ -> {:error, dgettext("errors", "Invalid answer data")}
end end
{:reply, result, state} {:reply, result, state}

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Captcha.Kocaptcha do defmodule Pleroma.Captcha.Kocaptcha do
import Pleroma.Web.Gettext
alias Pleroma.Captcha.Service alias Pleroma.Captcha.Service
@behaviour Service @behaviour Service
@ -12,7 +13,7 @@ def new do
case Tesla.get(endpoint <> "/new") do case Tesla.get(endpoint <> "/new") do
{:error, _} -> {:error, _} ->
%{error: "Kocaptcha service unavailable"} %{error: dgettext("errors", "Kocaptcha service unavailable")}
{:ok, res} -> {:ok, res} ->
json_resp = Jason.decode!(res.body) json_resp = Jason.decode!(res.body)
@ -32,6 +33,6 @@ def validate(_token, captcha, answer_data) do
if not is_nil(captcha) and if not is_nil(captcha) and
:crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(answer_data), :crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(answer_data),
do: :ok, do: :ok,
else: {:error, "Invalid CAPTCHA"} else: {:error, dgettext("errors", "Invalid CAPTCHA")}
end end
end end

View file

@ -4,6 +4,7 @@
defmodule Pleroma.Plugs.EnsureAuthenticatedPlug do defmodule Pleroma.Plugs.EnsureAuthenticatedPlug do
import Plug.Conn import Plug.Conn
import Pleroma.Web.TranslationHelpers
alias Pleroma.User alias Pleroma.User
def init(options) do def init(options) do
@ -16,8 +17,7 @@ def call(%{assigns: %{user: %User{}}} = conn, _) do
def call(conn, _) do def call(conn, _) do
conn conn
|> put_resp_content_type("application/json") |> render_error(:forbidden, "Invalid credentials.")
|> send_resp(403, Jason.encode!(%{error: "Invalid credentials."}))
|> halt |> halt
end end
end end

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug do defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug do
import Pleroma.Web.TranslationHelpers
import Plug.Conn import Plug.Conn
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.User alias Pleroma.User
@ -23,8 +24,7 @@ def call(conn, _) do
{false, _} -> {false, _} ->
conn conn
|> put_resp_content_type("application/json") |> render_error(:forbidden, "This resource requires authentication.")
|> send_resp(403, Jason.encode!(%{error: "This resource requires authentication."}))
|> halt |> halt
end end
end end

View file

@ -4,6 +4,7 @@
defmodule Pleroma.Plugs.OAuthScopesPlug do defmodule Pleroma.Plugs.OAuthScopesPlug do
import Plug.Conn import Plug.Conn
import Pleroma.Web.Gettext
@behaviour Plug @behaviour Plug
@ -30,11 +31,14 @@ def call(%Plug.Conn{assigns: assigns} = conn, %{scopes: scopes} = options) do
true -> true ->
missing_scopes = scopes -- token.scopes missing_scopes = scopes -- token.scopes
error_message = "Insufficient permissions: #{Enum.join(missing_scopes, " #{op} ")}." permissions = Enum.join(missing_scopes, " #{op} ")
error_message =
dgettext("errors", "Insufficient permissions: %{permissions}.", permissions: permissions)
conn conn
|> put_resp_content_type("application/json") |> put_resp_content_type("application/json")
|> send_resp(403, Jason.encode!(%{error: error_message})) |> send_resp(:forbidden, Jason.encode!(%{error: error_message}))
|> halt() |> halt()
end end
end end

View file

@ -44,8 +44,7 @@ defmodule Pleroma.Plugs.RateLimiter do
... ...
end end
""" """
import Pleroma.Web.TranslationHelpers
import Phoenix.Controller, only: [json: 2]
import Plug.Conn import Plug.Conn
alias Pleroma.User alias Pleroma.User
@ -63,7 +62,7 @@ def call(conn, nil), do: conn
def call(conn, opts) do def call(conn, opts) do
case check_rate(conn, opts) do case check_rate(conn, opts) do
{:ok, _count} -> conn {:ok, _count} -> conn
{:error, _count} -> render_error(conn) {:error, _count} -> render_throttled_error(conn)
end end
end end
@ -85,10 +84,9 @@ def ip(%{remote_ip: remote_ip}) do
|> Enum.join(".") |> Enum.join(".")
end end
defp render_error(conn) do defp render_throttled_error(conn) do
conn conn
|> put_status(:too_many_requests) |> render_error(:too_many_requests, "Throttled")
|> json(%{error: "Throttled"})
|> halt() |> halt()
end end
end end

View file

@ -0,0 +1,63 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
# NOTE: this module is based on https://github.com/smeevil/set_locale
defmodule Pleroma.Plugs.SetLocalePlug do
import Plug.Conn, only: [get_req_header: 2, assign: 3]
def init(_), do: nil
def call(conn, _) do
locale = get_locale_from_header(conn) || Gettext.get_locale()
Gettext.put_locale(locale)
assign(conn, :locale, locale)
end
defp get_locale_from_header(conn) do
conn
|> extract_accept_language()
|> Enum.find(&supported_locale?/1)
end
defp extract_accept_language(conn) do
case get_req_header(conn, "accept-language") do
[value | _] ->
value
|> String.split(",")
|> Enum.map(&parse_language_option/1)
|> Enum.sort(&(&1.quality > &2.quality))
|> Enum.map(& &1.tag)
|> Enum.reject(&is_nil/1)
|> ensure_language_fallbacks()
_ ->
[]
end
end
defp supported_locale?(locale) do
Pleroma.Web.Gettext
|> Gettext.known_locales()
|> Enum.member?(locale)
end
defp parse_language_option(string) do
captures = Regex.named_captures(~r/^\s?(?<tag>[\w\-]+)(?:;q=(?<quality>[\d\.]+))?$/i, string)
quality =
case Float.parse(captures["quality"] || "1.0") do
{val, _} -> val
:error -> 1.0
end
%{tag: captures["tag"], quality: quality}
end
defp ensure_language_fallbacks(tags) do
Enum.flat_map(tags, fn tag ->
[language | _] = String.split(tag, "-")
if Enum.member?(tags, language), do: [tag], else: [tag, language]
end)
end
end

View file

@ -7,6 +7,7 @@ defmodule Pleroma.Plugs.UploadedMedia do
""" """
import Plug.Conn import Plug.Conn
import Pleroma.Web.Gettext
require Logger require Logger
@behaviour Plug @behaviour Plug
@ -45,7 +46,7 @@ def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do
else else
_ -> _ ->
conn conn
|> send_resp(500, "Failed") |> send_resp(:internal_server_error, dgettext("errors", "Failed"))
|> halt() |> halt()
end end
end end
@ -64,7 +65,7 @@ defp get_media(conn, {:static_dir, directory}, _, opts) do
conn conn
else else
conn conn
|> send_resp(404, "Not found") |> send_resp(:not_found, dgettext("errors", "Not found"))
|> halt() |> halt()
end end
end end
@ -84,7 +85,7 @@ defp get_media(conn, unknown, _, _) do
Logger.error("#{__MODULE__}: Unknown get startegy: #{inspect(unknown)}") Logger.error("#{__MODULE__}: Unknown get startegy: #{inspect(unknown)}")
conn conn
|> send_resp(500, "Internal Error") |> send_resp(:internal_server_error, dgettext("errors", "Internal Error"))
|> halt() |> halt()
end end
end end

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.UserIsAdminPlug do defmodule Pleroma.Plugs.UserIsAdminPlug do
import Pleroma.Web.TranslationHelpers
import Plug.Conn import Plug.Conn
alias Pleroma.User alias Pleroma.User
@ -16,8 +17,7 @@ def call(%{assigns: %{user: %User{info: %{is_admin: true}}}} = conn, _) do
def call(conn, _) do def call(conn, _) do
conn conn
|> put_resp_content_type("application/json") |> render_error(:forbidden, "User is not admin.")
|> send_resp(403, Jason.encode!(%{error: "User is not admin."}))
|> halt |> halt
end end
end end

View file

@ -3,6 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Uploaders.Uploader do defmodule Pleroma.Uploaders.Uploader do
import Pleroma.Web.Gettext
@moduledoc """ @moduledoc """
Defines the contract to put and get an uploaded file to any backend. Defines the contract to put and get an uploaded file to any backend.
""" """
@ -66,7 +68,7 @@ defp handle_callback(uploader, upload) do
{:error, error} {:error, error}
end end
after after
30_000 -> {:error, "Uploader callback timeout"} 30_000 -> {:error, dgettext("errors", "Uploader callback timeout")}
end end
end end
end end

View file

@ -31,9 +31,8 @@ def relay_active?(conn, _) do
conn conn
else else
conn conn
|> put_status(404) |> render_error(:not_found, "not found")
|> json(%{error: "not found"}) |> halt()
|> halt
end end
end end
@ -190,7 +189,7 @@ def inbox(conn, params) do
Logger.info(inspect(conn.req_headers)) Logger.info(inspect(conn.req_headers))
end end
json(conn, "error") json(conn, dgettext("errors", "error"))
end end
def relay(conn, _params) do def relay(conn, _params) do
@ -218,9 +217,15 @@ def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = par
|> put_resp_header("content-type", "application/activity+json") |> put_resp_header("content-type", "application/activity+json")
|> json(UserView.render("inbox.json", %{user: user, max_id: params["max_id"]})) |> json(UserView.render("inbox.json", %{user: user, max_id: params["max_id"]}))
else else
err =
dgettext("errors", "can't read inbox of %{nickname} as %{as_nickname}",
nickname: nickname,
as_nickname: user.nickname
)
conn conn
|> put_status(:forbidden) |> put_status(:forbidden)
|> json("can't read inbox of #{nickname} as #{user.nickname}") |> json(err)
end end
end end
@ -246,7 +251,7 @@ def handle_user_activity(user, %{"type" => "Delete"} = params) do
{:ok, delete} <- ActivityPub.delete(object) do {:ok, delete} <- ActivityPub.delete(object) do
{:ok, delete} {:ok, delete}
else else
_ -> {:error, "Can't delete object"} _ -> {:error, dgettext("errors", "Can't delete object")}
end end
end end
@ -255,12 +260,12 @@ def handle_user_activity(user, %{"type" => "Like"} = params) do
{:ok, activity, _object} <- ActivityPub.like(user, object) do {:ok, activity, _object} <- ActivityPub.like(user, object) do
{:ok, activity} {:ok, activity}
else else
_ -> {:error, "Can't like object"} _ -> {:error, dgettext("errors", "Can't like object")}
end end
end end
def handle_user_activity(_, _) do def handle_user_activity(_, _) do
{:error, "Unhandled activity type"} {:error, dgettext("errors", "Unhandled activity type")}
end end
def update_outbox( def update_outbox(
@ -288,22 +293,28 @@ def update_outbox(
|> json(message) |> json(message)
end end
else else
err =
dgettext("errors", "can't update outbox of %{nickname} as %{as_nickname}",
nickname: nickname,
as_nickname: user.nickname
)
conn conn
|> put_status(:forbidden) |> put_status(:forbidden)
|> json("can't update outbox of #{nickname} as #{user.nickname}") |> json(err)
end end
end end
def errors(conn, {:error, :not_found}) do def errors(conn, {:error, :not_found}) do
conn conn
|> put_status(404) |> put_status(:not_found)
|> json("Not found") |> json(dgettext("errors", "Not found"))
end end
def errors(conn, _e) do def errors(conn, _e) do
conn conn
|> put_status(500) |> put_status(:internal_server_error)
|> json("error") |> json(dgettext("errors", "error"))
end end
defp set_requester_reachable(%Plug.Conn{} = conn, _) do defp set_requester_reachable(%Plug.Conn{} = conn, _) do

View file

@ -160,9 +160,7 @@ def right_add(conn, %{"permission_group" => permission_group, "nickname" => nick
end end
def right_add(conn, _) do def right_add(conn, _) do
conn render_error(conn, :not_found, "No such permission_group")
|> put_status(404)
|> json(%{error: "No such permission_group"})
end end
def right_get(conn, %{"nickname" => nickname}) do def right_get(conn, %{"nickname" => nickname}) do
@ -184,9 +182,7 @@ def right_delete(
) )
when permission_group in ["moderator", "admin"] do when permission_group in ["moderator", "admin"] do
if admin_nickname == nickname do if admin_nickname == nickname do
conn render_error(conn, :forbidden, "You can't revoke your own admin status.")
|> put_status(403)
|> json(%{error: "You can't revoke your own admin status."})
else else
user = User.get_cached_by_nickname(nickname) user = User.get_cached_by_nickname(nickname)
@ -207,9 +203,7 @@ def right_delete(
end end
def right_delete(conn, _) do def right_delete(conn, _) do
conn render_error(conn, :not_found, "No such permission_group")
|> put_status(404)
|> json(%{error: "No such permission_group"})
end end
def set_activation_status(conn, %{"nickname" => nickname, "status" => status}) do def set_activation_status(conn, %{"nickname" => nickname, "status" => status}) do
@ -401,26 +395,26 @@ def config_update(conn, %{"configs" => configs}) do
def errors(conn, {:error, :not_found}) do def errors(conn, {:error, :not_found}) do
conn conn
|> put_status(404) |> put_status(:not_found)
|> json("Not found") |> json(dgettext("errors", "Not found"))
end end
def errors(conn, {:error, reason}) do def errors(conn, {:error, reason}) do
conn conn
|> put_status(400) |> put_status(:bad_request)
|> json(reason) |> json(reason)
end end
def errors(conn, {:param_cast, _}) do def errors(conn, {:param_cast, _}) do
conn conn
|> put_status(400) |> put_status(:bad_request)
|> json("Invalid parameters") |> json(dgettext("errors", "Invalid parameters"))
end end
def errors(conn, _) do def errors(conn, _) do
conn conn
|> put_status(500) |> put_status(:internal_server_error)
|> json("Something went wrong") |> json(dgettext("errors", "Something went wrong"))
end end
defp page_params(params) do defp page_params(params) do

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.AdminAPI.Config do defmodule Pleroma.Web.AdminAPI.Config do
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
import Pleroma.Web.Gettext
alias __MODULE__ alias __MODULE__
alias Pleroma.Repo alias Pleroma.Repo
@ -57,7 +58,11 @@ def delete(params) do
with %Config{} = config <- Config.get_by_params(params) do with %Config{} = config <- Config.get_by_params(params) do
Repo.delete(config) Repo.delete(config)
else else
nil -> {:error, "Config with params #{inspect(params)} not found"} nil ->
err =
dgettext("errors", "Config with params %{params} not found", params: inspect(params))
{:error, err}
end end
end end

View file

@ -13,6 +13,7 @@ defmodule Pleroma.Web.CommonAPI do
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
import Pleroma.Web.Gettext
import Pleroma.Web.CommonAPI.Utils import Pleroma.Web.CommonAPI.Utils
def follow(follower, followed) do def follow(follower, followed) do
@ -74,7 +75,7 @@ def delete(activity_id, user) do
{:ok, delete} {:ok, delete}
else else
_ -> _ ->
{:error, "Could not delete"} {:error, dgettext("errors", "Could not delete")}
end end
end end
@ -85,7 +86,7 @@ def repeat(id_or_ap_id, user) do
ActivityPub.announce(user, object) ActivityPub.announce(user, object)
else else
_ -> _ ->
{:error, "Could not repeat"} {:error, dgettext("errors", "Could not repeat")}
end end
end end
@ -95,7 +96,7 @@ def unrepeat(id_or_ap_id, user) do
ActivityPub.unannounce(user, object) ActivityPub.unannounce(user, object)
else else
_ -> _ ->
{:error, "Could not unrepeat"} {:error, dgettext("errors", "Could not unrepeat")}
end end
end end
@ -106,7 +107,7 @@ def favorite(id_or_ap_id, user) do
ActivityPub.like(user, object) ActivityPub.like(user, object)
else else
_ -> _ ->
{:error, "Could not favorite"} {:error, dgettext("errors", "Could not favorite")}
end end
end end
@ -116,7 +117,7 @@ def unfavorite(id_or_ap_id, user) do
ActivityPub.unlike(user, object) ActivityPub.unlike(user, object)
else else
_ -> _ ->
{:error, "Could not unfavorite"} {:error, dgettext("errors", "Could not unfavorite")}
end end
end end
@ -148,10 +149,10 @@ def vote(user, object, choices) do
object = Object.get_cached_by_ap_id(object.data["id"]) object = Object.get_cached_by_ap_id(object.data["id"])
{:ok, answer_activities, object} {:ok, answer_activities, object}
else else
{:author, _} -> {:error, "Poll's author can't vote"} {:author, _} -> {:error, dgettext("errors", "Poll's author can't vote")}
{:existing_votes, _} -> {:error, "Already voted"} {:existing_votes, _} -> {:error, dgettext("errors", "Already voted")}
{:choice_check, {_, false}} -> {:error, "Invalid indices"} {:choice_check, {_, false}} -> {:error, dgettext("errors", "Invalid indices")}
{:count_check, false} -> {:error, "Too many choices"} {:count_check, false} -> {:error, dgettext("errors", "Too many choices")}
end end
end end
@ -248,9 +249,14 @@ def post(user, %{"status" => status} = data) do
res res
else else
{:private_to_public, true} -> {:error, "The message visibility must be direct"} {:private_to_public, true} ->
{:error, _} = e -> e {:error, dgettext("errors", "The message visibility must be direct")}
e -> {:error, e}
{:error, _} = e ->
e
e ->
{:error, e}
end end
end end
@ -301,7 +307,7 @@ def pin(id_or_ap_id, %{ap_id: user_ap_id} = user) do
{:error, err} {:error, err}
_ -> _ ->
{:error, "Could not pin"} {:error, dgettext("errors", "Could not pin")}
end end
end end
@ -318,7 +324,7 @@ def unpin(id_or_ap_id, user) do
{:error, err} {:error, err}
_ -> _ ->
{:error, "Could not unpin"} {:error, dgettext("errors", "Could not unpin")}
end end
end end
@ -326,7 +332,7 @@ def add_mute(user, activity) do
with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]) do with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]) do
{:ok, activity} {:ok, activity}
else else
{:error, _} -> {:error, "conversation is already muted"} {:error, _} -> {:error, dgettext("errors", "conversation is already muted")}
end end
end end
@ -371,8 +377,8 @@ def report(user, data) do
{:ok, activity} {:ok, activity}
else else
{:error, err} -> {:error, err} {:error, err} -> {:error, err}
{:account_id, %{}} -> {:error, "Valid `account_id` required"} {:account_id, %{}} -> {:error, dgettext("errors", "Valid `account_id` required")}
{:account, nil} -> {:error, "Account not found"} {:account, nil} -> {:error, dgettext("errors", "Account not found")}
end end
end end
@ -381,14 +387,9 @@ def update_report_state(activity_id, state) do
{:ok, activity} <- Utils.update_report_state(activity, state) do {:ok, activity} <- Utils.update_report_state(activity, state) do
{:ok, activity} {:ok, activity}
else else
nil -> nil -> {:error, :not_found}
{:error, :not_found} {:error, reason} -> {:error, reason}
_ -> {:error, dgettext("errors", "Could not update state")}
{:error, reason} ->
{:error, reason}
_ ->
{:error, "Could not update state"}
end end
end end
@ -398,11 +399,8 @@ def update_activity_scope(activity_id, opts \\ %{}) do
{:ok, activity} <- set_visibility(activity, opts) do {:ok, activity} <- set_visibility(activity, opts) do
{:ok, activity} {:ok, activity}
else else
nil -> nil -> {:error, :not_found}
{:error, :not_found} {:error, reason} -> {:error, reason}
{:error, reason} ->
{:error, reason}
end end
end end

View file

@ -3,6 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CommonAPI.Utils do defmodule Pleroma.Web.CommonAPI.Utils do
import Pleroma.Web.Gettext
alias Calendar.Strftime alias Calendar.Strftime
alias Comeonin.Pbkdf2 alias Comeonin.Pbkdf2
alias Pleroma.Activity alias Pleroma.Activity
@ -372,7 +374,7 @@ def confirm_current_password(user, password) do
true <- Pbkdf2.checkpw(password, db_user.password_hash) do true <- Pbkdf2.checkpw(password, db_user.password_hash) do
{:ok, db_user} {:ok, db_user}
else else
_ -> {:error, "Invalid password."} _ -> {:error, dgettext("errors", "Invalid password.")}
end end
end end
@ -455,7 +457,8 @@ def make_report_content_html(comment) do
if String.length(comment) <= max_size do if String.length(comment) <= max_size do
{:ok, format_input(comment, "text/plain")} {:ok, format_input(comment, "text/plain")}
else else
{:error, "Comment must be up to #{max_size} characters"} {:error,
dgettext("errors", "Comment must be up to %{max_size} characters", max_size: max_size)}
end end
end end
@ -490,7 +493,7 @@ def conversation_id_to_context(id) do
context context
else else
_e -> _e ->
{:error, "No such conversation"} {:error, dgettext("errors", "No such conversation")}
end end
end end
@ -512,10 +515,10 @@ def validate_character_limit(full_payload, attachments, limit) do
if length > 0 or Enum.count(attachments) > 0 do if length > 0 or Enum.count(attachments) > 0 do
:ok :ok
else else
{:error, "Cannot post an empty status without attachments"} {:error, dgettext("errors", "Cannot post an empty status without attachments")}
end end
else else
{:error, "The status is over the character limit"} {:error, dgettext("errors", "The status is over the character limit")}
end end
end end
end end

View file

@ -7,13 +7,9 @@ defmodule Pleroma.Web.Endpoint do
socket("/socket", Pleroma.Web.UserSocket) socket("/socket", Pleroma.Web.UserSocket)
# Serve at "/" the static files from "priv/static" directory. plug(Pleroma.Plugs.SetLocalePlug)
#
# You should set gzip to true if you are running phoenix.digest
# when deploying your static files in production.
plug(CORSPlug) plug(CORSPlug)
plug(Pleroma.Plugs.HTTPSecurityPlug) plug(Pleroma.Plugs.HTTPSecurityPlug)
plug(Pleroma.Plugs.UploadedMedia) plug(Pleroma.Plugs.UploadedMedia)
@static_cache_control "public, no-cache" @static_cache_control "public, no-cache"
@ -30,6 +26,10 @@ defmodule Pleroma.Web.Endpoint do
} }
) )
# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phoenix.digest
# when deploying your static files in production.
plug( plug(
Plug.Static, Plug.Static,
at: "/", at: "/",

View file

@ -160,10 +160,7 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do
AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true}) AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true})
) )
else else
_e -> _e -> render_error(conn, :forbidden, "Invalid request")
conn
|> put_status(403)
|> json(%{error: "Invalid request"})
end end
end end
@ -258,10 +255,7 @@ def user(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
account = AccountView.render("account.json", %{user: user, for: for_user}) account = AccountView.render("account.json", %{user: user, for: for_user})
json(conn, account) json(conn, account)
else else
_e -> _e -> render_error(conn, :not_found, "Can't find user")
conn
|> put_status(404)
|> json(%{error: "Can't find user"})
end end
end end
@ -509,15 +503,8 @@ def get_poll(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|> put_view(StatusView) |> put_view(StatusView)
|> try_render("poll.json", %{object: object, for: user}) |> try_render("poll.json", %{object: object, for: user})
else else
nil -> nil -> render_error(conn, :not_found, "Record not found")
conn false -> render_error(conn, :not_found, "Record not found")
|> put_status(404)
|> json(%{error: "Record not found"})
false ->
conn
|> put_status(404)
|> json(%{error: "Record not found"})
end end
end end
@ -546,18 +533,14 @@ def poll_vote(%{assigns: %{user: user}} = conn, %{"id" => id, "choices" => choic
|> try_render("poll.json", %{object: object, for: user}) |> try_render("poll.json", %{object: object, for: user})
else else
nil -> nil ->
conn render_error(conn, :not_found, "Record not found")
|> put_status(404)
|> json(%{error: "Record not found"})
false -> false ->
conn render_error(conn, :not_found, "Record not found")
|> put_status(404)
|> json(%{error: "Record not found"})
{:error, message} -> {:error, message} ->
conn conn
|> put_status(422) |> put_status(:unprocessable_entity)
|> json(%{error: message}) |> json(%{error: message})
end end
end end
@ -646,10 +629,7 @@ def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
json(conn, %{}) json(conn, %{})
else else
_e -> _e -> render_error(conn, :forbidden, "Can't delete this post")
conn
|> put_status(403)
|> json(%{error: "Can't delete this post"})
end end
end end
@ -697,8 +677,8 @@ def pin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
else else
{:error, reason} -> {:error, reason} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:bad_request)
|> send_resp(:bad_request, Jason.encode!(%{"error" => reason})) |> json(%{"error" => reason})
end end
end end
@ -774,8 +754,8 @@ def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params)
else else
{:error, reason} -> {:error, reason} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => reason})) |> json(%{"error" => reason})
end end
end end
@ -790,8 +770,8 @@ def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _para
else else
{:error, reason} -> {:error, reason} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => reason})) |> json(%{"error" => reason})
end end
end end
@ -869,9 +849,7 @@ def set_mascot(%{assigns: %{user: user}} = conn, %{"file" => file}) do
conn conn
|> json(rendered) |> json(rendered)
else else
conn render_error(conn, :unsupported_media_type, "mascots can only be images")
|> put_resp_content_type("application/json")
|> send_resp(415, Jason.encode!(%{"error" => "mascots can only be images"}))
end end
end end
end end
@ -1000,8 +978,8 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1014,8 +992,8 @@ def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) d
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1032,8 +1010,8 @@ def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1050,8 +1028,8 @@ def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1080,8 +1058,8 @@ def mute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1094,8 +1072,8 @@ def unmute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1116,8 +1094,8 @@ def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1131,8 +1109,8 @@ def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1166,8 +1144,8 @@ def subscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1180,8 +1158,8 @@ def unsubscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do
else else
{:error, message} -> {:error, message} ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:forbidden)
|> send_resp(403, Jason.encode!(%{"error" => message})) |> json(%{error: message})
end end
end end
@ -1229,13 +1207,8 @@ def user_favourites(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params
|> put_view(StatusView) |> put_view(StatusView)
|> render("index.json", %{activities: activities, for: for_user, as: :activity}) |> render("index.json", %{activities: activities, for: for_user, as: :activity})
else else
nil -> nil -> {:error, :not_found}
{:error, :not_found} true -> render_error(conn, :forbidden, "Can't get favorites")
true ->
conn
|> put_status(403)
|> json(%{error: "Can't get favorites"})
end end
end end
@ -1267,10 +1240,7 @@ def get_list(%{assigns: %{user: user}} = conn, %{"id" => id}) do
res = ListView.render("list.json", list: list) res = ListView.render("list.json", list: list)
json(conn, res) json(conn, res)
else else
_e -> _e -> render_error(conn, :not_found, "Record not found")
conn
|> put_status(404)
|> json(%{error: "Record not found"})
end end
end end
@ -1286,7 +1256,7 @@ def delete_list(%{assigns: %{user: user}} = conn, %{"id" => id}) do
json(conn, %{}) json(conn, %{})
else else
_e -> _e ->
json(conn, "error") json(conn, dgettext("errors", "error"))
end end
end end
@ -1337,7 +1307,7 @@ def rename_list(%{assigns: %{user: user}} = conn, %{"id" => id, "title" => title
json(conn, res) json(conn, res)
else else
_e -> _e ->
json(conn, "error") json(conn, dgettext("errors", "error"))
end end
end end
@ -1361,10 +1331,7 @@ def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params)
|> put_view(StatusView) |> put_view(StatusView)
|> render("index.json", %{activities: activities, for: user, as: :activity}) |> render("index.json", %{activities: activities, for: user, as: :activity})
else else
_e -> _e -> render_error(conn, :forbidden, "Error.")
conn
|> put_status(403)
|> json(%{error: "Error."})
end end
end end
@ -1483,8 +1450,8 @@ def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _para
else else
e -> e ->
conn conn
|> put_resp_content_type("application/json") |> put_status(:internal_server_error)
|> send_resp(500, Jason.encode!(%{"error" => inspect(e)})) |> json(%{error: inspect(e)})
end end
end end
@ -1652,20 +1619,18 @@ def errors(conn, {:error, %Changeset{} = changeset}) do
|> Enum.map_join(", ", fn {_k, v} -> v end) |> Enum.map_join(", ", fn {_k, v} -> v end)
conn conn
|> put_status(422) |> put_status(:unprocessable_entity)
|> json(%{error: error_message}) |> json(%{error: error_message})
end end
def errors(conn, {:error, :not_found}) do def errors(conn, {:error, :not_found}) do
conn render_error(conn, :not_found, "Record not found")
|> put_status(404)
|> json(%{error: "Record not found"})
end end
def errors(conn, _) do def errors(conn, _) do
conn conn
|> put_status(500) |> put_status(:internal_server_error)
|> json("Something went wrong") |> json(dgettext("errors", "Something went wrong"))
end end
def suggestions(%{assigns: %{user: user}} = conn, _) do def suggestions(%{assigns: %{user: user}} = conn, _) do
@ -1785,21 +1750,17 @@ def account_register(
else else
{:error, errors} -> {:error, errors} ->
conn conn
|> put_status(400) |> put_status(:bad_request)
|> json(Jason.encode!(errors)) |> json(errors)
end end
end end
def account_register(%{assigns: %{app: _app}} = conn, _params) do def account_register(%{assigns: %{app: _app}} = conn, _params) do
conn render_error(conn, :bad_request, "Missing parameters")
|> put_status(400)
|> json(%{error: "Missing parameters"})
end end
def account_register(conn, _) do def account_register(conn, _) do
conn render_error(conn, :forbidden, "Invalid credentials")
|> put_status(403)
|> json(%{error: "Invalid credentials"})
end end
def conversations(%{assigns: %{user: user}} = conn, params) do def conversations(%{assigns: %{user: user}} = conn, params) do
@ -1829,21 +1790,14 @@ def conversation_read(%{assigns: %{user: user}} = conn, %{"id" => participation_
def try_render(conn, target, params) def try_render(conn, target, params)
when is_binary(target) do when is_binary(target) do
res = render(conn, target, params) case render(conn, target, params) do
nil -> render_error(conn, :not_implemented, "Can't display this activity")
if res == nil do res -> res
conn
|> put_status(501)
|> json(%{error: "Can't display this activity"})
else
res
end end
end end
def try_render(conn, _, _) do def try_render(conn, _, _) do
conn render_error(conn, :not_implemented, "Can't display this activity")
|> put_status(501)
|> json(%{error: "Can't display this activity"})
end end
defp present?(nil), do: false defp present?(nil), do: false

View file

@ -59,13 +59,13 @@ def delete(%{assigns: %{user: user, token: token}} = conn, _params) do
# #
def errors(conn, {:error, :not_found}) do def errors(conn, {:error, :not_found}) do
conn conn
|> put_status(404) |> put_status(:not_found)
|> json("Not found") |> json(dgettext("errors", "Not found"))
end end
def errors(conn, _) do def errors(conn, _) do
conn conn
|> put_status(500) |> put_status(:internal_server_error)
|> json("Something went wrong") |> json(dgettext("errors", "Something went wrong"))
end end
end end

View file

@ -29,7 +29,7 @@ def check_password(conn, %{"user" => username, "pass" => password}) do
else else
false -> false ->
conn conn
|> put_status(403) |> put_status(:forbidden)
|> json(false) |> json(false)
_ -> _ ->

View file

@ -201,8 +201,6 @@ def nodeinfo(conn, %{"version" => "2.1"}) do
end end
def nodeinfo(conn, _) do def nodeinfo(conn, _) do
conn render_error(conn, :not_found, "Nodeinfo schema version not handled")
|> put_status(404)
|> json(%{error: "Nodeinfo schema version not handled"})
end end
end end

View file

@ -9,21 +9,24 @@ defmodule Pleroma.Web.OAuth.FallbackController do
def call(conn, {:register, :generic_error}) do def call(conn, {:register, :generic_error}) do
conn conn
|> put_status(:internal_server_error) |> put_status(:internal_server_error)
|> put_flash(:error, "Unknown error, please check the details and try again.") |> put_flash(
:error,
dgettext("errors", "Unknown error, please check the details and try again.")
)
|> OAuthController.registration_details(conn.params) |> OAuthController.registration_details(conn.params)
end end
def call(conn, {:register, _error}) do def call(conn, {:register, _error}) do
conn conn
|> put_status(:unauthorized) |> put_status(:unauthorized)
|> put_flash(:error, "Invalid Username/Password") |> put_flash(:error, dgettext("errors", "Invalid Username/Password"))
|> OAuthController.registration_details(conn.params) |> OAuthController.registration_details(conn.params)
end end
def call(conn, _error) do def call(conn, _error) do
conn conn
|> put_status(:unauthorized) |> put_status(:unauthorized)
|> put_flash(:error, "Invalid Username/Password") |> put_flash(:error, dgettext("errors", "Invalid Username/Password"))
|> OAuthController.authorize(conn.params) |> OAuthController.authorize(conn.params)
end end
end end

View file

@ -90,7 +90,7 @@ defp handle_existing_authorization(
redirect(conn, external: url) redirect(conn, external: url)
else else
conn conn
|> put_flash(:error, "Unlisted redirect_uri.") |> put_flash(:error, dgettext("errors", "Unlisted redirect_uri."))
|> redirect(external: redirect_uri(conn, redirect_uri)) |> redirect(external: redirect_uri(conn, redirect_uri))
end end
end end
@ -128,7 +128,7 @@ def after_create_authorization(%Plug.Conn{} = conn, %Authorization{} = auth, %{
redirect(conn, external: url) redirect(conn, external: url)
else else
conn conn
|> put_flash(:error, "Unlisted redirect_uri.") |> put_flash(:error, dgettext("errors", "Unlisted redirect_uri."))
|> redirect(external: redirect_uri(conn, redirect_uri)) |> redirect(external: redirect_uri(conn, redirect_uri))
end end
end end
@ -142,7 +142,7 @@ defp handle_create_authorization_error(
# Per https://github.com/tootsuite/mastodon/blob/ # Per https://github.com/tootsuite/mastodon/blob/
# 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L39 # 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L39
conn conn
|> put_flash(:error, "This action is outside the authorized scopes") |> put_flash(:error, dgettext("errors", "This action is outside the authorized scopes"))
|> put_status(:unauthorized) |> put_status(:unauthorized)
|> authorize(params) |> authorize(params)
end end
@ -155,7 +155,7 @@ defp handle_create_authorization_error(
# Per https://github.com/tootsuite/mastodon/blob/ # Per https://github.com/tootsuite/mastodon/blob/
# 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L76 # 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L76
conn conn
|> put_flash(:error, "Your login is missing a confirmed e-mail address") |> put_flash(:error, dgettext("errors", "Your login is missing a confirmed e-mail address"))
|> put_status(:forbidden) |> put_status(:forbidden)
|> authorize(params) |> authorize(params)
end end
@ -176,9 +176,7 @@ def token_exchange(
json(conn, Token.Response.build(user, token, response_attrs)) json(conn, Token.Response.build(user, token, response_attrs))
else else
_error -> _error -> render_invalid_credentials_error(conn)
put_status(conn, 400)
|> json(%{error: "Invalid credentials"})
end end
end end
@ -192,9 +190,7 @@ def token_exchange(%Plug.Conn{} = conn, %{"grant_type" => "authorization_code"}
json(conn, Token.Response.build(user, token, response_attrs)) json(conn, Token.Response.build(user, token, response_attrs))
else else
_error -> _error -> render_invalid_credentials_error(conn)
put_status(conn, 400)
|> json(%{error: "Invalid credentials"})
end end
end end
@ -214,18 +210,13 @@ def token_exchange(
{:auth_active, false} -> {:auth_active, false} ->
# Per https://github.com/tootsuite/mastodon/blob/ # Per https://github.com/tootsuite/mastodon/blob/
# 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L76 # 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L76
conn render_error(conn, :forbidden, "Your login is missing a confirmed e-mail address")
|> put_status(:forbidden)
|> json(%{error: "Your login is missing a confirmed e-mail address"})
{:user_active, false} -> {:user_active, false} ->
conn render_error(conn, :forbidden, "Your account is currently disabled")
|> put_status(:forbidden)
|> json(%{error: "Your account is currently disabled"})
_error -> _error ->
put_status(conn, 400) render_invalid_credentials_error(conn)
|> json(%{error: "Invalid credentials"})
end end
end end
@ -247,9 +238,7 @@ def token_exchange(%Plug.Conn{} = conn, %{"grant_type" => "client_credentials"}
{:ok, token} <- Token.exchange_token(app, auth) do {:ok, token} <- Token.exchange_token(app, auth) do
json(conn, Token.Response.build_for_client_credentials(token)) json(conn, Token.Response.build_for_client_credentials(token))
else else
_error -> _error -> render_invalid_credentials_error(conn)
put_status(conn, 400)
|> json(%{error: "Invalid credentials"})
end end
end end
@ -271,9 +260,7 @@ def token_revoke(%Plug.Conn{} = conn, params), do: bad_request(conn, params)
# Response for bad request # Response for bad request
defp bad_request(%Plug.Conn{} = conn, _) do defp bad_request(%Plug.Conn{} = conn, _) do
conn render_error(conn, :internal_server_error, "Bad request")
|> put_status(500)
|> json(%{error: "Bad request"})
end end
@doc "Prepares OAuth request to provider for Ueberauth" @doc "Prepares OAuth request to provider for Ueberauth"
@ -304,9 +291,11 @@ def prepare_request(%Plug.Conn{} = conn, %{
def request(%Plug.Conn{} = conn, params) do def request(%Plug.Conn{} = conn, params) do
message = message =
if params["provider"] do if params["provider"] do
"Unsupported OAuth provider: #{params["provider"]}." dgettext("errors", "Unsupported OAuth provider: %{provider}.",
provider: params["provider"]
)
else else
"Bad OAuth request." dgettext("errors", "Bad OAuth request.")
end end
conn conn
@ -320,7 +309,10 @@ def callback(%Plug.Conn{assigns: %{ueberauth_failure: failure}} = conn, params)
message = Enum.join(messages, "; ") message = Enum.join(messages, "; ")
conn conn
|> put_flash(:error, "Failed to authenticate: #{message}.") |> put_flash(
:error,
dgettext("errors", "Failed to authenticate: %{message}.", message: message)
)
|> redirect(external: redirect_uri(conn, params["redirect_uri"])) |> redirect(external: redirect_uri(conn, params["redirect_uri"]))
end end
@ -350,7 +342,7 @@ def callback(%Plug.Conn{} = conn, params) do
Logger.debug(inspect(["OAUTH_ERROR", error, conn.assigns])) Logger.debug(inspect(["OAUTH_ERROR", error, conn.assigns]))
conn conn
|> put_flash(:error, "Failed to set up user account.") |> put_flash(:error, dgettext("errors", "Failed to set up user account."))
|> redirect(external: redirect_uri(conn, params["redirect_uri"])) |> redirect(external: redirect_uri(conn, params["redirect_uri"]))
end end
end end
@ -468,4 +460,8 @@ def default_redirect_uri(%App{} = app) do
|> String.split() |> String.split()
|> Enum.at(0) |> Enum.at(0)
end end
defp render_invalid_credentials_error(conn) do
render_error(conn, :bad_request, "Invalid credentials")
end
end end

View file

@ -245,14 +245,10 @@ defp represent_activity(conn, _, activity, user) do
end end
def errors(conn, {:error, :not_found}) do def errors(conn, {:error, :not_found}) do
conn render_error(conn, :not_found, "Not found")
|> put_status(404)
|> text("Not found")
end end
def errors(conn, _) do def errors(conn, _) do
conn render_error(conn, :internal_server_error, "Something went wrong")
|> put_status(500)
|> text("Something went wrong")
end end
end end

View file

@ -0,0 +1,17 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TranslationHelpers do
defmacro render_error(conn, status, msgid, bindings \\ Macro.escape(%{})) do
quote do
require Pleroma.Web.Gettext
unquote(conn)
|> Plug.Conn.put_status(unquote(status))
|> Phoenix.Controller.json(%{
error: Pleroma.Web.Gettext.dgettext("errors", unquote(msgid), unquote(bindings))
})
end
end
end

View file

@ -12,7 +12,7 @@ def callback(conn, %{"upload_path" => upload_path} = params) do
end end
def callbacks(conn, _) do def callbacks(conn, _) do
send_resp(conn, 400, "bad request") render_error(conn, :bad_request, "bad request")
end end
defp process_callback(conn, pid, params) when is_pid(pid) do defp process_callback(conn, pid, params) when is_pid(pid) do
@ -24,6 +24,6 @@ defp process_callback(conn, pid, params) when is_pid(pid) do
end end
defp process_callback(conn, _, _) do defp process_callback(conn, _, _) do
send_resp(conn, 400, "bad request") render_error(conn, :bad_request, "bad request")
end end
end end

View file

@ -23,9 +23,11 @@ defmodule Pleroma.Web do
def controller do def controller do
quote do quote do
use Phoenix.Controller, namespace: Pleroma.Web use Phoenix.Controller, namespace: Pleroma.Web
import Plug.Conn import Plug.Conn
import Pleroma.Web.Gettext import Pleroma.Web.Gettext
import Pleroma.Web.Router.Helpers import Pleroma.Web.Router.Helpers
import Pleroma.Web.TranslationHelpers
plug(:set_put_layout) plug(:set_put_layout)

View file

@ -34,7 +34,7 @@
"excoveralls": {:hex, :excoveralls, "0.11.1", "dd677fbdd49114fdbdbf445540ec735808250d56b011077798316505064edb2c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.11.1", "dd677fbdd49114fdbdbf445540ec735808250d56b011077798316505064edb2c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, "floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
"gen_smtp": {:hex, :gen_smtp, "0.14.0", "39846a03522456077c6429b4badfd1d55e5e7d0fdfb65e935b7c5e38549d9202", [:rebar3], [], "hexpm"}, "gen_smtp": {:hex, :gen_smtp, "0.14.0", "39846a03522456077c6429b4badfd1d55e5e7d0fdfb65e935b7c5e38549d9202", [:rebar3], [], "hexpm"},
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"}, "gettext": {:hex, :gettext, "0.17.0", "abe21542c831887a2b16f4c94556db9c421ab301aee417b7c4fbde7fbdbe01ec", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"}, "html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},

View file

@ -91,3 +91,375 @@ msgstr ""
msgid "must be equal to %{number}" msgid "must be equal to %{number}"
msgstr "" msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:381
msgid "Account not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:153
msgid "Already voted"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:263
msgid "Bad request"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:254
msgid "Can't delete object"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:569
msgid "Can't delete this post"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1731
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1737
msgid "Can't display this activity"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:195
msgid "Can't find user"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1148
msgid "Can't get favorites"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:263
msgid "Can't like object"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:518
msgid "Cannot post an empty status without attachments"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:461
msgid "Comment must be up to %{max_size} characters"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/config.ex:63
msgid "Config with params %{params} not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:78
msgid "Could not delete"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:110
msgid "Could not favorite"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:310
msgid "Could not pin"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:89
msgid "Could not repeat"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:120
msgid "Could not unfavorite"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:327
msgid "Could not unpin"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:99
msgid "Could not unrepeat"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:392
msgid "Could not update state"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1271
msgid "Error."
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:36
msgid "Invalid CAPTCHA"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1700
#: lib/pleroma/web/oauth/oauth_controller.ex:465
msgid "Invalid credentials"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:20
msgid "Invalid credentials."
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:154
msgid "Invalid indices"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:411
msgid "Invalid parameters"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:377
msgid "Invalid password."
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:163
msgid "Invalid request"
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:16
msgid "Kocaptcha service unavailable"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1696
msgid "Missing parameters"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:496
msgid "No such conversation"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:163
#: lib/pleroma/web/admin_api/admin_api_controller.ex:206
msgid "No such permission_group"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:69
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:311
#: lib/pleroma/web/admin_api/admin_api_controller.ex:399
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:63
#: lib/pleroma/web/ostatus/ostatus_controller.ex:248
msgid "Not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:152
msgid "Poll's author can't vote"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:443
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:444
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:473
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:476
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1180
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1564
msgid "Record not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:417
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1570
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:69
#: lib/pleroma/web/ostatus/ostatus_controller.ex:252
msgid "Something went wrong"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:253
msgid "The message visibility must be direct"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:521
msgid "The status is over the character limit"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:27
msgid "This resource requires authentication."
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/rate_limiter.ex:89
msgid "Throttled"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:155
msgid "Too many choices"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:268
msgid "Unhandled activity type"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/user_is_admin_plug.ex:20
msgid "User is not admin."
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:380
msgid "Valid `account_id` required"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:185
msgid "You can't revoke your own admin status."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:216
msgid "Your account is currently disabled"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:158
#: lib/pleroma/web/oauth/oauth_controller.ex:213
msgid "Your login is missing a confirmed e-mail address"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:221
msgid "can't read inbox of %{nickname} as %{as_nickname}"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:297
msgid "can't update outbox of %{nickname} as %{as_nickname}"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:335
msgid "conversation is already muted"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:192
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:317
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1196
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1247
msgid "error"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:789
msgid "mascots can only be images"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:34
msgid "not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:298
msgid "Bad OAuth request."
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:92
msgid "CAPTCHA already used"
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:89
msgid "CAPTCHA expired"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:50
msgid "Failed"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:314
msgid "Failed to authenticate: %{message}."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:345
msgid "Failed to set up user account."
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/oauth_scopes_plug.ex:37
msgid "Insufficient permissions: %{permissions}."
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:89
msgid "Internal Error"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:22
#: lib/pleroma/web/oauth/fallback_controller.ex:29
msgid "Invalid Username/Password"
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:107
msgid "Invalid answer data"
msgstr ""
#, elixir-format
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:204
msgid "Nodeinfo schema version not handled"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:145
msgid "This action is outside the authorized scopes"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:14
msgid "Unknown error, please check the details and try again."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:93
#: lib/pleroma/web/oauth/oauth_controller.ex:131
msgid "Unlisted redirect_uri."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:294
msgid "Unsupported OAuth provider: %{provider}."
msgstr ""
#, elixir-format
#: lib/pleroma/uploaders/uploader.ex:71
msgid "Uploader callback timeout"
msgstr ""
#, elixir-format
#: lib/pleroma/web/uploader_controller.ex:11
#: lib/pleroma/web/uploader_controller.ex:23
msgid "bad request"
msgstr ""

View file

@ -7,7 +7,6 @@
## Run `mix gettext.extract` to bring this file up to ## Run `mix gettext.extract` to bring this file up to
## date. Leave `msgstr`s empty as changing them here as no ## date. Leave `msgstr`s empty as changing them here as no
## effect: edit them in PO (`.po`) files instead. ## effect: edit them in PO (`.po`) files instead.
## From Ecto.Changeset.cast/4 ## From Ecto.Changeset.cast/4
msgid "can't be blank" msgid "can't be blank"
msgstr "" msgstr ""
@ -89,3 +88,375 @@ msgstr ""
msgid "must be equal to %{number}" msgid "must be equal to %{number}"
msgstr "" msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:381
msgid "Account not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:153
msgid "Already voted"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:263
msgid "Bad request"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:254
msgid "Can't delete object"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:569
msgid "Can't delete this post"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1731
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1737
msgid "Can't display this activity"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:195
msgid "Can't find user"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1148
msgid "Can't get favorites"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:263
msgid "Can't like object"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:518
msgid "Cannot post an empty status without attachments"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:461
msgid "Comment must be up to %{max_size} characters"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/config.ex:63
msgid "Config with params %{params} not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:78
msgid "Could not delete"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:110
msgid "Could not favorite"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:310
msgid "Could not pin"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:89
msgid "Could not repeat"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:120
msgid "Could not unfavorite"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:327
msgid "Could not unpin"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:99
msgid "Could not unrepeat"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:392
msgid "Could not update state"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1271
msgid "Error."
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:36
msgid "Invalid CAPTCHA"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1700
#: lib/pleroma/web/oauth/oauth_controller.ex:465
msgid "Invalid credentials"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:20
msgid "Invalid credentials."
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:154
msgid "Invalid indices"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:411
msgid "Invalid parameters"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:377
msgid "Invalid password."
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:163
msgid "Invalid request"
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:16
msgid "Kocaptcha service unavailable"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1696
msgid "Missing parameters"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:496
msgid "No such conversation"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:163
#: lib/pleroma/web/admin_api/admin_api_controller.ex:206
msgid "No such permission_group"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:69
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:311
#: lib/pleroma/web/admin_api/admin_api_controller.ex:399
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:63
#: lib/pleroma/web/ostatus/ostatus_controller.ex:248
msgid "Not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:152
msgid "Poll's author can't vote"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:443
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:444
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:473
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:476
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1180
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1564
msgid "Record not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:417
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1570
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:69
#: lib/pleroma/web/ostatus/ostatus_controller.ex:252
msgid "Something went wrong"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:253
msgid "The message visibility must be direct"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:521
msgid "The status is over the character limit"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:27
msgid "This resource requires authentication."
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/rate_limiter.ex:89
msgid "Throttled"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:155
msgid "Too many choices"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:268
msgid "Unhandled activity type"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/user_is_admin_plug.ex:20
msgid "User is not admin."
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:380
msgid "Valid `account_id` required"
msgstr ""
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:185
msgid "You can't revoke your own admin status."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:216
msgid "Your account is currently disabled"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:158
#: lib/pleroma/web/oauth/oauth_controller.ex:213
msgid "Your login is missing a confirmed e-mail address"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:221
msgid "can't read inbox of %{nickname} as %{as_nickname}"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:297
msgid "can't update outbox of %{nickname} as %{as_nickname}"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:335
msgid "conversation is already muted"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:192
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:317
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1196
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1247
msgid "error"
msgstr ""
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:789
msgid "mascots can only be images"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:34
msgid "not found"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:298
msgid "Bad OAuth request."
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:92
msgid "CAPTCHA already used"
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:89
msgid "CAPTCHA expired"
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:50
msgid "Failed"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:314
msgid "Failed to authenticate: %{message}."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:345
msgid "Failed to set up user account."
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/oauth_scopes_plug.ex:37
msgid "Insufficient permissions: %{permissions}."
msgstr ""
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:89
msgid "Internal Error"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:22
#: lib/pleroma/web/oauth/fallback_controller.ex:29
msgid "Invalid Username/Password"
msgstr ""
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:107
msgid "Invalid answer data"
msgstr ""
#, elixir-format
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:204
msgid "Nodeinfo schema version not handled"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:145
msgid "This action is outside the authorized scopes"
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:14
msgid "Unknown error, please check the details and try again."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:93
#: lib/pleroma/web/oauth/oauth_controller.ex:131
msgid "Unlisted redirect_uri."
msgstr ""
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:294
msgid "Unsupported OAuth provider: %{provider}."
msgstr ""
#, elixir-format
#: lib/pleroma/uploaders/uploader.ex:71
msgid "Uploader callback timeout"
msgstr ""
#, elixir-format
#: lib/pleroma/web/uploader_controller.ex:11
#: lib/pleroma/web/uploader_controller.ex:23
msgid "bad request"
msgstr ""

View file

@ -0,0 +1,463 @@
## `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: ru\n"
"Plural-Forms: nplurals=3\n"
msgid "can't be blank"
msgstr "не может быть пустым"
msgid "has already been taken"
msgstr "уже занято"
msgid "is invalid"
msgstr "неверный"
msgid "has invalid format"
msgstr "неверный формат"
msgid "has an invalid entry"
msgstr "содержит неверную запись"
msgid "is reserved"
msgstr "занято"
msgid "does not match confirmation"
msgstr "не совпадает"
msgid "is still associated with this entry"
msgstr "по прежнему связан с этой записью"
msgid "are still associated with this entry"
msgstr "по прежнему связаны с этой записью"
msgid "should be %{count} character(s)"
msgid_plural "should be %{count} character(s)"
msgstr[0] "должен состоять из %{count} символа"
msgstr[1] "должен состоять из %{count} символов"
msgstr[2] "должен состоять из %{count} символов"
msgid "should have %{count} item(s)"
msgid_plural "should have %{count} item(s)"
msgstr[0] "должен содержать %{count} элемент"
msgstr[1] "должен содержать %{count} элемента"
msgstr[2] "должен содержать %{count} элементов"
msgid "should be at least %{count} character(s)"
msgid_plural "should be at least %{count} character(s)"
msgstr[0] "должен быть не менее чем %{count} символа"
msgstr[1] "должен быть не менее чем %{count} символов"
msgstr[2] "должен быть не менее чем %{count} символов"
msgid "should have at least %{count} item(s)"
msgid_plural "should have at least %{count} item(s)"
msgstr[0] "должен быть не менее %{count} элемента"
msgstr[1] "должен быть не менее %{count} элементов"
msgstr[2] "должен быть не менее %{count} элементов"
msgid "should be at most %{count} character(s)"
msgid_plural "should be at most %{count} character(s)"
msgstr[0] "должен быть не более %{count} символа"
msgstr[1] "должен быть не более %{count} символов"
msgstr[2] "должен быть не более %{count} символов"
msgid "should have at most %{count} item(s)"
msgid_plural "should have at most %{count} item(s)"
msgstr[0] "должен содержать не менее %{count} элемента"
msgstr[1] "должен содержать не менее %{count} элемента"
msgstr[2] "должен содержать не менее %{count} элементов"
msgid "must be less than %{number}"
msgstr "должен быть меньше %{number}"
msgid "must be greater than %{number}"
msgstr "должен быть больше %{number}"
msgid "must be less than or equal to %{number}"
msgstr "должен быть меньше или равен %{number}"
msgid "must be greater than or equal to %{number}"
msgstr "должен быть больше или равен %{number}"
msgid "must be equal to %{number}"
msgstr "должен быть равным %{number}"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:381
msgid "Account not found"
msgstr "Учетная запись не найдена"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:153
msgid "Already voted"
msgstr "Уже проголосовал(а)"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:263
msgid "Bad request"
msgstr "Неверный запрос"
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:254
msgid "Can't delete object"
msgstr "Произошла ошибка при удалении объекта"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:569
msgid "Can't delete this post"
msgstr "Произошла ошибка при удалении этой записи"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1731
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1737
msgid "Can't display this activity"
msgstr "Произошла ошибка при показе этой записи"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:195
msgid "Can't find user"
msgstr "Пользователь не найден"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1148
msgid "Can't get favorites"
msgstr "Не в состоянии получить избранное"
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:263
msgid "Can't like object"
msgstr "Не могу поставить лайк"
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:518
msgid "Cannot post an empty status without attachments"
msgstr "Нельзя отправить пустой статус без приложений"
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:461
msgid "Comment must be up to %{max_size} characters"
msgstr "Комментарий должен быть не более %{max_size} символов"
#, elixir-format
#: lib/pleroma/web/admin_api/config.ex:63
msgid "Config with params %{params} not found"
msgstr "Параметры конфигурации %{params} не найдены"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:78
msgid "Could not delete"
msgstr "Не в силах удалить"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:110
msgid "Could not favorite"
msgstr "Не в силах добавить в избранное"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:310
msgid "Could not pin"
msgstr "Не в силах прикрепить"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:89
msgid "Could not repeat"
msgstr "Не в силах повторить"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:120
msgid "Could not unfavorite"
msgstr "Не в силах удалить из избранного"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:327
msgid "Could not unpin"
msgstr "Не в силах открепить"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:99
msgid "Could not unrepeat"
msgstr "Не в силах отменить повтор"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:392
msgid "Could not update state"
msgstr "Не в силах обновить состояние"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1271
msgid "Error."
msgstr "Ошибка"
#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:36
msgid "Invalid CAPTCHA"
msgstr "Неверная CAPTCHA"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1700
#: lib/pleroma/web/oauth/oauth_controller.ex:465
msgid "Invalid credentials"
msgstr "Неверные учетные данные"
#, elixir-format
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:20
msgid "Invalid credentials."
msgstr "Неверные учетные данные"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:154
msgid "Invalid indices"
msgstr "Неверные индексы"
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:411
msgid "Invalid parameters"
msgstr "Неверны параметры"
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:377
msgid "Invalid password."
msgstr "Неверный пароль"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:163
msgid "Invalid request"
msgstr "Неверный запрос"
#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:16
msgid "Kocaptcha service unavailable"
msgstr "Kocaptcha недоступен"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1696
msgid "Missing parameters"
msgstr "Не хватает параметров"
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:496
msgid "No such conversation"
msgstr "Разговор не найден"
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:163
#: lib/pleroma/web/admin_api/admin_api_controller.ex:206
msgid "No such permission_group"
msgstr "Такой группы полномочий не существует"
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:69
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:311
#: lib/pleroma/web/admin_api/admin_api_controller.ex:399
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:63
#: lib/pleroma/web/ostatus/ostatus_controller.ex:248
msgid "Not found"
msgstr "Не найден"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:152
msgid "Poll's author can't vote"
msgstr "Автор опроса не может голосовать"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:443
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:444
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:473
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:476
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1180
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1564
msgid "Record not found"
msgstr "Запись не найдена"
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:417
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1570
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:69
#: lib/pleroma/web/ostatus/ostatus_controller.ex:252
msgid "Something went wrong"
msgstr "Что-то пошло не так"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:253
msgid "The message visibility must be direct"
msgstr "Видимость у сообщения должна быть `Личное`"
#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:521
msgid "The status is over the character limit"
msgstr "Превышена длина статуса"
#, elixir-format
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:27
msgid "This resource requires authentication."
msgstr "Для этого ресурса требуется аутентификация"
#, elixir-format
#: lib/pleroma/plugs/rate_limiter.ex:89
msgid "Throttled"
msgstr "Ограничено. Превышен лимит запросов."
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:155
msgid "Too many choices"
msgstr "Слишком много ответов"
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:268
msgid "Unhandled activity type"
msgstr "Неизвестный тип activity"
#, elixir-format
#: lib/pleroma/plugs/user_is_admin_plug.ex:20
msgid "User is not admin."
msgstr "Пользователь не обладает правами администратора"
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:380
msgid "Valid `account_id` required"
msgstr "Требуется корректный `account_id`"
#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:185
msgid "You can't revoke your own admin status."
msgstr "Вы не можете отозвать статус администратора у вашей учетной записи"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:216
msgid "Your account is currently disabled"
msgstr "Ваша учетная запись отключена"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:158
#: lib/pleroma/web/oauth/oauth_controller.ex:213
msgid "Your login is missing a confirmed e-mail address"
msgstr "Ваш e-mail адрес не подтвержден"
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:221
msgid "can't read inbox of %{nickname} as %{as_nickname}"
msgstr ""
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:297
msgid "can't update outbox of %{nickname} as %{as_nickname}"
msgstr ""
#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:335
msgid "conversation is already muted"
msgstr "разговор уже игнорируется"
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:192
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:317
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1196
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1247
msgid "error"
msgstr "ошибка"
#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:789
msgid "mascots can only be images"
msgstr "маскоты должны быть картинками"
#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:34
msgid "not found"
msgstr "не найдено"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:298
msgid "Bad OAuth request."
msgstr "Неверный OAuth запрос"
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:92
msgid "CAPTCHA already used"
msgstr "CAPTCHA уже использована"
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:89
msgid "CAPTCHA expired"
msgstr "CAPTCHA устарела"
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:50
msgid "Failed"
msgstr "Ошибка"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:314
msgid "Failed to authenticate: %{message}."
msgstr "Ошибка при входе: %{message}"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:345
msgid "Failed to set up user account."
msgstr "Ошибка при создании учетной записи"
#, elixir-format
#: lib/pleroma/plugs/oauth_scopes_plug.ex:37
msgid "Insufficient permissions: %{permissions}."
msgstr "Недостаточно полномочий: %{permissions}"
#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:89
msgid "Internal Error"
msgstr "Внутренняя ошибка"
#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:22
#: lib/pleroma/web/oauth/fallback_controller.ex:29
msgid "Invalid Username/Password"
msgstr "Неверное имя пользователя или пароль"
#, elixir-format
#: lib/pleroma/captcha/captcha.ex:107
msgid "Invalid answer data"
msgstr "Неверный ответ"
#, elixir-format
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:204
msgid "Nodeinfo schema version not handled"
msgstr "Версия схемы Nodeinfo не учитывается"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:145
msgid "This action is outside the authorized scopes"
msgstr "Это действие выходит за рамки доступных полномочий"
#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:14
msgid "Unknown error, please check the details and try again."
msgstr "Неизвестная ошибка. Пожалуйста, проверьте данные и попробуйте снова."
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:93
#: lib/pleroma/web/oauth/oauth_controller.ex:131
msgid "Unlisted redirect_uri."
msgstr "Неизвестный redirect_uri"
#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:294
msgid "Unsupported OAuth provider: %{provider}."
msgstr "Неизвестный OAuth провайдер: %{provider}"
#, elixir-format
#: lib/pleroma/uploaders/uploader.ex:71
msgid "Uploader callback timeout"
msgstr "Тайм-аут при загрузке"
#, elixir-format
#: lib/pleroma/web/uploader_controller.ex:11
#: lib/pleroma/web/uploader_controller.ex:23
msgid "bad request"
msgstr "неправильный запрос"

View file

@ -0,0 +1,46 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.SetLocalePlugTest do
use ExUnit.Case, async: true
use Plug.Test
alias Pleroma.Plugs.SetLocalePlug
alias Plug.Conn
test "default locale is `en`" do
conn =
:get
|> conn("/cofe")
|> SetLocalePlug.call([])
assert "en" == Gettext.get_locale()
assert %{locale: "en"} == conn.assigns
end
test "use supported locale from `accept-language`" do
conn =
:get
|> conn("/cofe")
|> Conn.put_req_header(
"accept-language",
"ru, fr-CH, fr;q=0.9, en;q=0.8, *;q=0.5"
)
|> SetLocalePlug.call([])
assert "ru" == Gettext.get_locale()
assert %{locale: "ru"} == conn.assigns
end
test "use default locale if locale from `accept-language` is not supported" do
conn =
:get
|> conn("/cofe")
|> Conn.put_req_header("accept-language", "tlh")
|> SetLocalePlug.call([])
assert "en" == Gettext.get_locale()
assert %{locale: "en"} == conn.assigns
end
end