Use conversation mapping objects to get / retrieve context from TwAPI.
authorRoger Braun <roger@rogerbraun.net>
Sun, 30 Apr 2017 11:53:26 +0000 (13:53 +0200)
committerRoger Braun <roger@rogerbraun.net>
Sun, 30 Apr 2017 11:53:26 +0000 (13:53 +0200)
lib/pleroma/object.ex
lib/pleroma/web/twitter_api/representers/activity_representer.ex
lib/pleroma/web/twitter_api/twitter_api.ex
test/web/twitter_api/representers/activity_representer_test.exs
test/web/twitter_api/twitter_api_controller_test.exs
test/web/twitter_api/twitter_api_test.exs

index f932034d7b99b2b9b8b0a4c90054fba43f71fc7f..a924c3199d53698cdaf247e3181b920f62313129 100644 (file)
@@ -13,4 +13,8 @@ defmodule Pleroma.Object do
     Repo.one(from object in Object,
       where: fragment("? @> ?", object.data, ^%{id: ap_id}))
   end
+
+  def context_mapping(context) do
+    %Object{data: %{"id" => context}}
+  end
 end
index f2bf93abb26c5ba84879bc653aa36144dd6a7b1d..bfaabb4e424eee5f08bb2ae41af6aa7a1c55de0b 100644 (file)
@@ -1,9 +1,9 @@
 defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
   use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
   alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ObjectRepresenter}
+  alias Pleroma.Web.TwitterAPI.TwitterAPI
   alias Pleroma.Activity
 
-
   defp user_by_ap_id(user_list, ap_id) do
     Enum.find(user_list, fn (%{ap_id: user_id}) -> ap_id == user_id end)
   end
@@ -82,6 +82,12 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
     |> Enum.filter(&(&1))
     |> Enum.map(fn (user) -> UserRepresenter.to_map(user, opts) end)
 
