Add reblogging to MastodonAPI.
authorRoger Braun <roger@rogerbraun.net>
Sat, 9 Sep 2017 15:48:57 +0000 (17:48 +0200)
committerRoger Braun <roger@rogerbraun.net>
Sat, 9 Sep 2017 15:48:57 +0000 (17:48 +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_controller_test.exs
test/web/twitter_api/twitter_api_test.exs

index a894ac9c1cf45b482d30e9c8571f525460203973..b1d2172c7c923825e26d82c95e99fa2d1a6273c4 100644 (file)
@@ -10,4 +10,25 @@ defmodule Pleroma.Web.CommonAPI do
       {:ok, delete}
     end
   end
+
+  def repeat(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.announce(user, object)
+    else
+      _ ->
+        {:error, "Could not repeat"}
+    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)
+    if activity.data["type"] == "Create" do
+      activity
+    else
+      Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+    end
+  end
 end
index af62c3df0962e36fa9486c74c4c4e67b65233901..67b5d49b309e04b28d42e4f527bbc6260537778c 100644 (file)
@@ -80,4 +80,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
         |> json(%{error: "Can't delete this post"})
     end
   end
+
+  def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
+    with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(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 45e7d45f42db9105700a99b84b179113d1be4ebb..d1e5f58c5c61816be6dd600c4b600b79c08d3aba 100644 (file)
@@ -7,7 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     render_many(opts.activities, StatusView, "status.json", opts)
   end
 
-  def render("status.json", %{activity: %{data: %{"object" => object}} = activity}) do
+  def render("status.json", %{activity: %{data: %{"object" => object}} = activity} = opts) do
     user = User.get_cached_by_ap_id(activity.data["actor"])
 
     like_count = object["like_count"] || 0
@@ -21,6 +21,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     |> Enum.filter(&(&1))
     |> Enum.map(fn (user) -> AccountView.render("mention.json", %{user: user}) end)
 
+    repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || [])
+
     %{
       id: activity.id,
       uri: object["id"],
@@ -33,7 +35,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       created_at: object["published"],
       reblogs_count: announcement_count,
       favourites_count: like_count,
-      reblogged: false,
+      reblogged: !!repeated,
       favourited: false, # fix
       muted: false,
       sensitive: sensitive,
index d3cae62011e26da62dcce91f9e5a00ce873c60c8..4e59530ae5c2afb5e492808c01e8ceffb4b0c7c7 100644 (file)
@@ -57,6 +57,8 @@ defmodule Pleroma.Web.Router do
 
     post "/statuses", MastodonAPIController, :post_status
     delete "/statuses/:id", MastodonAPIController, :delete_status
+
+    post "/statuses/:id/reblog", MastodonAPIController, :reblog_status
   end
 
   scope "/api", Pleroma.Web do
index 1ae076e2430eb5628e08ee9aeb1a329291785cb9..daa53c73b0c9695c20e004bb77a179e089d33a1d 100644 (file)
@@ -3,7 +3,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
   alias Pleroma.Web.TwitterAPI.UserView
-  alias Pleroma.Web.OStatus
+  alias Pleroma.Web.{OStatus, CommonAPI}
   alias Pleroma.Formatter
 
   import Pleroma.Web.TwitterAPI.Utils
@@ -141,17 +141,12 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     {:ok, status}
   end
 
-  def retweet(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
-    object = Object.get_by_ap_id(object["id"])
-
-    {:ok, _announce_activity, object} = ActivityPub.announce(user, object)
-    new_data = activity.data
-    |> Map.put("object", object.data)
-
-    status = %{activity | data: new_data}
-    |> activity_to_status(%{for: user})
-
-    {:ok, status}
+  def repeat(%User{} = user, ap_id_or_id) do
+    with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(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
index 5e0b9ea0aafe8463554cfd9f10e2dd1596d09f34..a07c60e0625dfe7c5817be39943e57e8de0ddb30 100644 (file)
@@ -167,22 +167,13 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
   end
 
   def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do
-    activity = get_by_id_or_ap_id(id)
-    if activity.data["actor"] == user.ap_id do
-      bad_request_reply(conn, "You cannot repeat your own notice.")
-    else
-      {:ok, status} = TwitterAPI.retweet(user, activity)
-      response = Poison.encode!(status)
-
-      conn
-
-      |> json_reply(200, response)
+    with {:ok, status} <- TwitterAPI.repeat(user, id) do
+      json(conn, status)
     end
   end
 
   def register(conn, params) do
     with {:ok, user} <- TwitterAPI.register_user(params) do
-
       render(conn, UserView, "show.json", %{user: user})
     else
       {:error, errors} ->
index d781af675cdf528df4850b954391b81a4765b57c..6cdb75d089a498c63409a9d9b57a226afba72353 100644 (file)
@@ -121,4 +121,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       assert Repo.get(Activity, activity.id) == activity
     end
   end
+
+  describe "reblogging" do
+    test "reblogs and returns the reblogged status", %{conn: conn} do
+      activity = insert(:note_activity)
+      user = insert(:user)
+
+      conn = conn
+      |> assign(:user, user)
+      |> post("/api/v1/statuses/#{activity.id}/reblog")
+
+      assert %{"id" => id, "reblogged" => true, "reblogs_count" => 1} = json_response(conn, 200)
+      assert activity.id == id
+    end
+  end
 end
index 89b8c2eeb8996d87e02d9014f5ffaa922c486ad3..2c89509ff1bed8aad114039ab4f01ed31cdf4d84 100644 (file)
@@ -354,13 +354,6 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
 
       request_path = "/api/statuses/retweet/#{note_activity.id}.json"
 
-      user = Repo.get_by(User, ap_id: note_activity.data["actor"])
-      response = conn
-      |> with_credentials(user.nickname, "test")
-      |> post(request_path)
-      assert json_response(response, 400) == %{"error" => "You cannot repeat your own notice.",
-                                               "request" => request_path}
-
       response = conn
       |> with_credentials(current_user.nickname, "test")
       |> post(request_path)
index bbb261eff3c143459a90b9058b3ba4827fadd3cc..c1c9b2d2264cc76bebff5187979b3d31308c9edb 100644 (file)
@@ -290,7 +290,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.retweet(user, note_activity)
+    {:ok, status} = TwitterAPI.repeat(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})