fetch_public_timeline(opts, "public timeline only media")
end
- # TODO: remove using `:method` after benchmarks
defp fetch_public_timeline(user, :with_blocks) do
opts = opts_for_public_timeline(user)
remote_non_friends = Agent.get(:non_friends_remote, & &1)
- Benchee.run(
- %{
- "public timeline without blocks" => fn opts ->
- ActivityPub.fetch_public_activities(opts)
- end
- },
- inputs: %{
- "old filtering" => Map.delete(opts, :method),
- "with psql fun" => Map.put(opts, :method, :fun),
- "with unnest" => Map.put(opts, :method, :unnest)
- }
- )
+ Benchee.run(%{
+ "public timeline without blocks" => fn ->
+ ActivityPub.fetch_public_activities(opts)
+ end
+ })
Enum.each(remote_non_friends, fn non_friend ->
{:ok, _} = User.block(user, non_friend)
Benchee.run(
%{
- "public timeline with user block" => fn opts ->
+ "public timeline with user block" => fn ->
ActivityPub.fetch_public_activities(opts)
end
},
- inputs: %{
- "old filtering" => Map.delete(opts, :method),
- "with psql fun" => Map.put(opts, :method, :fun),
- "with unnest" => Map.put(opts, :method, :unnest)
- }
)
domains =
"public timeline with domain block" => fn opts ->
ActivityPub.fetch_public_activities(opts)
end
- },
- inputs: %{
- "old filtering" => Map.delete(opts, :method),
- "with psql fun" => Map.put(opts, :method, :fun),
- "with unnest" => Map.put(opts, :method, :unnest)
}
)
end
query =
if has_named_binding?(query, :object), do: query, else: Activity.with_joined_object(query)
- # TODO: update after benchmarks
- query =
- case opts[:method] do
- :fun ->
- from(a in query,
- where:
- fragment(
- "recipients_contain_blocked_domains(?, ?) = false",
- a.recipients,
- ^domain_blocks
- )
- )
-
- :unnest ->
- from(a in query,
- where:
- fragment(
- "NOT ? && (SELECT ARRAY(SELECT split_part(UNNEST(?), '/', 3)))",
- ^domain_blocks,
- a.recipients
- )
- )
-
- _ ->
- query
- end
-
from(
[activity, object: o] in query,
where: fragment("not (? = ANY(?))", activity.actor, ^blocked_ap_ids),
where: fragment("not (? && ?)", activity.recipients, ^blocked_ap_ids),
+ where:
+ fragment(
+ "recipients_contain_blocked_domains(?, ?) = false",
+ activity.recipients,
+ ^domain_blocks
+ ),
where:
fragment(
"not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
only_media_param(),
with_muted_param(),
exclude_visibilities_param(),
- # TODO: remove after benchmarks
- Operation.parameter(
- :method,
- :query,
- %Schema{type: :string},
- "Temp parameter"
- ),
reply_visibility_param() | pagination_params()
],
operationId: "TimelineController.public",
if restrict? and is_nil(user) do
render_error(conn, :unauthorized, "authorization required for timeline view")
else
- # TODO: return back after benchmarks
- params =
+ activities =
params
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", local_only)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("reply_filtering_user", user)
-
- params =
- if params["method"] do
- Map.put(params, :method, String.to_existing_atom(params["method"]))
- else
- params
- end
-
- activities = ActivityPub.fetch_public_activities(params)
+ |> ActivityPub.fetch_public_activities()
conn
|> add_link_headers(activities, %{"local" => local_only})
[%{"id" => ^activity_id}] = json_response_and_validate_schema(res_conn, 200)
end
- # TODO: update after benchmarks
test "doesn't return replies if follow is posting with users from blocked domain" do
%{conn: conn, user: blocker} = oauth_access(["read:statuses"])
friend = insert(:user)
{:ok, _reply_from_friend} =
CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
- res_conn = get(conn, "/api/v1/timelines/public?method=fun")
-
- activities = json_response_and_validate_schema(res_conn, 200)
- [%{"id" => ^activity_id}] = activities
- end
-
- # TODO: update after benchmarks
- test "doesn't return replies if follow is posting with users from blocked domain with unnest param" do
- %{conn: conn, user: blocker} = oauth_access(["read:statuses"])
- friend = insert(:user)
- blockee = insert(:user, ap_id: "https://example.com/users/blocked")
- {:ok, blocker} = User.follow(blocker, friend)
- {:ok, blocker} = User.block_domain(blocker, "example.com")
-
- conn = assign(conn, :user, blocker)
-
- {:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
-
- {:ok, reply_from_blockee} =
- CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
-
- {:ok, _reply_from_friend} =
- CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
-
- res_conn = get(conn, "/api/v1/timelines/public?method=unnest")
+ res_conn = get(conn, "/api/v1/timelines/public")
activities = json_response_and_validate_schema(res_conn, 200)
[%{"id" => ^activity_id}] = activities