list.ex 2.82 KB
Newer Older
1
# Pleroma: A lightweight social networking server
kaniini's avatar
kaniini committed
2
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3
4
# SPDX-License-Identifier: AGPL-3.0-only

eal's avatar
eal committed
5
6
defmodule Pleroma.List do
  use Ecto.Schema
Haelwenn's avatar
Haelwenn committed
7
8
9
10
11
12
13

  import Ecto.Query
  import Ecto.Changeset

  alias Pleroma.Activity
  alias Pleroma.Repo
  alias Pleroma.User
eal's avatar
eal committed
14
15

  schema "lists" do
href's avatar
href committed
16
    belongs_to(:user, User, type: Pleroma.FlakeId)
eal's avatar
eal committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    field(:title, :string)
    field(:following, {:array, :string}, default: [])

    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

Maksim's avatar
Maksim committed
35
  def for_user(user, _opts) do
eal's avatar
eal committed
36
37
38
39
40
41
42
43
44
45
46
    query =
      from(
        l in Pleroma.List,
        where: l.user_id == ^user.id,
        order_by: [desc: l.id],
        limit: 50
      )

    Repo.all(query)
  end

eal's avatar
eal committed
47
  def get(id, %{id: user_id} = _user) do
eal's avatar
eal committed
48
49
50
51
52
53
54
55
56
57
    query =
      from(
        l in Pleroma.List,
        where: l.id == ^id,
        where: l.user_id == ^user_id
      )

    Repo.one(query)
  end

Maksim's avatar
Maksim committed
58
  def get_following(%Pleroma.List{following: following} = _list) do
eal's avatar
eal committed
59
60
61
62
63
64
    q =
      from(
        u in User,
        where: u.follower_address in ^following
      )

eal's avatar
eal committed
65
66
67
    {:ok, Repo.all(q)}
  end

eal's avatar
eal committed
68
69
70
71
72
73
74
75
76
77
78
79
80
  # 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

81
82
  # Get lists to which the account belongs.
  def get_lists_account_belongs(%User{} = owner, account_id) do
minibikini's avatar
minibikini committed
83
    user = User.get_cached_by_id(account_id)
84

85
86
87
    query =
      from(
        l in Pleroma.List,
88
89
90
91
92
93
94
        where:
          l.user_id == ^owner.id and
            fragment(
              "? = ANY(?)",
              ^user.follower_address,
              l.following
            )
95
      )
96

97
98
99
    Repo.all(query)
  end

eal's avatar
eal committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  def rename(%Pleroma.List{} = list, title) do
    list
    |> title_changeset(%{title: title})
    |> Repo.update()
  end

  def create(title, %User{} = creator) do
    list = %Pleroma.List{user_id: creator.id, title: title}
    Repo.insert(list)
  end

  def follow(%Pleroma.List{following: following} = list, %User{} = followed) do
    update_follows(list, %{following: Enum.uniq([followed.follower_address | following])})
  end

  def unfollow(%Pleroma.List{following: following} = list, %User{} = unfollowed) do
    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
end