Pre-fetch conversation ids.

This commit is contained in:
lain 2018-04-02 14:46:56 +02:00
parent cd543d58a1
commit a4db3a732f
2 changed files with 63 additions and 2 deletions

View file

@ -7,9 +7,44 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Formatter alias Pleroma.Formatter
import Ecto.Query
defp query_context_ids(contexts) do
query = from o in Object,
where: fragment("(?)->>'id' = ANY(?)", o.data, ^contexts)
Repo.all(query)
end
defp collect_context_ids(activities) do
contexts = activities
|> Enum.map(fn(%{data: data}) ->
data["context"]
end)
|> Enum.filter(&(&1))
|> query_context_ids()
|> Enum.reduce(%{}, fn(%{data: %{"id" => ap_id}, id: id}, acc) ->
Map.put(acc, ap_id, id)
end)
end
defp get_context_id(%{data: %{"context" => nil}}), do: nil
defp get_context_id(%{data: %{"context" => context}}, options) do
cond do
id = options[:context_ids][context] -> id
true -> TwitterAPI.context_to_conversation_id(context)
end
end
def render("index.json", opts) do def render("index.json", opts) do
context_ids = collect_context_ids(opts.activities)
opts = opts
|> Map.put(:context_ids, context_ids)
render_many( render_many(
opts.activities, opts.activities,
ActivityView, ActivityView,
@ -80,7 +115,7 @@ def render("activity.json", %{activity: %{data: %{"type" => "Announce"}} = activ
"uri" => "tag:#{activity.data["id"]}:objectType=note", "uri" => "tag:#{activity.data["id"]}:objectType=note",
"created_at" => created_at, "created_at" => created_at,
"retweeted_status" => retweeted_status, "retweeted_status" => retweeted_status,
"statusnet_conversation_id" => conversation_id(announced_activity), "statusnet_conversation_id" => get_context_id(announced_activity, opts),
"external_url" => activity.data["id"], "external_url" => activity.data["id"],
"activity_type" => "repeat" "activity_type" => "repeat"
} }
@ -130,7 +165,7 @@ def render(
|> Enum.filter(& &1) |> Enum.filter(& &1)
|> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end) |> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end)
conversation_id = conversation_id(activity) conversation_id = get_context_id(activity, opts)
tags = activity.data["object"]["tag"] || [] tags = activity.data["object"]["tag"] || []
possibly_sensitive = activity.data["object"]["sensitive"] || Enum.member?(tags, "nsfw") possibly_sensitive = activity.data["object"]["sensitive"] || Enum.member?(tags, "nsfw")

View file

@ -10,7 +10,9 @@ defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
import Pleroma.Factory import Pleroma.Factory
import Mock
test "a create activity with a note" do test "a create activity with a note" do
user = insert(:user) user = insert(:user)
@ -51,6 +53,30 @@ test "a create activity with a note" do
assert result == expected assert result == expected
end end
test "a list of activities" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
convo_id = TwitterAPI.context_to_conversation_id(activity.data["object"]["context"])
mocks = [
{
TwitterAPI,
[],
[context_to_conversation_id: fn(_) -> false end]
}
]
with_mocks mocks do
[result] = ActivityView.render("index.json", activities: [activity])
assert result["statusnet_conversation_id"] == convo_id
assert result["user"]
refute called TwitterAPI.context_to_conversation_id(:_)
end
end
test "an activity that is a reply" do test "an activity that is a reply" do
user = insert(:user) user = insert(:user)
other_user = insert(:user, %{nickname: "shp"}) other_user = insert(:user, %{nickname: "shp"})