From 1388054796feed8f03d659171bbbc0c21056dd2f Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Thu, 13 Apr 2017 15:50:05 +0200 Subject: [PATCH] Add liking to ActivityPub. --- lib/pleroma/web/activity_pub/activity_pub.ex | 34 ++++++++++++++++++-- test/web/activity_pub/activity_pub_test.exs | 24 ++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 75e4101f2..10efa2c9d 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1,10 +1,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do alias Pleroma.Repo - alias Pleroma.{Activity, Object, Upload} + alias Pleroma.{Activity, Object, Upload, User} import Ecto.Query def insert(map) when is_map(map) do - map = Map.put_new_lazy(map, "id", &generate_activity_id/0) + map = map + |> Map.put_new_lazy("id", &generate_activity_id/0) + |> Map.put_new_lazy("published", &make_date/0) map = if is_map(map["object"]) do object = Map.put_new_lazy(map["object"], "id", &generate_object_id/0) @@ -17,6 +19,30 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do Repo.insert(%Activity{data: map}) end + def like(%User{ap_id: ap_id}, object = %Object{data: %{ "id" => id}}) do + data = %{ + "type" => "Like", + "actor" => ap_id, + "object" => id + } + + {:ok, activity} = insert(data) + like_count = (object.data["like_count"] || 0) + 1 + new_data = object.data |> Map.put("like_count", like_count) + changeset = Ecto.Changeset.change(object, data: new_data) + {:ok, object} = Repo.update(changeset) + + # Update activities that already had this. Could be done in a seperate process. + relevant_activities = Activity.all_by_object_ap_id(id) + Enum.map(relevant_activities, fn (activity) -> + new_activity_data = activity.data |> Map.put("object", new_data) + changeset = Ecto.Changeset.change(activity, data: new_activity_data) + Repo.update(changeset) + end) + + {:ok, activity, object} + end + def generate_activity_id do generate_id("activities") end @@ -74,4 +100,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do data = Upload.store(file) Repo.insert(%Object{data: data}) end + + defp make_date do + DateTime.utc_now() |> DateTime.to_iso8601 + end end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 5cfd46238..2bdd439b0 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -4,6 +4,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do alias Pleroma.{Activity, Object} alias Pleroma.Builders.ActivityBuilder + import Pleroma.Factory + describe "insertion" do test "inserts a given map into the activity database, giving it an id if it has none." do data = %{ @@ -110,6 +112,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end end + describe "like an object" do + test "adds a like activity to the db" do + note_activity = insert(:note_activity) + object = Object.get_by_ap_id(note_activity.data["object"]["id"]) + user = insert(:user) + user_two = insert(:user) + + {:ok, like_activity, object} = ActivityPub.like(user, object) + + assert like_activity.data["actor"] == user.ap_id + assert like_activity.data["type"] == "Like" + assert like_activity.data["object"] == object.data["id"] + assert object.data["like_count"] == 1 + + [note_activity] = Activity.all_by_object_ap_id(object.data["id"]) + assert note_activity.data["object"]["like_count"] == 1 + + {:ok, _like_activity, object} = ActivityPub.like(user_two, object) + assert object.data["like_count"] == 2 + end + end + describe "uploading files" do test "copies the file to the configured folder" do file = %Plug.Upload{content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg"}