pleroma api: hook up scrobbler controller
authorAriadne Conill <ariadne@dereferenced.org>
Sat, 28 Sep 2019 02:12:12 +0000 (02:12 +0000)
committerAriadne Conill <ariadne@dereferenced.org>
Mon, 30 Sep 2019 10:39:17 +0000 (10:39 +0000)
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
lib/pleroma/web/router.ex
test/web/pleroma_api/controllers/scrobble_controller_test.exs [new file with mode: 0644]

index 4250735413aae356d76f0085e2ea77236d3ee987..95f994c17055470ea885120561808c5b54c87d99 100644 (file)
@@ -608,6 +608,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_thread_visibility(query, _, _), do: query
 
+  def fetch_user_abstract_activities(user, reading_user, params \\ %{}) do
+    params =
+      params
+      |> Map.put("user", reading_user)
+      |> Map.put("actor_id", user.ap_id)
+      |> Map.put("whole_db", true)
+
+    recipients =
+      user_activities_recipients(%{
+        "godmode" => params["godmode"],
+        "reading_user" => reading_user
+      })
+
+    fetch_activities(recipients, params)
+    |> Enum.reverse()
+  end
+
   def fetch_user_activities(user, reading_user, params \\ %{}) do
     params =
       params
index cf024a83c771931680105f15d8235ccf6d2a86d1..d398f7853088e9ba9d456f30ad09cc9c04d66355 100644 (file)
@@ -385,6 +385,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     }
   end
 
+  def render("listens.json", opts) do
+    safe_render_many(opts.activities, StatusView, "listen.json", opts)
+  end
+
   def render("poll.json", %{object: object} = opts) do
     {multiple, options} =
       case object.data do
index d17ccf84d0778ff5de3972f365a8a5df12e12f76..1b0ed1f40cd2186d4cb66575ef7c8ec2e8ba1d24 100644 (file)
@@ -5,11 +5,13 @@
 defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
   use Pleroma.Web, :controller
 
-  import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
+  import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, fetch_integer_param: 2]
 
   alias Pleroma.Conversation.Participation
   alias Pleroma.Notification
+  alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.MastodonAPI.ConversationView
   alias Pleroma.Web.MastodonAPI.NotificationView
   alias Pleroma.Web.MastodonAPI.StatusView
@@ -86,4 +88,42 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
       |> render("index.json", %{notifications: notifications, for: user})
     end
   end
+
+  def update_now_playing(%{assigns: %{user: user}} = conn, %{"title" => _} = params) do
+    params =
+      if !params["length"] do
+        params
+      else
+        params
+        |> Map.put("length", fetch_integer_param(params, "length"))
+      end
+
+    with {:ok, activity} <- CommonAPI.listen(user, params) do
+      conn
+      |> put_view(StatusView)
+      |> render("listen.json", %{activity: activity, for: user})
+    else
+      {:error, message} ->
+        conn
+        |> put_status(:bad_request)
+        |> json(%{"error" => message})
+    end
+  end
+
+  def user_now_playing(%{assigns: %{user: reading_user}} = conn, params) do
+    with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do
+      params = Map.put(params, "type", ["Listen"])
+
+      activities = ActivityPub.fetch_user_abstract_activities(user, reading_user, params)
+
+      conn
+      |> add_link_headers(activities)
+      |> put_view(StatusView)
+      |> render("listens.json", %{
+        activities: activities,
+        for: reading_user,
+        as: :activity
+      })
+    end
+  end
 end
index 805bef16f176089eefc57d7e1b47b199bb43f2f7..bd5f02af1739924ccce042ed8641d8edae47c899 100644 (file)
@@ -300,6 +300,17 @@ defmodule Pleroma.Web.Router do
       patch("/conversations/:id", PleromaAPIController, :update_conversation)
       post("/notifications/read", PleromaAPIController, :read_notification)
     end
+
+    scope [] do
+      pipe_through(:oauth_write)
+      post("/now-playing", PleromaAPIController, :update_now_playing)
+    end
+  end
+
+  scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
+    pipe_through([:api, :oauth_read_or_public])
+
+    get("/accounts/:id/now-playing", PleromaAPIController, :user_now_playing)
   end
 
   scope "/api/v1", Pleroma.Web.MastodonAPI do
diff --git a/test/web/pleroma_api/controllers/scrobble_controller_test.exs b/test/web/pleroma_api/controllers/scrobble_controller_test.exs
new file mode 100644 (file)
index 0000000..8cbb588
--- /dev/null
@@ -0,0 +1,63 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
+  use Pleroma.Web.ConnCase
+
+  alias Pleroma.Web.CommonAPI
+  import Pleroma.Factory
+
+  describe "POST /api/v1/pleroma/now-playing" do
+    test "works correctly", %{conn: conn} do
+      user = insert(:user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> post("/api/v1/pleroma/now-playing", %{
+          "title" => "lain radio episode 1",
+          "artist" => "lain",
+          "album" => "lain radio",
+          "length" => "180000"
+        })
+
+      assert %{"title" => "lain radio episode 1"} = json_response(conn, 200)
+    end
+  end
+
+  describe "GET /api/v1/pleroma/accounts/:id/now-playing" do
+    test "works correctly", %{conn: conn} do
+      user = insert(:user)
+
+      {:ok, _activity} =
+        CommonAPI.listen(user, %{
+          "title" => "lain radio episode 1",
+          "artist" => "lain",
+          "album" => "lain radio"
+        })
+
+      {:ok, _activity} =
+        CommonAPI.listen(user, %{
+          "title" => "lain radio episode 2",
+          "artist" => "lain",
+          "album" => "lain radio"
+        })
+
+      {:ok, _activity} =
+        CommonAPI.listen(user, %{
+          "title" => "lain radio episode 3",
+          "artist" => "lain",
+          "album" => "lain radio"
+        })
+
+      conn =
+        conn
+        |> get("/api/v1/pleroma/accounts/#{user.id}/now-playing")
+
+      result = json_response(conn, 200)
+
+      assert length(result) == 3
+    end
+  end
+end