X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fostatus%2Fostatus.ex;h=7aa1ac4acfd8d5882f16ff8d6b1a7339107ee547;hb=018a1a390fdb72652c615c28ac36f1b9a6a84d82;hp=59c5d8e9e177d02fd4a32f77b6ed81f93abf2e72;hpb=20015b4b67cf0dfab6bdb658c9eb0e1ae04febdc;p=akkoma diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 59c5d8e9e..7aa1ac4ac 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -3,7 +3,7 @@ defmodule Pleroma.Web.OStatus do import Pleroma.Web.XML require Logger - alias Pleroma.{Repo, User, Web} + alias Pleroma.{Repo, User, Web, Object} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.{WebFinger, Websub} @@ -21,44 +21,57 @@ defmodule Pleroma.Web.OStatus do def handle_incoming(xml_string) do doc = parse_document(xml_string) - - {:xmlObj, :string, object_type } = :xmerl_xpath.string('string(/entry/activity:object-type[1])', doc) - - case object_type do - 'http://activitystrea.ms/schema/1.0/note' -> - handle_note(doc) - _ -> - Logger.error("Couldn't parse incoming document") - end + entries = :xmerl_xpath.string('//entry', doc) + + activities = Enum.map(entries, fn (entry) -> + {:xmlObj, :string, object_type } = :xmerl_xpath.string('string(/entry/activity:object-type[1])', entry) + + case object_type do + 'http://activitystrea.ms/schema/1.0/note' -> + with {:ok, activity} <- handle_note(entry, doc), do: activity + 'http://activitystrea.ms/schema/1.0/comment' -> + with {:ok, activity} <- handle_note(entry, doc), do: activity + _ -> + Logger.error("Couldn't parse incoming document") + nil + end + end) + {:ok, activities} end - # TODO - # wire up replies - def handle_note(doc) do - content_html = string_from_xpath("/entry/content[1]", doc) + def handle_note(entry, doc \\ nil) do + content_html = string_from_xpath("/entry/content[1]", entry) - uri = string_from_xpath("/entry/author/uri[1]", doc) - {:ok, actor} = find_or_make_user(uri) + [author] = :xmerl_xpath.string('//author[1]', doc) + {:ok, actor} = find_make_or_update_user(author) + inReplyTo = string_from_xpath("/entry/thr:in-reply-to[1]/@ref", entry) - context = string_from_xpath("/entry/ostatus:conversation[1]", doc) |> String.trim - context = if String.length(context) > 0 do - context - else - ActivityPub.generate_context_id - end + context = (string_from_xpath("/entry/ostatus:conversation[1]", entry) || "") |> String.trim + + context = with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(inReplyTo) do + context + else _e -> + if String.length(context) > 0 do + context + else + ActivityPub.generate_context_id + end + end to = [ "https://www.w3.org/ns/activitystreams#Public" ] - mentions = :xmerl_xpath.string('/entry/link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', doc) + mentions = :xmerl_xpath.string('/entry/link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry) |> Enum.map(fn(person) -> string_from_xpath("@href", person) end) to = to ++ mentions - date = string_from_xpath("/entry/published", doc) + date = string_from_xpath("/entry/published", entry) + id = string_from_xpath("/entry/id", entry) object = %{ + "id" => id, "type" => "Note", "to" => to, "content" => content_html, @@ -67,15 +80,31 @@ defmodule Pleroma.Web.OStatus do "actor" => actor.ap_id } - inReplyTo = string_from_xpath("/entry/thr:in-reply-to[1]/@href", doc) - object = if inReplyTo do Map.put(object, "inReplyTo", inReplyTo) else object end - ActivityPub.create(to, actor, context, object, %{}, date) + # TODO: Bail out sooner and use transaction. + if Object.get_by_ap_id(id) do + {:error, "duplicate activity"} + else + ActivityPub.create(to, actor, context, object, %{}, date, false) + end + end + + def find_make_or_update_user(doc) do + uri = string_from_xpath("//author/uri[1]", doc) + with {:ok, user} <- find_or_make_user(uri) do + avatar = make_avatar_object(doc) + if user.avatar != avatar do + change = Ecto.Changeset.change(user, %{avatar: avatar}) + Repo.update(change) + else + {:ok, user} + end + end end def find_or_make_user(uri) do @@ -98,7 +127,8 @@ defmodule Pleroma.Web.OStatus do name: info.name, nickname: info.nickname <> "@" <> info.host, ap_id: info.uri, - info: info + info: info, + avatar: info.avatar } # TODO: Make remote user changeset # SHould enforce fqn nickname @@ -107,9 +137,9 @@ defmodule Pleroma.Web.OStatus do end # TODO: Just takes the first one for now. - defp make_avatar_object(author_doc) do - href = string_from_xpath("/author[1]/link[@rel=\"avatar\"]/@href", author_doc) - type = string_from_xpath("/author[1]/link[@rel=\"avatar\"]/@type", author_doc) + def make_avatar_object(author_doc) do + href = string_from_xpath("//author[1]/link[@rel=\"avatar\"]/@href", author_doc) + type = string_from_xpath("//author[1]/link[@rel=\"avatar\"]/@type", author_doc) if href do %{