+
+    conversation_id = with context when not is_nil(context) <- activity.data["context"] do
+      TwitterAPI.context_to_conversation_id(context)
+    else _e -> nil
+    end
+
     %{
       "id" => activity.id,
       "user" => UserRepresenter.to_map(user, opts),
@@ -92,7 +98,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
       "is_post_verb" => true,
       "created_at" => created_at,
       "in_reply_to_status_id" => activity.data["object"]["inReplyToStatusId"],
-      "statusnet_conversation_id" => activity.data["object"]["statusnetConversationId"],
+      "statusnet_conversation_id" => conversation_id,
       "attachments" => (activity.data["object"]["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts),
       "attentions" => attentions,
       "fave_num" => like_count,
index 1c3396d27adf46a8fb4be0b4aeecf624b691ca01..b2fb72a81597337508c16adb09761331d2ee5441 100644 (file)
@@ -102,12 +102,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
   end
 
   def fetch_conversation(user, id) do
-    query = from activity in Activity,
-      where: fragment("? @> ?", activity.data, ^%{ statusnetConversationId: id}),
-      limit: 1
-
-    with %Activity{} = activity <- Repo.one(query),
-         context <- activity.data["context"],
+    with context when is_binary(context) <- conversation_id_to_context(id),
          activities <- ActivityPub.fetch_activities_for_context(context),
          statuses <- activities |> activities_to_statuses(%{for: user})
     do
@@ -322,4 +317,22 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
   defp make_date do
     DateTime.utc_now() |> DateTime.to_iso8601
   end
+
+  def context_to_conversation_id(context) do
+    with %Object{id: id} <- Object.get_by_ap_id(context) do
+      id
+    else _e ->
+      changeset = Object.context_mapping(context)
+      {:ok, %{id: id}} = Repo.insert(changeset)
+      id
+    end
+  end
+
+  def conversation_id_to_context(id) do
+    with %Object{data: %{"id" => context}} <- Repo.get(Object, id) do
+      context
+    else _e ->
+      {:error, "No such conversation"}
+    end
+  end
 end
index d0cccb1497d84dff4ac3931446ba7d6019d46f15..64e7f0641b33148ef1a8de95fbd16569031a5f73 100644 (file)
@@ -69,6 +69,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
     content = HtmlSanitizeEx.strip_tags(content_html)
     date = DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") |> DateTime.to_iso8601
 
+    {:ok, convo_object} = Object.context_mapping("2hu") |> Repo.insert
+
     activity = %Activity{
       id: 1,
       data: %{
@@ -84,14 +86,15 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
           "type" => "Note",
           "content" => content_html,
           "inReplyToStatusId" => 213123,
-          "statusnetConversationId" => 4711,
           "attachment" => [
             object
           ],
           "like_count" => 5,
-          "announcement_count" => 3
+          "announcement_count" => 3,
+          "context" => "2hu"
         },
-        "published" => date
+        "published" => date,
+        "context" => "2hu"
       }
     }
 
@@ -106,7 +109,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
       "is_post_verb" => true,
       "created_at" => "Tue May 24 13:26:08 +0000 2016",
       "in_reply_to_status_id" => 213123,
-      "statusnet_conversation_id" => 4711,
+      "statusnet_conversation_id" => convo_object.id,
       "attachments" => [
         ObjectRepresenter.to_map(object)
       ],
index 6c249be7d619a0807437b3ce5e795f080cc6e46f..05cd084b4fb9cb2c70837bb403a56a0a089f77fc 100644 (file)
@@ -84,12 +84,13 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   describe "GET /statusnet/conversation/:id.json" do
     test "returns the statuses in the conversation", %{conn: conn} do
       {:ok, _user} = UserBuilder.insert
-      {:ok, _activity} = ActivityBuilder.insert(%{"statusnetConversationId" => 1, "context" => "2hu"})
-      {:ok, _activity_two} = ActivityBuilder.insert(%{"statusnetConversationId" => 1,"context" => "2hu"})
+      {:ok, _activity} = ActivityBuilder.insert(%{"context" => "2hu"})
+      {:ok, _activity_two} = ActivityBuilder.insert(%{"context" => "2hu"})
       {:ok, _activity_three} = ActivityBuilder.insert(%{"context" => "3hu"})
 
+      {:ok, object} = Object.context_mapping("2hu") |> Repo.insert
       conn = conn
-      |> get("/api/statusnet/conversation/1.json")
+      |> get("/api/statusnet/conversation/#{object.id}.json")
 
       response = json_response(conn, 200)
 
index 590428423b2e3a23e97476c3cfba61d572be328b..7200112571daee1c6c6c10b7a99c7dd2b38ef274 100644 (file)
@@ -201,11 +201,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
 
   test "fetch statuses in a context using the conversation id" do
     {:ok, user} = UserBuilder.insert()
-    {:ok, activity} = ActivityBuilder.insert(%{"statusnetConversationId" => 1, "context" => "2hu"})
-    {:ok, activity_two} = ActivityBuilder.insert(%{"statusnetConversationId" => 1,"context" => "2hu"})
+    {:ok, activity} = ActivityBuilder.insert(%{"context" => "2hu"})
+    {:ok, activity_two} = ActivityBuilder.insert(%{"context" => "2hu"})
     {:ok, _activity_three} = ActivityBuilder.insert(%{"context" => "3hu"})
 
-    statuses = TwitterAPI.fetch_conversation(user, 1)
+    {:ok, object} = Object.context_mapping("2hu") |> Repo.insert
+
+    statuses = TwitterAPI.fetch_conversation(user, object.id)
 
     assert length(statuses) == 2
     assert Enum.at(statuses, 0)["id"] == activity.id
@@ -314,9 +316,33 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
     refute Repo.get_by(User, nickname: "lain")
   end
 
+  test "it assigns an integer conversation_id" do
+    note_activity = insert(:note_activity)
+    user = User.get_cached_by_ap_id(note_activity.data["actor"])
+    status = ActivityRepresenter.to_map(note_activity, %{user: user})
+
+    assert is_number(status["statusnet_conversation_id"])
+  end
+
   setup do
     Supervisor.terminate_child(Pleroma.Supervisor, Cachex)
     Supervisor.restart_child(Pleroma.Supervisor, Cachex)
     :ok
   end
+
+  describe "context_to_conversation_id" do
+    test "creates a mapping object" do
+      conversation_id = TwitterAPI.context_to_conversation_id("random context")
+      object = Object.get_by_ap_id("random context")
+
+      assert conversation_id == object.id
+    end
+
+    test "returns an existing mapping for an existing object" do
+      {:ok, object} = Object.context_mapping("random context") |> Repo.insert
+      conversation_id = TwitterAPI.context_to_conversation_id("random context")
+
+      assert conversation_id == object.id
+    end
+  end
 end