Merge branch 'develop' into 'remove-avatar-header'
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
a0c65bbd6c
237 changed files with 8534 additions and 2226 deletions
|
|
@ -11,9 +11,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
alias Pleroma.Conversation.Participation
|
||||
alias Pleroma.Filter
|
||||
alias Pleroma.Formatter
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.Pagination
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
|
|
@ -46,16 +46,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
|
||||
require Logger
|
||||
|
||||
plug(
|
||||
Pleroma.Plugs.RateLimitPlug,
|
||||
%{
|
||||
max_requests: Config.get([:app_account_creation, :max_requests]),
|
||||
interval: Config.get([:app_account_creation, :interval])
|
||||
}
|
||||
when action in [:account_register]
|
||||
)
|
||||
plug(Pleroma.Plugs.RateLimiter, :app_account_creation when action == :account_register)
|
||||
plug(Pleroma.Plugs.RateLimiter, :search when action in [:search, :search2, :account_search])
|
||||
|
||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||
@local_mastodon_name "Mastodon-Local"
|
||||
|
||||
action_fallback(:errors)
|
||||
|
|
@ -117,13 +110,24 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
|> Enum.dedup()
|
||||
|
||||
info_params =
|
||||
[:no_rich_text, :locked, :hide_followers, :hide_follows, :hide_favorites, :show_role]
|
||||
[
|
||||
:no_rich_text,
|
||||
:locked,
|
||||
:hide_followers,
|
||||
:hide_follows,
|
||||
:hide_favorites,
|
||||
:show_role,
|
||||
:skip_thread_containment
|
||||
]
|
||||
|> Enum.reduce(%{}, fn key, acc ->
|
||||
add_if_present(acc, params, to_string(key), key, fn value ->
|
||||
{:ok, ControllerHelper.truthy_param?(value)}
|
||||
end)
|
||||
end)
|
||||
|> add_if_present(params, "default_scope", :default_scope)
|
||||
|> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
|
||||
{:ok, Map.merge(user.info.pleroma_settings_store, value)}
|
||||
end)
|
||||
|> add_if_present(params, "header", :banner, fn value ->
|
||||
with %Plug.Upload{} <- value,
|
||||
{:ok, object} <- ActivityPub.upload(value, type: :banner) do
|
||||
|
|
@ -132,6 +136,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
_ -> :error
|
||||
end
|
||||
end)
|
||||
|> add_if_present(params, "pleroma_background_image", :background, fn value ->
|
||||
with %Plug.Upload{} <- value,
|
||||
{:ok, object} <- ActivityPub.upload(value, type: :background) do
|
||||
{:ok, object.data}
|
||||
else
|
||||
_ -> :error
|
||||
end
|
||||
end)
|
||||
|> Map.put(:emoji, user_info_emojis)
|
||||
|
||||
info_cng = User.Info.profile_update(user.info, info_params)
|
||||
|
|
@ -143,7 +155,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
CommonAPI.update(user)
|
||||
end
|
||||
|
||||
json(conn, AccountView.render("account.json", %{user: user, for: user}))
|
||||
json(
|
||||
conn,
|
||||
AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true})
|
||||
)
|
||||
else
|
||||
_e ->
|
||||
conn
|
||||
|
|
@ -216,7 +231,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
end
|
||||
|
||||
def verify_credentials(%{assigns: %{user: user}} = conn, _) do
|
||||
account = AccountView.render("account.json", %{user: user, for: user})
|
||||
chat_token = Phoenix.Token.sign(conn, "user socket", user.id)
|
||||
|
||||
account =
|
||||
AccountView.render("account.json", %{
|
||||
user: user,
|
||||
for: user,
|
||||
with_pleroma_settings: true,
|
||||
with_chat_token: chat_token
|
||||
})
|
||||
|
||||
json(conn, account)
|
||||
end
|
||||
|
||||
|
|
@ -260,7 +284,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
languages: ["en"],
|
||||
registrations: Pleroma.Config.get([:instance, :registrations_open]),
|
||||
# Extra (not present in Mastodon):
|
||||
max_toot_chars: Keyword.get(instance, :limit)
|
||||
max_toot_chars: Keyword.get(instance, :limit),
|
||||
poll_limits: Keyword.get(instance, :poll_limits)
|
||||
}
|
||||
|
||||
json(conn, response)
|
||||
|
|
@ -472,6 +497,67 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
end
|
||||
end
|
||||
|
||||
def get_poll(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||
with %Object{} = object <- Object.get_by_id(id),
|
||||
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
|
||||
true <- Visibility.visible_for_user?(activity, user) do
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> try_render("poll.json", %{object: object, for: user})
|
||||
else
|
||||
nil ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Record not found"})
|
||||
|
||||
false ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Record not found"})
|
||||
end
|
||||
end
|
||||
|
||||
defp get_cached_vote_or_vote(user, object, choices) do
|
||||
idempotency_key = "polls:#{user.id}:#{object.data["id"]}"
|
||||
|
||||
{_, res} =
|
||||
Cachex.fetch(:idempotency_cache, idempotency_key, fn _ ->
|
||||
case CommonAPI.vote(user, object, choices) do
|
||||
{:error, _message} = res -> {:ignore, res}
|
||||
res -> {:commit, res}
|
||||
end
|
||||
end)
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def poll_vote(%{assigns: %{user: user}} = conn, %{"id" => id, "choices" => choices}) do
|
||||
with %Object{} = object <- Object.get_by_id(id),
|
||||
true <- object.data["type"] == "Question",
|
||||
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
|
||||
true <- Visibility.visible_for_user?(activity, user),
|
||||
{:ok, _activities, object} <- get_cached_vote_or_vote(user, object, choices) do
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> try_render("poll.json", %{object: object, for: user})
|
||||
else
|
||||
nil ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Record not found"})
|
||||
|
||||
false ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Record not found"})
|
||||
|
||||
{:error, message} ->
|
||||
conn
|
||||
|> put_status(422)
|
||||
|> json(%{error: message})
|
||||
end
|
||||
end
|
||||
|
||||
def scheduled_statuses(%{assigns: %{user: user}} = conn, params) do
|
||||
with scheduled_activities <- MastodonAPI.get_scheduled_activities(user, params) do
|
||||
conn
|
||||
|
|
@ -521,26 +607,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
end
|
||||
end
|
||||
|
||||
def post_status(conn, %{"status" => "", "media_ids" => media_ids} = params)
|
||||
when length(media_ids) > 0 do
|
||||
params =
|
||||
params
|
||||
|> Map.put("status", ".")
|
||||
|
||||
post_status(conn, params)
|
||||
end
|
||||
|
||||
def post_status(%{assigns: %{user: user}} = conn, %{"status" => _} = params) do
|
||||
params =
|
||||
params
|
||||
|> Map.put("in_reply_to_status_id", params["in_reply_to_id"])
|
||||
|
||||
idempotency_key =
|
||||
case get_req_header(conn, "idempotency-key") do
|
||||
[key] -> key
|
||||
_ -> Ecto.UUID.generate()
|
||||
end
|
||||
|
||||
scheduled_at = params["scheduled_at"]
|
||||
|
||||
if scheduled_at && ScheduledActivity.far_enough?(scheduled_at) do
|
||||
|
|
@ -553,17 +624,40 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
else
|
||||
params = Map.drop(params, ["scheduled_at"])
|
||||
|
||||
{:ok, activity} =
|
||||
Cachex.fetch!(:idempotency_cache, idempotency_key, fn _ ->
|
||||
CommonAPI.post(user, params)
|
||||
end)
|
||||
case get_cached_status_or_post(conn, params) do
|
||||
{:ignore, message} ->
|
||||
conn
|
||||
|> put_status(422)
|
||||
|> json(%{error: message})
|
||||
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
||||
{:error, message} ->
|
||||
conn
|
||||
|> put_status(422)
|
||||
|> json(%{error: message})
|
||||
|
||||
{_, activity} ->
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp get_cached_status_or_post(%{assigns: %{user: user}} = conn, params) do
|
||||
idempotency_key =
|
||||
case get_req_header(conn, "idempotency-key") do
|
||||
[key] -> key
|
||||
_ -> Ecto.UUID.generate()
|
||||
end
|
||||
|
||||
Cachex.fetch(:idempotency_cache, idempotency_key, fn _ ->
|
||||
case CommonAPI.post(user, params) do
|
||||
{:ok, activity} -> activity
|
||||
{:error, message} -> {:ignore, message}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||
with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
|
||||
json(conn, %{})
|
||||
|
|
@ -1107,114 +1201,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
end
|
||||
end
|
||||
|
||||
def status_search_query_with_gin(q, query) do
|
||||
from([a, o] in q,
|
||||
where:
|
||||
fragment(
|
||||
"to_tsvector('english', ?->>'content') @@ plainto_tsquery('english', ?)",
|
||||
o.data,
|
||||
^query
|
||||
),
|
||||
order_by: [desc: :id]
|
||||
)
|
||||
end
|
||||
|
||||
def status_search_query_with_rum(q, query) do
|
||||
from([a, o] in q,
|
||||
where:
|
||||
fragment(
|
||||
"? @@ plainto_tsquery('english', ?)",
|
||||
o.fts_content,
|
||||
^query
|
||||
),
|
||||
order_by: [fragment("? <=> now()::date", o.inserted_at)]
|
||||
)
|
||||
end
|
||||
|
||||
def status_search(user, query) do
|
||||
fetched =
|
||||
if Regex.match?(~r/https?:/, query) do
|
||||
with {:ok, object} <- Fetcher.fetch_object_from_id(query),
|
||||
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
|
||||
true <- Visibility.visible_for_user?(activity, user) do
|
||||
[activity]
|
||||
else
|
||||
_e -> []
|
||||
end
|
||||
end || []
|
||||
|
||||
q =
|
||||
from([a, o] in Activity.with_preloaded_object(Activity),
|
||||
where: fragment("?->>'type' = 'Create'", a.data),
|
||||
where: "https://www.w3.org/ns/activitystreams#Public" in a.recipients,
|
||||
limit: 20
|
||||
)
|
||||
|
||||
q =
|
||||
if Pleroma.Config.get([:database, :rum_enabled]) do
|
||||
status_search_query_with_rum(q, query)
|
||||
else
|
||||
status_search_query_with_gin(q, query)
|
||||
end
|
||||
|
||||
Repo.all(q) ++ fetched
|
||||
end
|
||||
|
||||
def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||
accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
|
||||
|
||||
statuses = status_search(user, query)
|
||||
|
||||
tags_path = Web.base_url() <> "/tag/"
|
||||
|
||||
tags =
|
||||
query
|
||||
|> String.split()
|
||||
|> Enum.uniq()
|
||||
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
||||
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
||||
|> Enum.map(fn tag -> %{name: tag, url: tags_path <> tag} end)
|
||||
|
||||
res = %{
|
||||
"accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
|
||||
"statuses" =>
|
||||
StatusView.render("index.json", activities: statuses, for: user, as: :activity),
|
||||
"hashtags" => tags
|
||||
}
|
||||
|
||||
json(conn, res)
|
||||
end
|
||||
|
||||
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||
accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
|
||||
|
||||
statuses = status_search(user, query)
|
||||
|
||||
tags =
|
||||
query
|
||||
|> String.split()
|
||||
|> Enum.uniq()
|
||||
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
||||
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
||||
|
||||
res = %{
|
||||
"accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
|
||||
"statuses" =>
|
||||
StatusView.render("index.json", activities: statuses, for: user, as: :activity),
|
||||
"hashtags" => tags
|
||||
}
|
||||
|
||||
json(conn, res)
|
||||
end
|
||||
|
||||
def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||
accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
|
||||
|
||||
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
|
||||
|
||||
json(conn, res)
|
||||
end
|
||||
|
||||
def favourites(%{assigns: %{user: user}} = conn, params) do
|
||||
params =
|
||||
params
|
||||
|
|
@ -1409,8 +1395,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
accounts =
|
||||
Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user}))
|
||||
|
||||
flavour = get_user_flavour(user)
|
||||
|
||||
initial_state =
|
||||
%{
|
||||
meta: %{
|
||||
|
|
@ -1429,6 +1413,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
max_toot_chars: limit,
|
||||
mascot: User.get_mascot(user)["url"]
|
||||
},
|
||||
poll_limits: Config.get([:instance, :poll_limits]),
|
||||
rights: %{
|
||||
delete_others_notice: present?(user.info.is_moderator),
|
||||
admin: present?(user.info.is_admin)
|
||||
|
|
@ -1496,7 +1481,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
conn
|
||||
|> put_layout(false)
|
||||
|> put_view(MastodonView)
|
||||
|> render("index.html", %{initial_state: initial_state, flavour: flavour})
|
||||
|> render("index.html", %{initial_state: initial_state})
|
||||
else
|
||||
conn
|
||||
|> put_session(:return_to, conn.request_path)
|
||||
|
|
@ -1519,43 +1504,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
end
|
||||
end
|
||||
|
||||
@supported_flavours ["glitch", "vanilla"]
|
||||
|
||||
def set_flavour(%{assigns: %{user: user}} = conn, %{"flavour" => flavour} = _params)
|
||||
when flavour in @supported_flavours do
|
||||
flavour_cng = User.Info.mastodon_flavour_update(user.info, flavour)
|
||||
|
||||
with changeset <- Ecto.Changeset.change(user),
|
||||
changeset <- Ecto.Changeset.put_embed(changeset, :info, flavour_cng),
|
||||
{:ok, user} <- User.update_and_set_cache(changeset),
|
||||
flavour <- user.info.flavour do
|
||||
json(conn, flavour)
|
||||
else
|
||||
e ->
|
||||
conn
|
||||
|> put_resp_content_type("application/json")
|
||||
|> send_resp(500, Jason.encode!(%{"error" => inspect(e)}))
|
||||
end
|
||||
end
|
||||
|
||||
def set_flavour(conn, _params) do
|
||||
conn
|
||||
|> put_status(400)
|
||||
|> json(%{error: "Unsupported flavour"})
|
||||
end
|
||||
|
||||
def get_flavour(%{assigns: %{user: user}} = conn, _params) do
|
||||
json(conn, get_user_flavour(user))
|
||||
end
|
||||
|
||||
defp get_user_flavour(%User{info: %{flavour: flavour}}) when flavour in @supported_flavours do
|
||||
flavour
|
||||
end
|
||||
|
||||
defp get_user_flavour(_) do
|
||||
"glitch"
|
||||
end
|
||||
|
||||
def login(%{assigns: %{user: %User{}}} = conn, _params) do
|
||||
redirect(conn, to: local_mastodon_root_path(conn))
|
||||
end
|
||||
|
|
@ -1754,7 +1702,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
|> String.replace("{{user}}", user)
|
||||
|
||||
with {:ok, %{status: 200, body: body}} <-
|
||||
@httpoison.get(
|
||||
HTTP.get(
|
||||
url,
|
||||
[],
|
||||
adapter: [
|
||||
|
|
|
|||
79
lib/pleroma/web/mastodon_api/search_controller.ex
Normal file
79
lib/pleroma/web/mastodon_api/search_controller.ex
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.SearchController do
|
||||
use Pleroma.Web, :controller
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
alias Pleroma.Web.ControllerHelper
|
||||
|
||||
require Logger
|
||||
|
||||
plug(Pleroma.Plugs.RateLimiter, :search when action in [:search, :search2, :account_search])
|
||||
|
||||
def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||
accounts = User.search(query, search_options(params, user))
|
||||
statuses = Activity.search(user, query)
|
||||
tags_path = Web.base_url() <> "/tag/"
|
||||
|
||||
tags =
|
||||
query
|
||||
|> String.split()
|
||||
|> Enum.uniq()
|
||||
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
||||
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
||||
|> Enum.map(fn tag -> %{name: tag, url: tags_path <> tag} end)
|
||||
|
||||
res = %{
|
||||
"accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
|
||||
"statuses" =>
|
||||
StatusView.render("index.json", activities: statuses, for: user, as: :activity),
|
||||
"hashtags" => tags
|
||||
}
|
||||
|
||||
json(conn, res)
|
||||
end
|
||||
|
||||
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||
accounts = User.search(query, search_options(params, user))
|
||||
statuses = Activity.search(user, query)
|
||||
|
||||
tags =
|
||||
query
|
||||
|> String.split()
|
||||
|> Enum.uniq()
|
||||
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
||||
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
||||
|
||||
res = %{
|
||||
"accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
|
||||
"statuses" =>
|
||||
StatusView.render("index.json", activities: statuses, for: user, as: :activity),
|
||||
"hashtags" => tags
|
||||
}
|
||||
|
||||
json(conn, res)
|
||||
end
|
||||
|
||||
def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||
accounts = User.search(query, search_options(params, user))
|
||||
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
|
||||
|
||||
json(conn, res)
|
||||
end
|
||||
|
||||
defp search_options(params, user) do
|
||||
[
|
||||
resolve: params["resolve"] == "true",
|
||||
following: params["following"] == "true",
|
||||
limit: ControllerHelper.fetch_integer_param(params, "limit"),
|
||||
offset: ControllerHelper.fetch_integer_param(params, "offset"),
|
||||
for_user: user
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
@ -66,6 +66,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
end
|
||||
|
||||
defp do_render("account.json", %{user: user} = opts) do
|
||||
display_name = HTML.strip_tags(user.name || user.nickname)
|
||||
|
||||
image = User.avatar_url(user) |> MediaProxy.url()
|
||||
header = User.banner_url(user) |> MediaProxy.url()
|
||||
user_info = User.get_cached_user_info(user)
|
||||
|
|
@ -96,7 +98,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
id: to_string(user.id),
|
||||
username: username_from_nickname(user.nickname),
|
||||
acct: user.nickname,
|
||||
display_name: user.name || user.nickname,
|
||||
display_name: display_name,
|
||||
locked: user_info.locked,
|
||||
created_at: Utils.to_masto_date(user.inserted_at),
|
||||
followers_count: user_info.follower_count,
|
||||
|
|
@ -124,12 +126,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
hide_followers: user.info.hide_followers,
|
||||
hide_follows: user.info.hide_follows,
|
||||
hide_favorites: user.info.hide_favorites,
|
||||
relationship: relationship
|
||||
relationship: relationship,
|
||||
skip_thread_containment: user.info.skip_thread_containment,
|
||||
background_image: image_url(user.info.background) |> MediaProxy.url()
|
||||
}
|
||||
}
|
||||
|> maybe_put_role(user, opts[:for])
|
||||
|> maybe_put_settings(user, opts[:for], user_info)
|
||||
|> maybe_put_notification_settings(user, opts[:for])
|
||||
|> maybe_put_settings_store(user, opts[:for], opts)
|
||||
|> maybe_put_chat_token(user, opts[:for], opts)
|
||||
end
|
||||
|
||||
defp username_from_nickname(string) when is_binary(string) do
|
||||
|
|
@ -152,6 +158,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
|
||||
defp maybe_put_settings(data, _, _, _), do: data
|
||||
|
||||
defp maybe_put_settings_store(data, %User{info: info, id: id}, %User{id: id}, %{
|
||||
with_pleroma_settings: true
|
||||
}) do
|
||||
data
|
||||
|> Kernel.put_in([:pleroma, :settings_store], info.pleroma_settings_store)
|
||||
end
|
||||
|
||||
defp maybe_put_settings_store(data, _, _, _), do: data
|
||||
|
||||
defp maybe_put_chat_token(data, %User{id: id}, %User{id: id}, %{
|
||||
with_chat_token: token
|
||||
}) do
|
||||
data
|
||||
|> Kernel.put_in([:pleroma, :chat_token], token)
|
||||
end
|
||||
|
||||
defp maybe_put_chat_token(data, _, _, _), do: data
|
||||
|
||||
defp maybe_put_role(data, %User{info: %{show_role: true}} = user, _) do
|
||||
data
|
||||
|> Kernel.put_in([:pleroma, :is_admin], user.info.is_admin)
|
||||
|
|
@ -171,4 +195,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
end
|
||||
|
||||
defp maybe_put_notification_settings(data, _, _), do: data
|
||||
|
||||
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
|
||||
defp image_url(_), do: nil
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,9 +22,14 @@ defmodule Pleroma.Web.MastodonAPI.ConversationView do
|
|||
|
||||
last_status = StatusView.render("status.json", %{activity: activity, for: user})
|
||||
|
||||
# Conversations return all users except the current user.
|
||||
users =
|
||||
participation.conversation.users
|
||||
|> Enum.reject(&(&1.id == user.id))
|
||||
|
||||
accounts =
|
||||
AccountView.render("accounts.json", %{
|
||||
users: participation.conversation.users,
|
||||
users: users,
|
||||
as: :user
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
spoiler_text: summary_html,
|
||||
visibility: get_visibility(object),
|
||||
media_attachments: attachments,
|
||||
poll: render("poll.json", %{object: object, for: opts[:for]}),
|
||||
mentions: mentions,
|
||||
tags: build_tags(tags),
|
||||
application: %{
|
||||
|
|
@ -290,8 +291,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
provider_url: page_url_data.scheme <> "://" <> page_url_data.host,
|
||||
url: page_url,
|
||||
image: image_url |> MediaProxy.url(),
|
||||
title: rich_media[:title],
|
||||
description: rich_media[:description],
|
||||
title: rich_media[:title] || "",
|
||||
description: rich_media[:description] || "",
|
||||
pleroma: %{
|
||||
opengraph: rich_media
|
||||
}
|
||||
|
|
@ -329,6 +330,64 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
}
|
||||
end
|
||||
|
||||
def render("poll.json", %{object: object} = opts) do
|
||||
{multiple, options} =
|
||||
case object.data do
|
||||
%{"anyOf" => options} when is_list(options) -> {true, options}
|
||||
%{"oneOf" => options} when is_list(options) -> {false, options}
|
||||
_ -> {nil, nil}
|
||||
end
|
||||
|
||||
if options do
|
||||
end_time =
|
||||
(object.data["closed"] || object.data["endTime"])
|
||||
|> NaiveDateTime.from_iso8601!()
|
||||
|
||||
expired =
|
||||
end_time
|
||||
|> NaiveDateTime.compare(NaiveDateTime.utc_now())
|
||||
|> case do
|
||||
:lt -> true
|
||||
_ -> false
|
||||
end
|
||||
|
||||
voted =
|
||||
if opts[:for] do
|
||||
existing_votes =
|
||||
Pleroma.Web.ActivityPub.Utils.get_existing_votes(opts[:for].ap_id, object)
|
||||
|
||||
existing_votes != [] or opts[:for].ap_id == object.data["actor"]
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
{options, votes_count} =
|
||||
Enum.map_reduce(options, 0, fn %{"name" => name} = option, count ->
|
||||
current_count = option["replies"]["totalItems"] || 0
|
||||
|
||||
{%{
|
||||
title: HTML.strip_tags(name),
|
||||
votes_count: current_count
|
||||
}, current_count + count}
|
||||
end)
|
||||
|
||||
%{
|
||||
# Mastodon uses separate ids for polls, but an object can't have
|
||||
# more than one poll embedded so object id is fine
|
||||
id: object.id,
|
||||
expires_at: Utils.to_masto_date(end_time),
|
||||
expired: expired,
|
||||
multiple: multiple,
|
||||
votes_count: votes_count,
|
||||
options: options,
|
||||
voted: voted,
|
||||
emojis: build_emojis(object.data["emoji"])
|
||||
}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def get_reply_to(activity, %{replied_to_activities: replied_to_activities}) do
|
||||
object = Object.normalize(activity)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
|||
"public:media",
|
||||
"public:local:media",
|
||||
"user",
|
||||
"user:notification",
|
||||
"direct",
|
||||
"list",
|
||||
"hashtag"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue