Add favoriting to Mastodon API.
authorRoger Braun <roger@rogerbraun.net>
Sat, 9 Sep 2017 16:09:37 +0000 (18:09 +0200)
committerRoger Braun <roger@rogerbraun.net>
Sat, 9 Sep 2017 16:09:37 +0000 (18:09 +0200)
lib/pleroma/web/common_api/common_api.ex
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/web/router.ex
lib/pleroma/web/twitter_api/twitter_api.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
test/web/mastodon_api/mastodon_api_controller_test.exs
test/web/twitter_api/twitter_api_test.exs

index b1d2172c7c923825e26d82c95e99fa2d1a6273c4..43cec91216115eb20b8eaa5242c562ba60db3569 100644 (file)
@@ -22,6 +22,17 @@ defmodule Pleroma.Web.CommonAPI do
     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,
+         object <- Object.get_by_ap_id(activity.data["object"]["id"]) do
+      ActivityPub.like(user, object)
+    else
+      _ ->
+        {:error, "Could not favorite"}
+    end
+  end
+
   # This is a hack for twidere.
   def get_by_id_or_ap_id(id) do
     activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id)
index 67b5d49b309e04b28d42e4f527bbc6260537778c..c0ae3fd233ebd22dda8b2a6f267b26f1ea55eebe 100644 (file)
@@ -87,4 +87,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
       render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
     end
   end
+
+  def fav_status(%{assigns: %{user: user}} = conn, %{"id" => 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
+      render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
+    end
+  end
 end
index d1e5f58c5c61816be6dd600c4b600b79c08d3aba..7b798506a08937ab66bbabde10e0e755b3d1dd42 100644 (file)
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     |> Enum.map(fn (user) -> AccountView.render("mention.json", %{user: user}) end)
 
     repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || [])
+    favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || [])
 
     %{
       id: activity.id,
@@ -36,7 +37,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       reblogs_count: announcement_count,
       favourites_count: like_count,
       reblogged: !!repeated,
-      favourited: false, # fix
+      favourited: !!favorited,
       muted: false,
       sensitive: sensitive,
       spoiler_text: "",
index 4e59530ae5c2afb5e492808c01e8ceffb4b0c7c7..33b51fd345e45ce4427b501cbfb4b802c505cf8a 100644 (file)
@@ -59,6 +59,7 @@ defmodule Pleroma.Web.Router do
     delete "/statuses/:id", MastodonAPIController, :delete_status
 
     post "/statuses/:id/reblog", MastodonAPIController, :reblog_status
+    post "/statuses/:id/favourite", MastodonAPIController, :fav_status
   end
 
   scope "/api", Pleroma.Web do
index daa53c73b0c9695c20e004bb77a179e089d33a1d..0c77e092cf6a4e718628c35326335e33d6711723 100644 (file)
@@ -115,19 +115,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     end
   end
 
-  def favorite(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
-    object = Object.get_by_ap_id(object["id"])
-
-    {:ok, _like_activity, object} = ActivityPub.like(user, object)
-    new_data = activity.data
-    |> Map.put("object", object.data)
-
-    status = %{activity | data: new_data}
-    |> activity_to_status(%{for: user})
-
-    {:ok, status}
-  end
-
   def unfavorite(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
     object = Object.get_by_ap_id(object["id"])
 
@@ -149,6 +136,14 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     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),
+         status <- activity_to_status(activity, %{for: user}) do
+      {:ok, status}
+    end
+  end
+
   def upload(%Plug.Upload{} = file, format \\ "xml") do
     {:ok, object} = ActivityPub.upload(file)
 
index a07c60e0625dfe7c5817be39943e57e8de0ddb30..7da1291b07d9427d509cabd44c0051899502128b 100644 (file)
@@ -149,12 +149,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
   end
 
   def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
-    activity = get_by_id_or_ap_id(id)
-    {:ok, status} = TwitterAPI.favorite(user, activity)
-    response = Poison.encode!(status)
-
-    conn
-    |> json_reply(200, response)
+    with {:ok, status} <- TwitterAPI.fav(user, id) do
+      json(conn, status)
+    end
   end
 
   def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
index 6cdb75d089a498c63409a9d9b57a226afba72353..9af49da123b050b75b1e06c9905e041b6fed6d9d 100644 (file)
@@ -135,4 +135,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       assert activity.id == id
     end
   end
+
+  describe "favoriting" do
+    test "favs a status and returns it", %{conn: conn} do
+      activity = insert(:note_activity)
+      user = insert(:user)
+
+      conn = conn
+      |> assign(:user, user)
+      |> post("/api/v1/statuses/#{activity.id}/favourite")
+
+      assert %{"id" => id, "favourites_count" => 1, "favourited" => true} = json_response(conn, 200)
+      assert activity.id == id
+    end
+  end
 end
index c1c9b2d2264cc76bebff5187979b3d31308c9edb..a9494f424b0d2c6881b4bb2094a358ae380c77e8 100644 (file)
@@ -264,7 +264,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
     note_activity = insert(:note_activity)
     activity_user = Repo.get_by!(User, ap_id: note_activity.data["actor"])
 
-    {:ok, status} = TwitterAPI.favorite(user, note_activity)
+    {:ok, status} = TwitterAPI.fav(user, note_activity.id)
     updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
 
     assert status == ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})