forked from AkkomaGang/akkoma
Add reblogging to MastodonAPI.
This commit is contained in:
parent
4dc517a0bb
commit
66e4c710d4
9 changed files with 58 additions and 33 deletions
|
@ -10,4 +10,25 @@ def delete(activity_id, user) do
|
||||||
{:ok, delete}
|
{:ok, delete}
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -80,4 +80,11 @@ def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|> json(%{error: "Can't delete this post"})
|
|> json(%{error: "Can't delete this post"})
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ def render("index.json", opts) do
|
||||||
render_many(opts.activities, StatusView, "status.json", opts)
|
render_many(opts.activities, StatusView, "status.json", opts)
|
||||||
end
|
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"])
|
user = User.get_cached_by_ap_id(activity.data["actor"])
|
||||||
|
|
||||||
like_count = object["like_count"] || 0
|
like_count = object["like_count"] || 0
|
||||||
|
@ -21,6 +21,8 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity}
|
||||||
|> Enum.filter(&(&1))
|
|> Enum.filter(&(&1))
|
||||||
|> Enum.map(fn (user) -> AccountView.render("mention.json", %{user: user}) end)
|
|> Enum.map(fn (user) -> AccountView.render("mention.json", %{user: user}) end)
|
||||||
|
|
||||||
|
repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || [])
|
||||||
|
|
||||||
%{
|
%{
|
||||||
id: activity.id,
|
id: activity.id,
|
||||||
uri: object["id"],
|
uri: object["id"],
|
||||||
|
@ -33,7 +35,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity}
|
||||||
created_at: object["published"],
|
created_at: object["published"],
|
||||||
reblogs_count: announcement_count,
|
reblogs_count: announcement_count,
|
||||||
favourites_count: like_count,
|
favourites_count: like_count,
|
||||||
reblogged: false,
|
reblogged: !!repeated,
|
||||||
favourited: false, # fix
|
favourited: false, # fix
|
||||||
muted: false,
|
muted: false,
|
||||||
sensitive: sensitive,
|
sensitive: sensitive,
|
||||||
|
|
|
@ -57,6 +57,8 @@ def user_fetcher(username) do
|
||||||
|
|
||||||
post "/statuses", MastodonAPIController, :post_status
|
post "/statuses", MastodonAPIController, :post_status
|
||||||
delete "/statuses/:id", MastodonAPIController, :delete_status
|
delete "/statuses/:id", MastodonAPIController, :delete_status
|
||||||
|
|
||||||
|
post "/statuses/:id/reblog", MastodonAPIController, :reblog_status
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/api", Pleroma.Web do
|
scope "/api", Pleroma.Web do
|
||||||
|
|
|
@ -3,7 +3,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
|
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
|
||||||
alias Pleroma.Web.TwitterAPI.UserView
|
alias Pleroma.Web.TwitterAPI.UserView
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.{OStatus, CommonAPI}
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
|
|
||||||
import Pleroma.Web.TwitterAPI.Utils
|
import Pleroma.Web.TwitterAPI.Utils
|
||||||
|
@ -141,17 +141,12 @@ def unfavorite(%User{} = user, %Activity{data: %{"object" => object}} = activity
|
||||||
{:ok, status}
|
{:ok, status}
|
||||||
end
|
end
|
||||||
|
|
||||||
def retweet(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
|
def repeat(%User{} = user, ap_id_or_id) do
|
||||||
object = Object.get_by_ap_id(object["id"])
|
with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(ap_id_or_id, user),
|
||||||
|
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id),
|
||||||
{:ok, _announce_activity, object} = ActivityPub.announce(user, object)
|
status <- activity_to_status(activity, %{for: user}) do
|
||||||
new_data = activity.data
|
{:ok, status}
|
||||||
|> Map.put("object", object.data)
|
end
|
||||||
|
|
||||||
status = %{activity | data: new_data}
|
|
||||||
|> activity_to_status(%{for: user})
|
|
||||||
|
|
||||||
{:ok, status}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload(%Plug.Upload{} = file, format \\ "xml") do
|
def upload(%Plug.Upload{} = file, format \\ "xml") do
|
||||||
|
|
|
@ -167,22 +167,13 @@ def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
activity = get_by_id_or_ap_id(id)
|
with {:ok, status} <- TwitterAPI.repeat(user, id) do
|
||||||
if activity.data["actor"] == user.ap_id do
|
json(conn, status)
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def register(conn, params) do
|
def register(conn, params) do
|
||||||
with {:ok, user} <- TwitterAPI.register_user(params) do
|
with {:ok, user} <- TwitterAPI.register_user(params) do
|
||||||
|
|
||||||
render(conn, UserView, "show.json", %{user: user})
|
render(conn, UserView, "show.json", %{user: user})
|
||||||
else
|
else
|
||||||
{:error, errors} ->
|
{:error, errors} ->
|
||||||
|
|
|
@ -121,4 +121,18 @@ test "when you didn't create it", %{conn: conn} do
|
||||||
assert Repo.get(Activity, activity.id) == activity
|
assert Repo.get(Activity, activity.id) == activity
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -354,13 +354,6 @@ test "with credentials", %{conn: conn, user: current_user} do
|
||||||
|
|
||||||
request_path = "/api/statuses/retweet/#{note_activity.id}.json"
|
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
|
response = conn
|
||||||
|> with_credentials(current_user.nickname, "test")
|
|> with_credentials(current_user.nickname, "test")
|
||||||
|> post(request_path)
|
|> post(request_path)
|
||||||
|
|
|
@ -290,7 +290,7 @@ test "it retweets a status and returns the retweet" do
|
||||||
note_activity = insert(:note_activity)
|
note_activity = insert(:note_activity)
|
||||||
activity_user = Repo.get_by!(User, ap_id: note_activity.data["actor"])
|
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"])
|
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
|
||||||
|
|
||||||
assert status == ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})
|
assert status == ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})
|
||||||
|
|
Loading…
Reference in a new issue