diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 0b1bc473a..202d648e1 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -4,28 +4,23 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.TwitterAPI.Representers.{ActivityRepresenter, UserRepresenter}
alias Pleroma.Web.OStatus
+ alias Pleroma.Formatter
import Ecto.Query
+ import Pleroma.Web.TwitterAPI.Utils
- def to_for_user_and_mentions(user, mentions) do
+ def to_for_user_and_mentions(user, mentions, inReplyTo) do
default_to = [
User.ap_followers(user),
"https://www.w3.org/ns/activitystreams#Public"
]
- default_to ++ Enum.map(mentions, fn ({_, %{ap_id: ap_id}}) -> ap_id end)
- end
-
- def format_input(text, mentions) do
- HtmlSanitizeEx.strip_tags(text)
- |> String.replace("\n", "
")
- |> add_user_links(mentions)
- end
-
- def attachments_from_ids(ids) do
- Enum.map(ids || [], fn (media_id) ->
- Repo.get(Object, media_id).data
- end)
+ to = default_to ++ Enum.map(mentions, fn ({_, %{ap_id: ap_id}}) -> ap_id end)
+ if inReplyTo do
+ Enum.uniq([inReplyTo.data["actor"] | to])
+ else
+ to
+ end
end
def get_replied_to_activity(id) when not is_nil(id) do
@@ -34,62 +29,16 @@ def get_replied_to_activity(id) when not is_nil(id) do
def get_replied_to_activity(_), do: nil
- def add_attachments(text, attachments) do
- attachment_text = Enum.map(attachments, fn
- (%{"url" => [%{"href" => href} | _]}) ->
- "#{href}"
- _ -> ""
- end)
- Enum.join([text | attachment_text], "
")
- end
-
def create_status(%User{} = user, %{"status" => status} = data) do
- attachments = attachments_from_ids(data["media_ids"])
- context = Utils.generate_context_id
- mentions = parse_mentions(status)
- content_html = status
- |> format_input(mentions)
- |> add_attachments(attachments)
-
- to = to_for_user_and_mentions(user, mentions)
- date = make_date()
-
- inReplyTo = get_replied_to_activity(data["in_reply_to_status_id"])
-
- # Wire up reply info.
- [to, context, object, additional] =
- if inReplyTo do
- context = inReplyTo.data["context"]
- to = to ++ [inReplyTo.data["actor"]]
-
- object = %{
- "type" => "Note",
- "to" => to,
- "content" => content_html,
- "published" => date,
- "context" => context,
- "attachment" => attachments,
- "actor" => user.ap_id,
- "inReplyTo" => inReplyTo.data["object"]["id"],
- "inReplyToStatusId" => inReplyTo.id,
- }
- additional = %{}
-
- [to, context, object, additional]
- else
- object = %{
- "type" => "Note",
- "to" => to,
- "content" => content_html,
- "published" => date,
- "context" => context,
- "attachment" => attachments,
- "actor" => user.ap_id
- }
- [to, context, object, %{}]
+ with attachments <- attachments_from_ids(data["media_ids"]),
+ mentions <- parse_mentions(status),
+ inReplyTo <- get_replied_to_activity(data["in_reply_to_status_id"]),
+ to <- to_for_user_and_mentions(user, mentions, inReplyTo),
+ content_html <- make_content_html(status, mentions, attachments),
+ context <- make_context(inReplyTo),
+ object <- make_note_data(user.ap_id, to, context, content_html, attachments, inReplyTo) do
+ ActivityPub.create(to, user, context, object)
end
-
- ActivityPub.create(to, user, context, object, additional, data)
end
def fetch_friend_statuses(user, opts \\ %{}) do
@@ -243,24 +192,6 @@ def parse_mentions(text) do
|> Enum.filter(fn ({_match, user}) -> user end)
end
- def add_user_links(text, mentions) do
- mentions = mentions
- |> Enum.sort_by(fn ({name, _}) -> -String.length(name) end)
- |> Enum.map(fn({name, user}) -> {name, user, Ecto.UUID.generate} end)
-
- # This replaces the mention with a unique reference first so it doesn't
- # contain parts of other replaced mentions. There probably is a better
- # solution for this...
- step_one = mentions
- |> Enum.reduce(text, fn ({match, _user, uuid}, text) ->
- String.replace(text, match, uuid)
- end)
-
- Enum.reduce(mentions, step_one, fn ({match, %User{ap_id: ap_id}, uuid}, text) ->
- String.replace(text, uuid, "#{match}")
- end)
- end
-
def register_user(params) do
params = %{
nickname: params["nickname"],
diff --git a/lib/pleroma/web/twitter_api/utils.ex b/lib/pleroma/web/twitter_api/utils.ex
new file mode 100644
index 000000000..6f5c9f727
--- /dev/null
+++ b/lib/pleroma/web/twitter_api/utils.ex
@@ -0,0 +1,72 @@
+defmodule Pleroma.Web.TwitterAPI.Utils do
+ alias Pleroma.{Repo, Object, Formatter, User, Activity}
+ alias Pleroma.Web.ActivityPub.Utils
+
+ def attachments_from_ids(ids) do
+ Enum.map(ids || [], fn (media_id) ->
+ Repo.get(Object, media_id).data
+ end)
+ end
+
+ def add_attachments(text, attachments) do
+ attachment_text = Enum.map(attachments, fn
+ (%{"url" => [%{"href" => href} | _]}) ->
+ "#{href}"
+ _ -> ""
+ end)
+ Enum.join([text | attachment_text], "
")
+ end
+
+ def format_input(text, mentions) do
+ HtmlSanitizeEx.strip_tags(text)
+ |> Formatter.linkify
+ |> String.replace("\n", "
")
+ |> add_user_links(mentions)
+ end
+
+ def add_user_links(text, mentions) do
+ mentions = mentions
+ |> Enum.sort_by(fn ({name, _}) -> -String.length(name) end)
+ |> Enum.map(fn({name, user}) -> {name, user, Ecto.UUID.generate} end)
+
+ # This replaces the mention with a unique reference first so it doesn't
+ # contain parts of other replaced mentions. There probably is a better
+ # solution for this...
+ step_one = mentions
+ |> Enum.reduce(text, fn ({match, _user, uuid}, text) ->
+ String.replace(text, match, uuid)
+ end)
+
+ Enum.reduce(mentions, step_one, fn ({match, %User{ap_id: ap_id}, uuid}, text) ->
+ String.replace(text, uuid, "#{match}")
+ end)
+ end
+
+ def make_content_html(status, mentions, attachments) do
+ status
+ |> format_input(mentions)
+ |> add_attachments(attachments)
+ end
+
+ def make_context(%Activity{data: %{"context" => context}}), do: context
+ def make_context(_), do: Utils.generate_context_id
+
+ def make_note_data(actor, to, context, content_html, attachments, inReplyTo) do
+ object = %{
+ "type" => "Note",
+ "to" => to,
+ "content" => content_html,
+ "context" => context,
+ "attachment" => attachments,
+ "actor" => actor
+ }
+
+ if inReplyTo do
+ object
+ |> Map.put("inReplyTo", inReplyTo.data["object"]["id"])
+ |> Map.put("inReplyToStatusId", inReplyTo.id)
+ else
+ object
+ end
+ end
+end
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index d70ef88f3..e20960228 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -2,6 +2,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
alias Pleroma.Builders.{UserBuilder, ActivityBuilder}
alias Pleroma.Web.TwitterAPI.TwitterAPI
+ alias Pleroma.Web.TwitterAPI.Utils
alias Pleroma.{Activity, User, Object, Repo}
alias Pleroma.Web.TwitterAPI.Representers.{ActivityRepresenter, UserRepresenter}
alias Pleroma.Web.ActivityPub.ActivityPub
@@ -261,7 +262,7 @@ test "it adds user links to an existing text" do
mentions = TwitterAPI.parse_mentions(text)
expected_text = "@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me"
- assert TwitterAPI.add_user_links(text, mentions) == expected_text
+ assert Utils.add_user_links(text, mentions) == expected_text
end
test "it favorites a status, returns the updated status" do