forked from AkkomaGang/akkoma
Merge pull request 'purge scrobbling' (#90) from purge/scrobbling into develop
Reviewed-on: AkkomaGang/akkoma#90
This commit is contained in:
commit
ffc5944334
19 changed files with 8 additions and 527 deletions
|
@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Scrobbling support
|
||||||
|
|
||||||
## 2022.07
|
## 2022.07
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -576,38 +576,6 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
|
||||||
* Response: the archive of the pack with a 200 status code, 403 if the pack is not set as shared,
|
* Response: the archive of the pack with a 200 status code, 403 if the pack is not set as shared,
|
||||||
404 if the pack does not exist
|
404 if the pack does not exist
|
||||||
|
|
||||||
## `GET /api/v1/pleroma/accounts/:id/scrobbles`
|
|
||||||
### Requests a list of current and recent Listen activities for an account
|
|
||||||
* Method `GET`
|
|
||||||
* Authentication: not required
|
|
||||||
* Params: None
|
|
||||||
* Response: An array of media metadata entities.
|
|
||||||
* Example response:
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"account": {...},
|
|
||||||
"id": "1234",
|
|
||||||
"title": "Some Title",
|
|
||||||
"artist": "Some Artist",
|
|
||||||
"album": "Some Album",
|
|
||||||
"length": 180000,
|
|
||||||
"created_at": "2019-09-28T12:40:45.000Z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## `POST /api/v1/pleroma/scrobble`
|
|
||||||
### Creates a new Listen activity for an account
|
|
||||||
* Method `POST`
|
|
||||||
* Authentication: required
|
|
||||||
* Params:
|
|
||||||
* `title`: the title of the media playing
|
|
||||||
* `album`: the album of the media playing [optional]
|
|
||||||
* `artist`: the artist of the media playing [optional]
|
|
||||||
* `length`: the length of the media playing [optional]
|
|
||||||
* Response: the newly created media metadata entity representing the Listen activity
|
|
||||||
|
|
||||||
# Emoji Reactions
|
# Emoji Reactions
|
||||||
|
|
||||||
Emoji reactions work a lot like favourites do. They make it possible to react to a post with a single emoji character. To detect the presence of this feature, you can check `pleroma_emoji_reactions` entry in the features list of nodeinfo.
|
Emoji reactions work a lot like favourites do. They make it possible to react to a post with a single emoji character. To detect the presence of this feature, you can check `pleroma_emoji_reactions` entry in the features list of nodeinfo.
|
||||||
|
|
|
@ -318,26 +318,6 @@ defp maybe_schedule_poll_notifications(activity) do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec listen(map()) :: {:ok, Activity.t()} | {:error, any()}
|
|
||||||
def listen(%{to: to, actor: actor, context: context, object: object} = params) do
|
|
||||||
additional = params[:additional] || %{}
|
|
||||||
# only accept false as false value
|
|
||||||
local = !(params[:local] == false)
|
|
||||||
published = params[:published]
|
|
||||||
|
|
||||||
listen_data =
|
|
||||||
make_listen_data(
|
|
||||||
%{to: to, actor: actor, published: published, context: context, object: object},
|
|
||||||
additional
|
|
||||||
)
|
|
||||||
|
|
||||||
with {:ok, activity} <- insert(listen_data, local),
|
|
||||||
_ <- notify_and_stream(activity),
|
|
||||||
:ok <- maybe_federate(activity) do
|
|
||||||
{:ok, activity}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec unfollow(User.t(), User.t(), String.t() | nil, boolean()) ::
|
@spec unfollow(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||||
{:ok, Activity.t()} | nil | {:error, any()}
|
{:ok, Activity.t()} | nil | {:error, any()}
|
||||||
def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||||
|
|
|
@ -384,37 +384,6 @@ def handle_incoming(%{"id" => ""}, _options), do: :error
|
||||||
def handle_incoming(%{"id" => id}, _options) when is_binary(id) and byte_size(id) < 8,
|
def handle_incoming(%{"id" => id}, _options) when is_binary(id) and byte_size(id) < 8,
|
||||||
do: :error
|
do: :error
|
||||||
|
|
||||||
def handle_incoming(
|
|
||||||
%{"type" => "Listen", "object" => %{"type" => "Audio"} = object} = data,
|
|
||||||
options
|
|
||||||
) do
|
|
||||||
actor = Containment.get_actor(data)
|
|
||||||
|
|
||||||
data =
|
|
||||||
Map.put(data, "actor", actor)
|
|
||||||
|> fix_addressing
|
|
||||||
|
|
||||||
with {:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(data["actor"]) do
|
|
||||||
reply_depth = (options[:depth] || 0) + 1
|
|
||||||
options = Keyword.put(options, :depth, reply_depth)
|
|
||||||
object = fix_object(object, options)
|
|
||||||
|
|
||||||
params = %{
|
|
||||||
to: data["to"],
|
|
||||||
object: object,
|
|
||||||
actor: user,
|
|
||||||
context: nil,
|
|
||||||
local: false,
|
|
||||||
published: data["published"],
|
|
||||||
additional: Map.take(data, ["cc", "id"])
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityPub.listen(params)
|
|
||||||
else
|
|
||||||
_e -> :error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc "Rewrite misskey likes into EmojiReacts"
|
@doc "Rewrite misskey likes into EmojiReacts"
|
||||||
def handle_incoming(
|
def handle_incoming(
|
||||||
%{
|
%{
|
||||||
|
@ -695,7 +664,7 @@ def prepare_object(object) do
|
||||||
# """
|
# """
|
||||||
|
|
||||||
def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data)
|
def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data)
|
||||||
when activity_type in ["Create", "Listen"] do
|
when activity_type in ["Create"] do
|
||||||
object =
|
object =
|
||||||
object_id
|
object_id
|
||||||
|> Object.normalize(fetch: false)
|
|> Object.normalize(fetch: false)
|
||||||
|
|
|
@ -713,21 +713,6 @@ def make_create_data(params, additional) do
|
||||||
|> Map.merge(additional)
|
|> Map.merge(additional)
|
||||||
end
|
end
|
||||||
|
|
||||||
#### Listen-related helpers
|
|
||||||
def make_listen_data(params, additional) do
|
|
||||||
published = params.published || make_date()
|
|
||||||
|
|
||||||
%{
|
|
||||||
"type" => "Listen",
|
|
||||||
"to" => params.to |> Enum.uniq(),
|
|
||||||
"actor" => params.actor.ap_id,
|
|
||||||
"object" => params.object,
|
|
||||||
"published" => published,
|
|
||||||
"context" => params.context
|
|
||||||
}
|
|
||||||
|> Map.merge(additional)
|
|
||||||
end
|
|
||||||
|
|
||||||
#### Flag-related helpers
|
#### Flag-related helpers
|
||||||
@spec make_flag_data(map(), map()) :: map()
|
@spec make_flag_data(map(), map()) :: map()
|
||||||
def make_flag_data(%{actor: actor, context: context, content: content} = params, additional) do
|
def make_flag_data(%{actor: actor, context: context, content: content} = params, additional) do
|
||||||
|
|
|
@ -16,7 +16,7 @@ def render("object.json", %{object: %Object{} = object}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("object.json", %{object: %Activity{data: %{"type" => activity_type}} = activity})
|
def render("object.json", %{object: %Activity{data: %{"type" => activity_type}} = activity})
|
||||||
when activity_type in ["Create", "Listen"] do
|
when activity_type in ["Create"] do
|
||||||
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
|
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
|
||||||
object = Object.normalize(activity, fetch: false)
|
object = Object.normalize(activity, fetch: false)
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ def spec(opts \\ []) do
|
||||||
"x-tagGroups": [
|
"x-tagGroups": [
|
||||||
%{
|
%{
|
||||||
"name" => "Accounts",
|
"name" => "Accounts",
|
||||||
"tags" => ["Account actions", "Retrieve account information", "Scrobbles"]
|
"tags" => ["Account actions", "Retrieve account information"]
|
||||||
},
|
},
|
||||||
%{
|
%{
|
||||||
"name" => "Administration",
|
"name" => "Administration",
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
# Pleroma: A lightweight social networking server
|
|
||||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
defmodule Pleroma.Web.ApiSpec.PleromaScrobbleOperation do
|
|
||||||
alias OpenApiSpex.Operation
|
|
||||||
alias OpenApiSpex.Reference
|
|
||||||
alias OpenApiSpex.Schema
|
|
||||||
alias Pleroma.Web.ApiSpec.Schemas.Account
|
|
||||||
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
|
|
||||||
|
|
||||||
import Pleroma.Web.ApiSpec.Helpers
|
|
||||||
|
|
||||||
def open_api_operation(action) do
|
|
||||||
operation = String.to_existing_atom("#{action}_operation")
|
|
||||||
apply(__MODULE__, operation, [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_operation do
|
|
||||||
%Operation{
|
|
||||||
tags: ["Scrobbles"],
|
|
||||||
summary: "Creates a new Listen activity for an account",
|
|
||||||
security: [%{"oAuth" => ["write"]}],
|
|
||||||
operationId: "PleromaAPI.ScrobbleController.create",
|
|
||||||
requestBody: request_body("Parameters", create_request(), requried: true),
|
|
||||||
responses: %{
|
|
||||||
200 => Operation.response("Scrobble", "application/json", scrobble())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def index_operation do
|
|
||||||
%Operation{
|
|
||||||
tags: ["Scrobbles"],
|
|
||||||
summary: "Requests a list of current and recent Listen activities for an account",
|
|
||||||
operationId: "PleromaAPI.ScrobbleController.index",
|
|
||||||
parameters: [
|
|
||||||
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"} | pagination_params()
|
|
||||||
],
|
|
||||||
security: [%{"oAuth" => ["read"]}],
|
|
||||||
responses: %{
|
|
||||||
200 =>
|
|
||||||
Operation.response("Array of Scrobble", "application/json", %Schema{
|
|
||||||
type: :array,
|
|
||||||
items: scrobble()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp create_request do
|
|
||||||
%Schema{
|
|
||||||
type: :object,
|
|
||||||
required: [:title],
|
|
||||||
properties: %{
|
|
||||||
title: %Schema{type: :string, description: "The title of the media playing"},
|
|
||||||
album: %Schema{type: :string, description: "The album of the media playing"},
|
|
||||||
artist: %Schema{type: :string, description: "The artist of the media playing"},
|
|
||||||
length: %Schema{type: :integer, description: "The length of the media playing"},
|
|
||||||
visibility: %Schema{
|
|
||||||
allOf: [VisibilityScope],
|
|
||||||
default: "public",
|
|
||||||
description: "Scrobble visibility"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
example: %{
|
|
||||||
"title" => "Some Title",
|
|
||||||
"artist" => "Some Artist",
|
|
||||||
"album" => "Some Album",
|
|
||||||
"length" => 180_000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp scrobble do
|
|
||||||
%Schema{
|
|
||||||
type: :object,
|
|
||||||
properties: %{
|
|
||||||
id: %Schema{type: :string},
|
|
||||||
account: Account,
|
|
||||||
title: %Schema{type: :string, description: "The title of the media playing"},
|
|
||||||
album: %Schema{type: :string, description: "The album of the media playing"},
|
|
||||||
artist: %Schema{type: :string, description: "The artist of the media playing"},
|
|
||||||
length: %Schema{
|
|
||||||
type: :integer,
|
|
||||||
description: "The length of the media playing",
|
|
||||||
nullable: true
|
|
||||||
},
|
|
||||||
created_at: %Schema{type: :string, format: :"date-time"}
|
|
||||||
},
|
|
||||||
example: %{
|
|
||||||
"id" => "1234",
|
|
||||||
"account" => Account.schema().example,
|
|
||||||
"title" => "Some Title",
|
|
||||||
"artist" => "Some Artist",
|
|
||||||
"album" => "Some Album",
|
|
||||||
"length" => 180_000,
|
|
||||||
"created_at" => "2019-09-28T12:40:45.000Z"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -388,12 +388,6 @@ def check_expiry_date(expiry_str) do
|
||||||
|> check_expiry_date()
|
|> check_expiry_date()
|
||||||
end
|
end
|
||||||
|
|
||||||
def listen(user, data) do
|
|
||||||
with {:ok, draft} <- ActivityDraft.listen(user, data) do
|
|
||||||
ActivityPub.listen(draft.changes)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def post(user, %{status: _} = data) do
|
def post(user, %{status: _} = data) do
|
||||||
with {:ok, draft} <- ActivityDraft.create(user, data) do
|
with {:ok, draft} <- ActivityDraft.create(user, data) do
|
||||||
ActivityPub.create(draft.changes, draft.preview?)
|
ActivityPub.create(draft.changes, draft.preview?)
|
||||||
|
|
|
@ -64,30 +64,6 @@ def create(user, params) do
|
||||||
|> validate()
|
|> validate()
|
||||||
end
|
end
|
||||||
|
|
||||||
def listen(user, params) do
|
|
||||||
user
|
|
||||||
|> new(params)
|
|
||||||
|> visibility()
|
|
||||||
|> to_and_cc()
|
|
||||||
|> context()
|
|
||||||
|> listen_object()
|
|
||||||
|> with_valid(&changes/1)
|
|
||||||
|> validate()
|
|
||||||
end
|
|
||||||
|
|
||||||
defp listen_object(draft) do
|
|
||||||
object =
|
|
||||||
draft.params
|
|
||||||
|> Map.take([:album, :artist, :title, :length])
|
|
||||||
|> Map.new(fn {key, value} -> {to_string(key), value} end)
|
|
||||||
|> Map.put("type", "Audio")
|
|
||||||
|> Map.put("to", draft.to)
|
|
||||||
|> Map.put("cc", draft.cc)
|
|
||||||
|> Map.put("actor", draft.user.ap_id)
|
|
||||||
|
|
||||||
%__MODULE__{draft | object: object}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp put_params(draft, params) do
|
defp put_params(draft, params) do
|
||||||
params = Map.put_new(params, :in_reply_to_status_id, params[:in_reply_to_id])
|
params = Map.put_new(params, :in_reply_to_status_id, params[:in_reply_to_id])
|
||||||
%__MODULE__{draft | params: params}
|
%__MODULE__{draft | params: params}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
# Pleroma: A lightweight social networking server
|
|
||||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
defmodule Pleroma.Web.PleromaAPI.ScrobbleController do
|
|
||||||
use Pleroma.Web, :controller
|
|
||||||
|
|
||||||
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
|
|
||||||
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
|
||||||
|
|
||||||
plug(
|
|
||||||
OAuthScopesPlug,
|
|
||||||
%{scopes: ["read"], fallback: :proceed_unauthenticated} when action == :index
|
|
||||||
)
|
|
||||||
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write"]} when action == :create)
|
|
||||||
|
|
||||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaScrobbleOperation
|
|
||||||
|
|
||||||
def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
|
||||||
with {:ok, activity} <- CommonAPI.listen(user, params) do
|
|
||||||
render(conn, "show.json", activity: activity, for: user)
|
|
||||||
else
|
|
||||||
{:error, message} ->
|
|
||||||
conn
|
|
||||||
|> put_status(:bad_request)
|
|
||||||
|> json(%{"error" => message})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def index(%{assigns: %{user: reading_user}} = conn, %{id: id} = params) do
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname_or_id(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)
|
|
||||||
|> render("index.json", %{
|
|
||||||
activities: activities,
|
|
||||||
for: reading_user,
|
|
||||||
as: :activity
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Pleroma: A lightweight social networking server
|
|
||||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
defmodule Pleroma.Web.PleromaAPI.ScrobbleView do
|
|
||||||
use Pleroma.Web, :view
|
|
||||||
|
|
||||||
require Pleroma.Constants
|
|
||||||
|
|
||||||
alias Pleroma.Activity
|
|
||||||
alias Pleroma.HTML
|
|
||||||
alias Pleroma.Object
|
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
|
||||||
alias Pleroma.Web.MastodonAPI.AccountView
|
|
||||||
|
|
||||||
def render("show.json", %{activity: %Activity{data: %{"type" => "Listen"}} = activity} = opts) do
|
|
||||||
object = Object.normalize(activity, fetch: false)
|
|
||||||
|
|
||||||
user = CommonAPI.get_user(activity.data["actor"])
|
|
||||||
created_at = Utils.to_masto_date(activity.data["published"])
|
|
||||||
|
|
||||||
%{
|
|
||||||
id: activity.id,
|
|
||||||
account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
|
|
||||||
created_at: created_at,
|
|
||||||
title: object.data["title"] |> HTML.strip_tags(),
|
|
||||||
artist: object.data["artist"] |> HTML.strip_tags(),
|
|
||||||
album: object.data["album"] |> HTML.strip_tags(),
|
|
||||||
length: object.data["length"]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def render("index.json", opts) do
|
|
||||||
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -448,8 +448,6 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/mascot", MascotController, :show)
|
get("/mascot", MascotController, :show)
|
||||||
put("/mascot", MascotController, :update)
|
put("/mascot", MascotController, :update)
|
||||||
|
|
||||||
post("/scrobble", ScrobbleController, :create)
|
|
||||||
|
|
||||||
get("/backups", BackupController, :index)
|
get("/backups", BackupController, :index)
|
||||||
post("/backups", BackupController, :create)
|
post("/backups", BackupController, :create)
|
||||||
end
|
end
|
||||||
|
@ -471,7 +469,6 @@ defmodule Pleroma.Web.Router do
|
||||||
|
|
||||||
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
||||||
pipe_through(:api)
|
pipe_through(:api)
|
||||||
get("/accounts/:id/scrobbles", ScrobbleController, :index)
|
|
||||||
get("/federation_status", InstancesController, :show)
|
get("/federation_status", InstancesController, :show)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -543,42 +543,6 @@ test "adds an id to a given object if it lacks one and is a note and inserts it
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "listen activities" do
|
|
||||||
test "does not increase user note count" do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
{:ok, activity} =
|
|
||||||
ActivityPub.listen(%{
|
|
||||||
to: ["https://www.w3.org/ns/activitystreams#Public"],
|
|
||||||
actor: user,
|
|
||||||
context: "",
|
|
||||||
object: %{
|
|
||||||
"actor" => user.ap_id,
|
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
|
||||||
"artist" => "lain",
|
|
||||||
"title" => "lain radio episode 1",
|
|
||||||
"length" => 180_000,
|
|
||||||
"type" => "Audio"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
assert activity.actor == user.ap_id
|
|
||||||
|
|
||||||
user = User.get_cached_by_id(user.id)
|
|
||||||
assert user.note_count == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
test "can be fetched into a timeline" do
|
|
||||||
_listen_activity_1 = insert(:listen)
|
|
||||||
_listen_activity_2 = insert(:listen)
|
|
||||||
_listen_activity_3 = insert(:listen)
|
|
||||||
|
|
||||||
timeline = ActivityPub.fetch_activities([], %{type: ["Listen"]})
|
|
||||||
|
|
||||||
assert length(timeline) == 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "create activities" do
|
describe "create activities" do
|
||||||
setup do
|
setup do
|
||||||
[user: insert(:user)]
|
[user: insert(:user)]
|
||||||
|
|
|
@ -12,39 +12,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
test "it works for incoming listens" do
|
|
||||||
_user = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
|
|
||||||
|
|
||||||
data = %{
|
|
||||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
|
||||||
"cc" => [],
|
|
||||||
"type" => "Listen",
|
|
||||||
"id" => "http://mastodon.example.org/users/admin/listens/1234/activity",
|
|
||||||
"actor" => "http://mastodon.example.org/users/admin",
|
|
||||||
"object" => %{
|
|
||||||
"type" => "Audio",
|
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
|
||||||
"cc" => [],
|
|
||||||
"id" => "http://mastodon.example.org/users/admin/listens/1234",
|
|
||||||
"attributedTo" => "http://mastodon.example.org/users/admin",
|
|
||||||
"title" => "lain radio episode 1",
|
|
||||||
"artist" => "lain",
|
|
||||||
"album" => "lain radio",
|
|
||||||
"length" => 180_000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
|
|
||||||
|
|
||||||
object = Object.normalize(activity, fetch: false)
|
|
||||||
|
|
||||||
assert object.data["title"] == "lain radio episode 1"
|
|
||||||
assert object.data["artist"] == "lain"
|
|
||||||
assert object.data["album"] == "lain radio"
|
|
||||||
assert object.data["length"] == 180_000
|
|
||||||
end
|
|
||||||
|
|
||||||
test "Funkwhale Audio object" do
|
test "Funkwhale Audio object" do
|
||||||
Tesla.Mock.mock(fn
|
Tesla.Mock.mock(fn
|
||||||
%{url: "https://channels.tests.funkwhale.audio/federation/actors/compositions"} ->
|
%{url: "https://channels.tests.funkwhale.audio/federation/actors/compositions"} ->
|
||||||
|
|
|
@ -273,20 +273,6 @@ test "it strips BCC field" do
|
||||||
assert is_nil(modified["bcc"])
|
assert is_nil(modified["bcc"])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it can handle Listen activities" do
|
|
||||||
listen_activity = insert(:listen)
|
|
||||||
|
|
||||||
{:ok, modified} = Transmogrifier.prepare_outgoing(listen_activity.data)
|
|
||||||
|
|
||||||
assert modified["type"] == "Listen"
|
|
||||||
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
{:ok, activity} = CommonAPI.listen(user, %{"title" => "lain radio episode 1"})
|
|
||||||
|
|
||||||
{:ok, _modified} = Transmogrifier.prepare_outgoing(activity.data)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "custom emoji urls are URI encoded" do
|
test "custom emoji urls are URI encoded" do
|
||||||
# :dinosaur: filename has a space -> dino walking.gif
|
# :dinosaur: filename has a space -> dino walking.gif
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -1331,45 +1331,6 @@ test "does not allow to vote twice" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "listen/2" do
|
|
||||||
test "returns a valid activity" do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
{:ok, activity} =
|
|
||||||
CommonAPI.listen(user, %{
|
|
||||||
title: "lain radio episode 1",
|
|
||||||
album: "lain radio",
|
|
||||||
artist: "lain",
|
|
||||||
length: 180_000
|
|
||||||
})
|
|
||||||
|
|
||||||
object = Object.normalize(activity, fetch: false)
|
|
||||||
|
|
||||||
assert object.data["title"] == "lain radio episode 1"
|
|
||||||
|
|
||||||
assert Visibility.get_visibility(activity) == "public"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "respects visibility=private" do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
{:ok, activity} =
|
|
||||||
CommonAPI.listen(user, %{
|
|
||||||
title: "lain radio episode 1",
|
|
||||||
album: "lain radio",
|
|
||||||
artist: "lain",
|
|
||||||
length: 180_000,
|
|
||||||
visibility: "private"
|
|
||||||
})
|
|
||||||
|
|
||||||
object = Object.normalize(activity, fetch: false)
|
|
||||||
|
|
||||||
assert object.data["title"] == "lain radio episode 1"
|
|
||||||
|
|
||||||
assert Visibility.get_visibility(activity) == "private"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "get_user/1" do
|
describe "get_user/1" do
|
||||||
test "gets user by ap_id" do
|
test "gets user by ap_id" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
# Pleroma: A lightweight social networking server
|
|
||||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
|
|
||||||
use Pleroma.Web.ConnCase, async: true
|
|
||||||
|
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
|
|
||||||
describe "POST /api/v1/pleroma/scrobble" do
|
|
||||||
test "works correctly" do
|
|
||||||
%{conn: conn} = oauth_access(["write"])
|
|
||||||
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> put_req_header("content-type", "application/json")
|
|
||||||
|> post("/api/v1/pleroma/scrobble", %{
|
|
||||||
"title" => "lain radio episode 1",
|
|
||||||
"artist" => "lain",
|
|
||||||
"album" => "lain radio",
|
|
||||||
"length" => "180000"
|
|
||||||
})
|
|
||||||
|
|
||||||
assert %{"title" => "lain radio episode 1"} = json_response_and_validate_schema(conn, 200)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /api/v1/pleroma/accounts/:id/scrobbles" do
|
|
||||||
test "works correctly" do
|
|
||||||
%{user: user, conn: conn} = oauth_access(["read"])
|
|
||||||
|
|
||||||
{: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 = get(conn, "/api/v1/pleroma/accounts/#{user.id}/scrobbles")
|
|
||||||
|
|
||||||
result = json_response_and_validate_schema(conn, 200)
|
|
||||||
|
|
||||||
assert length(result) == 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Pleroma: A lightweight social networking server
|
|
||||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
defmodule Pleroma.Web.PleromaAPI.ScrobbleViewTest do
|
|
||||||
use Pleroma.DataCase, async: true
|
|
||||||
|
|
||||||
alias Pleroma.Web.PleromaAPI.ScrobbleView
|
|
||||||
|
|
||||||
import Pleroma.Factory
|
|
||||||
|
|
||||||
test "successfully renders a Listen activity (pleroma extension)" do
|
|
||||||
listen_activity = insert(:listen)
|
|
||||||
|
|
||||||
status = ScrobbleView.render("show.json", activity: listen_activity)
|
|
||||||
|
|
||||||
assert status.length == listen_activity.data["object"]["length"]
|
|
||||||
assert status.title == listen_activity.data["object"]["title"]
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue