diff --git a/lib/service/activity_pub/transmogrifier.ex b/lib/service/activity_pub/transmogrifier.ex index 2c093d96..1c2a99c4 100644 --- a/lib/service/activity_pub/transmogrifier.ex +++ b/lib/service/activity_pub/transmogrifier.ex @@ -18,24 +18,39 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do object |> Map.put("actor", object["attributedTo"]) |> fix_attachments - # |> fix_in_reply_to + |> fix_in_reply_to |> fix_tag end - # def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object) - # when not is_nil(in_reply_to_id) do - # case ActivityPub.fetch_object_from_id(in_reply_to_id) do - # {:ok, replied_object} -> - # activity = Activity.get_create_activity_by_object_ap_id(replied_object.data["id"]) - # - # object - # |> Map.put("inReplyTo", replied_object.data["id"]) - # - # e -> - # Logger.error("Couldn't fetch #{object["inReplyTo"]} #{inspect(e)}") - # object - # end - # end + def fix_in_reply_to(%{"inReplyTo" => in_reply_to} = object) + when not is_nil(in_reply_to) do + in_reply_to_id = + cond do + is_bitstring(in_reply_to) -> # If the inReplyTo is just an AP ID + in_reply_to + + is_map(in_reply_to) && is_bitstring(in_reply_to["id"]) -> # If the inReplyTo is a object itself + in_reply_to["id"] + + is_list(in_reply_to) && is_bitstring(Enum.at(in_reply_to, 0)) -> # If the inReplyTo is an array + Enum.at(in_reply_to, 0) + + true -> + Logger.error("inReplyTo ID seem incorrect") + Logger.error(inspect(in_reply_to)) + "" + end + + case fetch_obj_helper(in_reply_to_id) do + {:ok, replied_object} -> + object + |> Map.put("inReplyTo", replied_object.data["id"]) + + e -> + Logger.error("Couldn't fetch #{in_reply_to_id} #{inspect(e)}") + object + end + end def fix_in_reply_to(object), do: object @@ -295,6 +310,22 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do # end # end # + + def add_hashtags(object) do + tags = + (object["tag"] || []) + |> Enum.map(fn tag -> + %{ + "href" => MobilizonWeb.Endpoint.url() <> "/tags/#{tag}", + "name" => "##{tag}", + "type" => "Hashtag" + } + end) + + object + |> Map.put("tag", tags) + end + def add_mention_tags(object) do recipients = object["to"] ++ (object["cc"] || []) @@ -359,4 +390,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do # object # |> Map.put("attachment", attachments) # end + + def fetch_obj_helper(url) when is_bitstring(url), do: ActivityPub.fetch_object_from_url(url) + def fetch_obj_helper(obj) when is_map(obj), do: ActivityPub.fetch_object_from_url(obj["id"]) end diff --git a/lib/service/activity_pub/utils.ex b/lib/service/activity_pub/utils.ex index 74a645fd..caf69f17 100644 --- a/lib/service/activity_pub/utils.ex +++ b/lib/service/activity_pub/utils.ex @@ -50,29 +50,10 @@ defmodule Mobilizon.Service.ActivityPub.Utils do generate_id("contexts") end - # def generate_object_id do - # Helpers.o_status_url(Endpoint, :object, UUID.generate()) - # end - def generate_id(type) do "#{MobilizonWeb.Endpoint.url()}/#{type}/#{UUID.generate()}" end - # def create_context(context) do - # context = context || generate_id("contexts") - # changeset = Object.context_mapping(context) - # - # case Repo.insert(changeset) do - # {:ok, object} -> - # object - # - # # This should be solved by an upsert, but it seems ecto - # # has problems accessing the constraint inside the jsonb. - # {:error, _} -> - # Events.get_cached_by_url(context) - # end - # end - @doc """ Enqueues an activity for federation if it's local """ @@ -105,15 +86,6 @@ defmodule Mobilizon.Service.ActivityPub.Utils do also adds it to an included object """ def lazy_put_activity_defaults(map) do - # %{data: %{"id" => context}, id: context_id} = create_context(map["context"]) - # - # map = - # map - # |> Map.put_new_lazy("id", &generate_activity_id/0) - # |> Map.put_new_lazy("published", &make_date/0) - # |> Map.put_new("context", context) - # |> Map.put_new("context_id", context_id) - if is_map(map["object"]) do object = lazy_put_object_defaults(map["object"], map) %{map | "object" => object} @@ -127,10 +99,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do """ def lazy_put_object_defaults(map, activity \\ %{}) do map - # |> Map.put_new_lazy("id", &generate_object_id/0) |> Map.put_new_lazy("published", &make_date/0) - |> Map.put_new("context", activity["context"]) - |> Map.put_new("context_id", activity["context_id"]) end @doc """ @@ -161,7 +130,6 @@ defmodule Mobilizon.Service.ActivityPub.Utils do "in_reply_to_comment_id" => nil, "event_id" => nil, "uuid" => object_data["uuid"], - # probably "local" => local } @@ -214,20 +182,6 @@ defmodule Mobilizon.Service.ActivityPub.Utils do def insert_full_object(_, _), do: :ok - # def update_object_in_activities(%{data: %{"id" => id}} = object) do - # # TODO - # # Update activities that already had this. Could be done in a seperate process. - # # Alternatively, just don't do this and fetch the current object each time. Most - # # could probably be taken from cache. - # relevant_activities = Activity.all_by_object_url(id) - # - # Enum.map(relevant_activities, fn activity -> - # new_activity_data = activity.data |> Map.put("object", object.data) - # changeset = Changeset.change(activity, data: new_activity_data) - # Repo.update(changeset) - # end) - # end - #### Like-related helpers # @doc """ @@ -273,7 +227,8 @@ defmodule Mobilizon.Service.ActivityPub.Utils do # "summary" => cw, # "attachment" => attachments, "actor" => actor, - "id" => "#{MobilizonWeb.Endpoint.url()}/comments/#{uuid}" + "id" => "#{MobilizonWeb.Endpoint.url()}/comments/#{uuid}", + "uuid" => uuid # "tag" => tags |> Enum.map(fn {_, tag} -> tag end) |> Enum.uniq() } @@ -348,23 +303,6 @@ defmodule Mobilizon.Service.ActivityPub.Utils do else: data end - # def fetch_latest_follow(%Actor{url: follower_id}, %Actor{url: followed_id}) do - # query = - # from( - # activity in Activity, - # where: - # fragment( - # "? @> ?", - # activity.data, - # ^%{type: "Follow", actor: follower_id, object: followed_id} - # ), - # order_by: [desc: :id], - # limit: 1 - # ) - # - # Repo.one(query) - # end - #### Announce-related helpers @doc """