Merge remote-tracking branch 'upstream/develop' into neckbeard
This commit is contained in:
commit
1a3dac6188
|
@ -30,7 +30,7 @@ defmodule Pleroma.Activity.Search 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 @@ defmodule Pleroma.Activity.Search 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
|
||||
|
|
|
@ -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 @@ defmodule Pleroma.User.Backup 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)
|
||||
|
|
|
@ -502,9 +502,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub 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)
|
||||
|
@ -604,9 +613,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
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
|
||||
|
||||
|
@ -693,8 +704,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub 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
|
||||
|
|
|
@ -84,7 +84,10 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|
|||
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
|
||||
|
|
|
@ -112,6 +112,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController 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
|
||||
|
|
|
@ -37,10 +37,7 @@ defmodule Pleroma.Workers.BackupWorker do
|
|||
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 +48,23 @@ defmodule Pleroma.Workers.BackupWorker do
|
|||
nil -> :ok
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -3,7 +3,7 @@ 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-22 19:00+0000\n"
|
||||
"PO-Revision-Date: 2022-07-24 10:04+0000\n"
|
||||
"Last-Translator: Yating Zhan <thestrandedvalley@protonmail.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <http://weblate.pleroma-dev.ebin.club/"
|
||||
"projects/pleroma/pleroma-backend-domain-config_descriptions/zh_Hans/>\n"
|
||||
|
@ -419,13 +419,13 @@ msgstr "包含不能直接被「Oban」解读的自定工人选项"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-ConcurrentLimiter"
|
||||
msgid "Limits configuration for background tasks."
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "[Oban](https://github.com/sorentwo/oban) 异步工作处理器的配置。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -438,12 +438,15 @@ msgstr "验证码相关设定"
|
|||
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 ""
|
||||
msgstr "邮递员相关设置"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -491,13 +494,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-Pleroma.Uploaders.Local"
|
||||
msgid "Local uploader-related settings"
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "S3 上传器相关设置"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -509,7 +512,7 @@ msgstr "账户备份"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-Pleroma.Web.MediaProxy.Invalidation.Http"
|
||||
msgid "HTTP invalidate settings"
|
||||
msgstr ""
|
||||
msgstr "HTTP 无效化设置"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -557,19 +560,19 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :ex_aws-:s3"
|
||||
msgid "S3"
|
||||
msgstr ""
|
||||
msgstr "S3"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :logger-:console"
|
||||
msgid "Console Logger"
|
||||
msgstr ""
|
||||
msgstr "终端日志器"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :logger-:ex_syslogger"
|
||||
msgid "ExSyslogger"
|
||||
msgstr ""
|
||||
msgstr "ExSyslogger"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -593,7 +596,7 @@ msgstr "验证"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-:connections_pool"
|
||||
msgid "Connections pool"
|
||||
msgstr ""
|
||||
msgstr "连接池"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -731,7 +734,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-:mrf_hashtag"
|
||||
msgid "MRF Hashtag"
|
||||
msgstr ""
|
||||
msgstr "MRF 标签"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -875,7 +878,7 @@ msgstr "欢迎"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-:workers"
|
||||
msgid "Workers"
|
||||
msgstr ""
|
||||
msgstr "工人"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1121,7 +1124,7 @@ msgstr "日志等级"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma > :admin_token"
|
||||
msgid "Admin token"
|
||||
msgstr ""
|
||||
msgstr "管理令牌"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1157,7 +1160,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:activitypub > :unfollow_blocked"
|
||||
msgid "Whether blocks result in people getting unfollowed"
|
||||
msgstr ""
|
||||
msgstr "屏蔽对象时是否同时取消对其的关注"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1169,7 +1172,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:assets > :default_user_avatar"
|
||||
msgid "URL of the default user avatar"
|
||||
msgstr ""
|
||||
msgstr "默认用户头像的网址"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1205,7 +1208,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:connections_pool > :connect_timeout"
|
||||
msgid "Timeout while `gun` will wait until connection is up. Default: 5000ms."
|
||||
msgstr ""
|
||||
msgstr "「Gun」等待连接时触发超时的上限。默认为5000ms。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1253,7 +1256,7 @@ msgstr "非活跃用户数量最低门槛"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:email_notifications > :digest > :interval"
|
||||
msgid "Minimum interval between digest emails to one user"
|
||||
msgstr "单个用户能收到摘要邮件的间隔频次"
|
||||
msgstr "单个用户每次收到摘要邮件的间隔"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1301,7 +1304,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:feed > :post_title > :max_length"
|
||||
msgid "Maximum number of characters before truncating title"
|
||||
msgstr "不被折叠的用户名的字符上限"
|
||||
msgstr "不被折叠的用户名的字数上限"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1325,7 +1328,7 @@ msgstr "当被停用时,自动隐藏未被填写的标题栏"
|
|||
#, 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 ""
|
||||
msgstr "输入背景的网址,若浏览已设定背景的用户资料时此处将不生效"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1392,7 +1395,8 @@ msgstr ""
|
|||
#, 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 ""
|
||||
msgstr "可见范围选项将只保留私信与用户默认,或是跟随被回复帖文的设定。这能够帮助 "
|
||||
"Pleroma FE 的用户不会意外将对私信的回复设置为公开。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1422,7 +1426,7 @@ msgstr ""
|
|||
#, 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 ""
|
||||
msgstr "回复的可见范围(仅关注者/不公开/公开)将默认跟随原贴文的设定"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1440,7 +1444,7 @@ msgstr "是否展示该实例的自定义面板"
|
|||
#, 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 ""
|
||||
msgstr "将面板与侧栏向右对齐"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1452,19 +1456,19 @@ msgstr ""
|
|||
#, 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 中已限定了可用主题"
|
||||
msgstr "使用某个主题。styles.json 中已限定了可用的主题"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:frontends > :admin"
|
||||
msgid "Admin frontend"
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "已安装的前端名称。只有包含了「名称」与「引用」数值才能被算作有效配置。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1506,7 +1510,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:frontends > :available > name"
|
||||
msgid "Name of the frontend."
|
||||
msgstr ""
|
||||
msgstr "前端名称。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1524,7 +1528,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:frontends > :primary > name"
|
||||
msgid "Name of the installed frontend. Valid config must include both `Name` and `Reference` values."
|
||||
msgstr ""
|
||||
msgstr "已安装的前端名称。只有包含了「名称」与「引用」数值才能被算作有效配置。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1542,13 +1546,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:gopher > :enabled"
|
||||
msgid "Enables the gopher interface"
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "指定绑定IP地址"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1566,7 +1570,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:hackney_pools > :federation > :max_connections"
|
||||
msgid "Number workers in the pool."
|
||||
msgstr ""
|
||||
msgstr "池内的工人数量。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1578,13 +1582,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:hackney_pools > :media"
|
||||
msgid "Settings for media pool."
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "池内的工人数量。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1632,7 +1636,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:http > :proxy_url"
|
||||
msgid "Proxy URL"
|
||||
msgstr "代理地址"
|
||||
msgstr "代理网址"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1680,7 +1684,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :account_activation_required"
|
||||
msgid "Require users to confirm their emails before signing in"
|
||||
msgstr ""
|
||||
msgstr "要求用户登陆时必须确认邮件"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1692,13 +1696,13 @@ msgstr "用户登陆需要管理员同意"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :account_field_name_length"
|
||||
msgid "An account field name maximum length. Default: 512."
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "单个用户信息内容的字数上限。默认为2048。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1716,19 +1720,19 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :attachment_links"
|
||||
msgid "Enable to automatically add attachment link text to statuses"
|
||||
msgstr ""
|
||||
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 "为一个会被新用户自动关注的(本地)用户设定昵称"
|
||||
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 ""
|
||||
msgstr "为会自动关注每一个新用户的(本地)用户设定昵称"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1758,7 +1762,7 @@ msgstr "创建账户的最低年龄限制。只有当需要输入生日时才生
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :birthday_required"
|
||||
msgid "Require users to enter their birthday."
|
||||
msgstr ""
|
||||
msgstr "要求用户输入出生日期。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1788,7 +1792,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :external_user_synchronization"
|
||||
msgid "Enabling following/followers counters synchronization for external users"
|
||||
msgstr ""
|
||||
msgstr "为外部用户启用对关注者与正在关注数量的同步"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1809,10 +1813,10 @@ msgid "Timeout (in days) of each external federation target being unreachable pr
|
|||
msgstr ""
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
#, 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 ""
|
||||
msgstr "若启用,「/api/pleroma/healthcheck」下将显示系统数据"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1824,13 +1828,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :invites_enabled"
|
||||
msgid "Enable user invitations for admins (depends on `registrations_open` being disabled)"
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "贴文字数上限(内容警告/标题包含在内)"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1842,13 +1846,13 @@ msgstr ""
|
|||
#, 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 ""
|
||||
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 ""
|
||||
msgstr "推荐账户的最大数量。设置为0将关闭该功能。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1920,7 +1924,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :name"
|
||||
msgid "Name of the instance"
|
||||
msgstr ""
|
||||
msgstr "实例名称"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1938,13 +1942,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :poll_limits > :max_expiration"
|
||||
msgid "Maximum expiration time (in seconds)"
|
||||
msgstr ""
|
||||
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 "单个选项的字符上限"
|
||||
msgstr "单个选项的字数上限"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1956,13 +1960,14 @@ msgstr "选项数量上限"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :poll_limits > :min_expiration"
|
||||
msgid "Minimum expiration time (in seconds)"
|
||||
msgstr ""
|
||||
msgstr "最小有效时间(以秒为单位)"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
#, 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 ""
|
||||
msgstr "允许管理员访问敏感信息(例,更新用户凭据、取得密码重置令牌、删除用户、能够索"
|
||||
"引并阅览私密状态与聊天信息)"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -1986,13 +1991,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :registration_reason_length"
|
||||
msgid "Maximum registration reason length. Default: 500."
|
||||
msgstr "注册申请理由的字符上限。默认为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 ""
|
||||
msgstr "开放注册。若要启用邀请制注册则需关闭此项。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -2011,12 +2016,14 @@ msgstr ""
|
|||
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
|
||||
#, 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 ""
|
||||
msgstr "允许通过此API来看见喜欢数量与表情反应。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -2034,25 +2041,25 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:instance > :upload_limit"
|
||||
msgid "File size limit of uploads (except for avatar, background, banner)"
|
||||
msgstr ""
|
||||
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。"
|
||||
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。"
|
||||
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 ""
|
||||
msgstr "允许/不允许获取并展示实例图标"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -2148,13 +2155,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:manifest > :icons"
|
||||
msgid "Describe the icons of the app"
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "描述此应用的主题颜色"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -2184,13 +2191,13 @@ msgstr ""
|
|||
#, 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 ""
|
||||
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 ""
|
||||
msgstr "图像的生成预览缩略图的宽度上限(视频预览则始终保持原始尺寸)。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -2352,13 +2359,13 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:mrf_rejectnonpublic > :allow_direct"
|
||||
msgid "Whether to allow direct messages"
|
||||
msgstr ""
|
||||
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 ""
|
||||
msgstr "是否允许仅限关注者的帖文"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -2526,7 +2533,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config description at :pleroma-:pools > :media"
|
||||
msgid "Settings for media pool."
|
||||
msgstr ""
|
||||
msgstr "媒体池设定。"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -5472,7 +5479,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-Pleroma.Captcha.Kocaptcha > :endpoint"
|
||||
msgid "Endpoint"
|
||||
msgstr ""
|
||||
msgstr "终点"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -5562,7 +5569,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-Pleroma.Emails.Mailer > Swoosh.Adapters.SMTP-:password"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
msgstr "密码"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -5694,7 +5701,7 @@ msgstr "链接颜色"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-Pleroma.Emails.UserEmail > :styling > :text_color"
|
||||
msgid "Text color"
|
||||
msgstr ""
|
||||
msgstr "文本颜色"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
@ -5952,7 +5959,7 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgctxt "config label at :pleroma-Pleroma.Workers.PurgeExpiredActivity > :enabled"
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
msgstr "已启用"
|
||||
|
||||
#: lib/pleroma/docs/translator.ex:5
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
|
@ -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
|
|
@ -18,6 +18,23 @@ defmodule Pleroma.Activity.SearchTest 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)
|
||||
|
|
|
@ -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 @@ defmodule Pleroma.User.BackupTest 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)
|
||||
|
|
|
@ -247,6 +247,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest 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 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest 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)
|
||||
|
|
|
@ -408,6 +408,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest 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"])
|
||||
|
|
|
@ -79,6 +79,51 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest 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 =
|
||||
|
|
|
@ -1901,23 +1901,50 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest 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
|
||||
|
|
|
@ -367,6 +367,47 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest 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
|
||||
|
|
|
@ -82,4 +82,24 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest 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:accounts"], 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
|
||||
|
|
Loading…
Reference in New Issue