Add unrepeat functionality
authorFrancis Dinh <normandy@firemail.cc>
Sat, 14 Apr 2018 07:39:16 +0000 (03:39 -0400)
committerFrancis Dinh <normandy@firemail.cc>
Sun, 15 Apr 2018 00:19:48 +0000 (20:19 -0400)
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/utils.ex
lib/pleroma/web/common_api/common_api.ex
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
lib/pleroma/web/router.ex
lib/pleroma/web/twitter_api/twitter_api.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex

index 04b50c1cc0fc32870dad268d569648c6e8d60263..b3154ea99b5ad65edc57e710b09fcd9963883019 100644 (file)
@@ -140,6 +140,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
+  def unannounce(%User{} = actor, %Object{} = object) do
+    with %Activity{} = activity <- get_existing_announce(actor.ap_id, object),
+         {:ok, _activity} <- Repo.delete(activity),
+         {:ok, object} <- remove_announce_from_object(activity, object) do
+      {:ok, object}
+    else
+      _e -> {:ok, object}
+    end
+  end
+
   def follow(follower, followed, activity_id \\ nil, local \\ true) do
     with data <- make_follow_data(follower, followed, activity_id),
          {:ok, activity} <- insert(data, local),
index 7a0762e9f17fc7bb0bc1d49634105dcb1905faea..c7c87667016f48f2e116e6e2ade877e7c262ff90 100644 (file)
@@ -239,6 +239,25 @@ defmodule Pleroma.Web.ActivityPub.Utils do
   @doc """
   Make announce activity data for the given actor and object
   """
+  def get_existing_announce(actor, %{data: %{"id" => id}}) do
+    query =
+      from(
+        activity in Activity,
+        where: fragment("(?)->>'actor' = ?", activity.data, ^actor),
+        # this is to use the index
+        where:
+          fragment(
+            "coalesce((?)->'object'->>'id', (?)->>'object') = ?",
+            activity.data,
+            activity.data,
+            ^id
+          ),
+        where: fragment("(?)->>'type' = 'Announce'", activity.data)
+      )
+
+    Repo.one(query)
+  end
+
   def make_announce_data(
         %User{ap_id: ap_id} = user,
         %Object{data: %{"id" => id}} = object,
@@ -262,6 +281,12 @@ defmodule Pleroma.Web.ActivityPub.Utils do
     end
   end
 
+  def remove_announce_from_object(%Activity{data: %{"actor" => actor}}, object) do
+    with announcements <- (object.data["announcements"] || []) |> List.delete(actor) do
+      update_element_in_object("announcement", announcements, object)
+    end
+  end
+
   #### Unfollow-related helpers
 
   def make_unfollow_data(follower, followed, follow_activity) do
index 21225c3b7d8a95b908b2820a795433dec25fdf0a..8889b9b4206c0c5c733aaccfb36d0f26cb2b5f6d 100644 (file)
@@ -24,6 +24,16 @@ defmodule Pleroma.Web.CommonAPI do
     end
   end
 
+  def unrepeat(id_or_ap_id, user) do
+    with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
+         object <- Object.get_by_ap_id(activity.data["object"]["id"]) do
+      ActivityPub.unannounce(user, object)
+    else
+      _ ->
+        {:error, "Could not unrepeat"}
+    end
+  end
+
   def favorite(id_or_ap_id, user) do
     with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
          false <- activity.data["actor"] == user.ap_id,
index 21a3660c8714889ccbcd552dd5c3ab473c4d8f8a..1825e156f50712c784c06587402ab59c7e7a9bd6 100644 (file)
@@ -296,6 +296,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
+  def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
+    with {:ok, announce, _activity} = CommonAPI.unrepeat(ap_id_or_id, user) do
+      render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity})
+    end
+  end
+
   def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
     with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user),
          %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
index 8ee27e63c08b77c59fc9742b901d56ec08834a96..5a32cf7b43e9ab5bc99bbd1fc24fdf91d436b3b3 100644 (file)
@@ -110,6 +110,7 @@ defmodule Pleroma.Web.Router do
     delete("/statuses/:id", MastodonAPIController, :delete_status)
 
     post("/statuses/:id/reblog", MastodonAPIController, :reblog_status)
+    post("/statuses/:id/unreblog", MastodonAPIController, :unreblog_status)
     post("/statuses/:id/favourite", MastodonAPIController, :fav_status)
     post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status)
 
index c12cd7f8aa14a8912e89b69e04609a9e31897b38..1791feb3adbe25b6465a1c8e8f0ac8f8f086a198 100644 (file)
@@ -64,6 +64,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     end
   end
 
+  def unrepeat(%User{} = user, ap_id_or_id) do
+    with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.unrepeat(ap_id_or_id, user),
+         %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
+      {:ok, activity}
+    end
+  end
+
   def fav(%User{} = user, ap_id_or_id) do
     with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user),
          %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
index 5f44e46c058b097c55230717fc97fa145e3a7fd3..986436326ce8c096795a39f3c263b2e9b686c16c 100644 (file)
@@ -229,6 +229,12 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
     end
   end
 
+  def unretweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do
+    with {:ok, activity} <- TwitterAPI.unrepeat(user, id) do
+      render(conn, ActivityView, "activity.json", %{activity: activity, for: user})
+    end
+  end
+
   def register(conn, params) do
     with {:ok, user} <- TwitterAPI.register_user(params) do
       render(conn, UserView, "show.json", %{user: user})