defmodule Pleroma.List do
use Ecto.Schema
import Ecto.{Changeset, Query}
- alias Pleroma.{User, Repo}
+ alias Pleroma.{User, Repo, Activity}
schema "lists" do
belongs_to(:user, Pleroma.User)
{:ok, Repo.all(q)}
end
+ # Get lists the activity should be streamed to.
+ def get_lists_from_activity(%Activity{actor: ap_id}) do
+ actor = User.get_cached_by_ap_id(ap_id)
+
+ query =
+ from(
+ l in Pleroma.List,
+ where: fragment("? && ?", l.following, ^[actor.follower_address])
+ )
+
+ Repo.all(query)
+ end
+
def rename(%Pleroma.List{} = list, title) do
list
|> title_changeset(%{title: title})
if activity.data["type"] in ["Create", "Announce"] do
Pleroma.Web.Streamer.stream("user", activity)
+ Pleroma.Web.Streamer.stream("list", activity)
if Enum.member?(activity.data["to"], public) do
Pleroma.Web.Streamer.stream("public", activity)
with token when not is_nil(token) <- params["access_token"],
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
%User{} = user <- Repo.get(User, user_id),
- stream when stream in ["public", "public:local", "user", "direct"] <- params["stream"] do
+ stream when stream in ["public", "public:local", "user", "direct", "list"] <-
+ params["stream"] do
+ topic = if stream == "list", do: "list:#{params["list"]}", else: stream
+
socket =
socket
- |> assign(:topic, params["stream"])
+ |> assign(:topic, topic)
|> assign(:user, user)
Pleroma.Web.Streamer.add_socket(params["stream"], socket)
{:noreply, topics}
end
+ def handle_cast(%{action: :stream, topic: "list", item: item}, topics) do
+ recipient_topics =
+ Pleroma.List.get_lists_from_activity(item)
+ |> Enum.map(fn %{id: id} -> "list:#{id}" end)
+
+ Enum.each(recipient_topics || [], fn list_topic ->
+ Logger.debug("Trying to push message to #{list_topic}\n\n")
+ push_to_socket(topics, list_topic, item)
+ end)
+
+ {:noreply, topics}
+ end
+
def handle_cast(%{action: :stream, topic: "user", item: %Notification{} = item}, topics) do
topic = "user:#{item.user_id}"
--- /dev/null
+defmodule Pleroma.Repo.Migrations.AddListFollowIndex do
+ use Ecto.Migration
+
+ def change do
+ create index(:lists, [:following])
+ end
+end
assert list_two in lists
refute list_three in lists
end
+
+ test "getting all lists the user is a member of" do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, list_one} = Pleroma.List.create("title", user)
+ {:ok, list_two} = Pleroma.List.create("other title", user)
+ {:ok, list_three} = Pleroma.List.create("third title", other_user)
+ {:ok, list_one} = Pleroma.List.follow(list_one, other_user)
+ {:ok, list_two} = Pleroma.List.follow(list_two, other_user)
+ {:ok, list_three} = Pleroma.List.follow(list_three, user)
+
+ lists = Pleroma.List.get_lists_from_activity(%Pleroma.Activity{actor: other_user.ap_id})
+ assert list_one in lists
+ assert list_two in lists
+ refute list_three in lists
+ end
end