list.ex (3606B)
- # Pleroma: A lightweight social networking server
- # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
- # SPDX-License-Identifier: AGPL-3.0-only
- defmodule Pleroma.List do
- use Ecto.Schema
- import Ecto.Query
- import Ecto.Changeset
- alias Pleroma.Activity
- alias Pleroma.Repo
- alias Pleroma.User
- schema "lists" do
- belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
- field(:title, :string)
- field(:following, {:array, :string}, default: [])
- field(:ap_id, :string)
- timestamps()
- end
- def title_changeset(list, attrs \\ %{}) do
- list
- |> cast(attrs, [:title])
- |> validate_required([:title])
- end
- def follow_changeset(list, attrs \\ %{}) do
- list
- |> cast(attrs, [:following])
- |> validate_required([:following])
- end
- def for_user(user, _opts) do
- query =
- from(
- l in Pleroma.List,
- where: l.user_id == ^user.id,
- order_by: [desc: l.id],
- limit: 50
- )
- Repo.all(query)
- end
- def get(id, %{id: user_id} = _user) do
- query =
- from(
- l in Pleroma.List,
- where: l.id == ^id,
- where: l.user_id == ^user_id
- )
- Repo.one(query)
- end
- def get_by_ap_id(ap_id) do
- Repo.get_by(__MODULE__, ap_id: ap_id)
- end
- def get_following(%Pleroma.List{following: following} = _list) do
- q =
- from(
- u in User,
- where: u.follower_address in ^following
- )
- {: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
- # Get lists to which the account belongs.
- def get_lists_account_belongs(%User{} = owner, user) do
- Pleroma.List
- |> where([l], l.user_id == ^owner.id)
- |> where([l], fragment("? = ANY(?)", ^user.follower_address, l.following))
- |> Repo.all()
- end
- def rename(%Pleroma.List{} = list, title) do
- list
- |> title_changeset(%{title: title})
- |> Repo.update()
- end
- def create(title, %User{} = creator) do
- changeset = title_changeset(%Pleroma.List{user_id: creator.id}, %{title: title})
- if changeset.valid? do
- Repo.transaction(fn ->
- list = Repo.insert!(changeset)
- list
- |> change(ap_id: "#{creator.ap_id}/lists/#{list.id}")
- |> Repo.update!()
- end)
- else
- {:error, changeset}
- end
- end
- def follow(%Pleroma.List{id: id}, %User{} = followed) do
- list = Repo.get(Pleroma.List, id)
- %{following: following} = list
- update_follows(list, %{following: Enum.uniq([followed.follower_address | following])})
- end
- def unfollow(%Pleroma.List{id: id}, %User{} = unfollowed) do
- list = Repo.get(Pleroma.List, id)
- %{following: following} = list
- update_follows(list, %{following: List.delete(following, unfollowed.follower_address)})
- end
- def delete(%Pleroma.List{} = list) do
- Repo.delete(list)
- end
- def update_follows(%Pleroma.List{} = list, attrs) do
- list
- |> follow_changeset(attrs)
- |> Repo.update()
- end
- def memberships(%User{follower_address: follower_address}) do
- Pleroma.List
- |> where([l], ^follower_address in l.following)
- |> select([l], l.ap_id)
- |> Repo.all()
- end
- def memberships(_), do: []
- def member?(%Pleroma.List{following: following}, %User{follower_address: follower_address}) do
- Enum.member?(following, follower_address)
- end
- def member?(_, _), do: false
- end