Add `ap_id` to List
authorEgor Kislitsyn <egor@kislitsyn.com>
Fri, 17 May 2019 12:56:37 +0000 (19:56 +0700)
committerEgor Kislitsyn <egor@kislitsyn.com>
Fri, 17 May 2019 12:56:37 +0000 (19:56 +0700)
lib/pleroma/list.ex
lib/pleroma/web/common_api/utils.ex
priv/repo/migrations/20190516112144_add_ap_id_to_lists.exs [new file with mode: 0644]
test/list_test.exs
test/web/common_api/common_api_test.exs

index 81b842e9cd909048c77b7dbaf37e880e9404b1f7..16955b3b559bf3f34bd339941a1267be58a814bc 100644 (file)
@@ -12,12 +12,11 @@ defmodule Pleroma.List do
   alias Pleroma.Repo
   alias Pleroma.User
 
-  @ap_id_regex ~r/^\/users\/(?<nickname>\w+)\/lists\/(?<list_id>\d+)/
-
   schema "lists" do
     belongs_to(:user, User, type: Pleroma.FlakeId)
     field(:title, :string)
     field(:following, {:array, :string}, default: [])
+    field(:ap_id, :string)
 
     timestamps()
   end
@@ -34,12 +33,6 @@ defmodule Pleroma.List do
     |> validate_required([:following])
   end
 
-  def ap_id(%User{nickname: nickname}, list_id) do
-    Pleroma.Web.Endpoint.url() <> "/users/#{nickname}/lists/#{list_id}"
-  end
-
-  def ap_id({nickname, list_id}), do: ap_id(%User{nickname: nickname}, list_id)
-
   def for_user(user, _opts) do
     query =
       from(
@@ -64,16 +57,7 @@ defmodule Pleroma.List do
   end
 
   def get_by_ap_id(ap_id) do
-    host = Pleroma.Web.Endpoint.host()
-
-    with %{host: ^host, path: path} <- URI.parse(ap_id),
-         %{"list_id" => list_id, "nickname" => nickname} <-
-           Regex.named_captures(@ap_id_regex, path),
-         %User{} = user <- User.get_cached_by_nickname(nickname) do
-      get(list_id, user)
-    else
-      _ -> nil
-    end
+    Repo.get_by(__MODULE__, ap_id: ap_id)
   end
 
   def get_following(%Pleroma.List{following: following} = _list) do
@@ -126,7 +110,14 @@ defmodule Pleroma.List do
 
   def create(title, %User{} = creator) do
     list = %Pleroma.List{user_id: creator.id, title: title}
-    Repo.insert(list)
+
+    Repo.transaction(fn ->
+      list = Repo.insert!(list)
+
+      list
+      |> change(ap_id: "#{creator.ap_id}/lists/#{list.id}")
+      |> Repo.update!()
+    end)
   end
 
   def follow(%Pleroma.List{following: following} = list, %User{} = followed) do
@@ -150,10 +141,8 @@ defmodule Pleroma.List do
   def memberships(%User{follower_address: follower_address}) do
     Pleroma.List
     |> where([l], ^follower_address in l.following)
-    |> join(:inner, [l], u in User, on: l.user_id == u.id)
-    |> select([l, u], {u.nickname, l.id})
+    |> select([l], l.ap_id)
     |> Repo.all()
-    |> Enum.map(&ap_id/1)
   end
 
   def memberships(_), do: []
index f082b77d84b034d87d28ed55b6732c3ae43edb8b..ba6ed67ef38d493d3070e82283cce8dc459137f2 100644 (file)
@@ -105,7 +105,8 @@ defmodule Pleroma.Web.CommonAPI.Utils do
   def to_for_user_and_mentions(_user, _mentions, _inReplyTo, _), do: {[], []}
 
   def bcc_for_list(user, {:list, list_id}) do
-    [Pleroma.List.ap_id(user, list_id)]
+    list = Pleroma.List.get(list_id, user)
+    [list.ap_id]
   end
 
   def bcc_for_list(_, _), do: []
diff --git a/priv/repo/migrations/20190516112144_add_ap_id_to_lists.exs b/priv/repo/migrations/20190516112144_add_ap_id_to_lists.exs
new file mode 100644 (file)
index 0000000..3c32bc3
--- /dev/null
@@ -0,0 +1,26 @@
+defmodule Pleroma.Repo.Migrations.AddApIdToLists do
+  use Ecto.Migration
+
+  def up do
+    alter table(:lists) do
+      add(:ap_id, :string)
+    end
+
+    execute("""
+    UPDATE lists
+    SET ap_id = u.ap_id || '/lists/' || lists.id
+    FROM users AS u
+    WHERE lists.user_id = u.id
+    """)
+
+    create(unique_index(:lists, :ap_id))
+  end
+
+  def down do
+    drop(index(:lists, [:ap_id]))
+
+    alter table(:lists) do
+      remove(:ap_id)
+    end
+  end
+end
index 0e72b66604c212e87957f873fd23b4f04a08dfa8..6c5c6b197f84e6ba514f2e8b6b9bb352163af349 100644 (file)
@@ -114,22 +114,10 @@ defmodule Pleroma.ListTest do
     refute not_owned_list in lists_2
   end
 
-  test "get ap_id by user nickname and list id" do
-    nickname = "foo"
-    list_id = 42
-
-    expected = Pleroma.Web.Endpoint.url() <> "/users/#{nickname}/lists/#{list_id}"
-
-    assert Pleroma.List.ap_id(%Pleroma.User{nickname: nickname}, list_id) == expected
-    assert Pleroma.List.ap_id({nickname, list_id}) == expected
-  end
-
   test "get by ap_id" do
     user = insert(:user)
     {:ok, list} = Pleroma.List.create("foo", user)
-    ap_id = Pleroma.List.ap_id(user, list.id)
-
-    assert Pleroma.List.get_by_ap_id(ap_id) == list
+    assert Pleroma.List.get_by_ap_id(list.ap_id) == list
   end
 
   test "memberships" do
@@ -138,8 +126,6 @@ defmodule Pleroma.ListTest do
     {:ok, list} = Pleroma.List.create("foo", user)
     {:ok, list} = Pleroma.List.follow(list, member)
 
-    list_ap_id = Pleroma.List.ap_id(user, list.id)
-
-    assert Pleroma.List.memberships(member) == [list_ap_id]
+    assert Pleroma.List.memberships(member) == [list.ap_id]
   end
 end
index 23e89d685184eb871d9254b263e3a66173fa68b6..84744e5af7ab9b6c3404311e9c47c1ca841c68a4 100644 (file)
@@ -114,13 +114,11 @@ defmodule Pleroma.Web.CommonAPITest do
       user = insert(:user)
       {:ok, list} = Pleroma.List.create("foo", user)
 
-      list_ap_id = Pleroma.List.ap_id(user, list.id)
-
       {:ok, activity} =
         CommonAPI.post(user, %{"status" => "foobar", "visibility" => "list:#{list.id}"})
 
-      assert activity.data["bcc"] == [list_ap_id]
-      assert activity.recipients == [list_ap_id, user.ap_id]
+      assert activity.data["bcc"] == [list.ap_id]
+      assert activity.recipients == [list.ap_id, user.ap_id]
     end
   end