"https://www.w3.org/ns/activitystreams#Public"
]
- to = default_to ++ Enum.map(mentions, fn ({_, %{ap_id: ap_id}}) -> ap_id end)
+ default_to ++ Enum.map(mentions, fn ({_, %{ap_id: ap_id}}) -> ap_id end)
end
def format_input(text, mentions) do
- content = HtmlSanitizeEx.strip_tags(text)
+ HtmlSanitizeEx.strip_tags(text)
|> String.replace("\n", "<br>")
|> add_user_links(mentions)
end
def get_replied_to_activity(_), do: nil
+ def add_attachments(text, attachments) do
+ attachment_text = Enum.map(attachments, fn
+ (%{"url" => [%{"href" => href} | _]}) ->
+ "<a href='#{href}'>#{href}</a>"
+ _ -> ""
+ end)
+ Enum.join([text | attachment_text], "<br>")
+ end
+
def create_status(user = %User{}, data = %{"status" => status}) do
attachments = attachments_from_ids(data["media_ids"])
context = ActivityPub.generate_context_id
mentions = parse_mentions(status)
- content_html = format_input(status, mentions)
+ content_html = status
+ |> format_input(mentions)
+ |> add_attachments(attachments)
+
to = to_for_user_and_mentions(user, mentions)
date = make_date()
"actor" => user.ap_id,
"inReplyTo" => inReplyTo.data["object"]["id"],
"inReplyToStatusId" => inReplyTo.id,
- "statusnetConversationId" => inReplyTo.data["statusnetConversationId"]
- }
- additional = %{
- "statusnetConversationId" => inReplyTo.data["statusnetConversationId"]
}
+ additional = %{}
[to, context, object, additional]
else
end
def fetch_public_statuses(user, opts \\ %{}) do
+ opts = Map.put(opts, "local_only", true)
+ ActivityPub.fetch_public_activities(opts)
+ |> activities_to_statuses(%{for: user})
+ end
+
+ def fetch_public_and_external_statuses(user, opts \\ %{}) do
ActivityPub.fetch_public_activities(opts)
|> activities_to_statuses(%{for: user})
end
end
def fetch_conversation(user, id) do
- query = from activity in Activity,
- where: fragment("? @> ?", activity.data, ^%{ statusnetConversationId: id}),
- limit: 1
-
- with %Activity{} = activity <- Repo.one(query),
- context <- activity.data["context"],
+ with context when is_binary(context) <- conversation_id_to_context(id),
activities <- ActivityPub.fetch_activities_for_context(context),
statuses <- activities |> activities_to_statuses(%{for: user})
do
end
end
- def follow(%User{} = follower, followed_id) do
- with %User{} = followed <- Repo.get(User, followed_id),
- { :ok, follower } <- User.follow(follower, followed),
+ def follow(%User{} = follower, params) do
+ with { :ok, %User{} = followed } <- get_user(params),
+ { :ok, follower } <- User.follow(follower, followed),
{ :ok, activity } <- ActivityPub.insert(%{
"type" => "Follow",
"actor" => follower.ap_id,
end
end
- def unfollow(%User{} = follower, followed_id) do
- with %User{} = followed <- Repo.get(User, followed_id),
- { :ok, follower } <- User.unfollow(follower, followed)
+ def unfollow(%User{} = follower, params) do
+ with { :ok, %User{} = unfollowed } <- get_user(params),
+ { :ok, follower } <- User.unfollow(follower, unfollowed)
do
- { :ok, follower, followed }
+ { :ok, follower, unfollowed}
else
err -> err
end
Enum.reduce(mentions, text, fn ({match, %User{ap_id: ap_id}}, text) -> String.replace(text, match, "<a href='#{ap_id}'>#{match}</a>") end)
end
- defp add_conversation_id(activity) do
- if is_integer(activity.data["statusnetConversationId"]) do
- {:ok, activity}
- else
- data = activity.data
- |> put_in(["object", "statusnetConversationId"], activity.id)
- |> put_in(["statusnetConversationId"], activity.id)
-
- object = Object.get_by_ap_id(activity.data["object"]["id"])
-
- changeset = Ecto.Changeset.change(object, data: data["object"])
- Repo.update(changeset)
-
- changeset = Ecto.Changeset.change(activity, data: data)
- Repo.update(changeset)
- end
- end
-
def register_user(params) do
params = %{
nickname: params["nickname"],
{:error, changeset} ->
errors = Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
|> Poison.encode!
- {:error, %{error: errors}}
+ {:error, %{error: errors}}
end
end
- def get_user(user, params) do
+ def get_user(user \\ nil, params) do
case params do
%{ "user_id" => user_id } ->
case target = Repo.get(User, user_id) do
defp make_date do
DateTime.utc_now() |> DateTime.to_iso8601
end
+
+ def context_to_conversation_id(context) do
+ with %Object{id: id} <- Object.get_cached_by_ap_id(context) do
+ id
+ else _e ->
+ changeset = Object.context_mapping(context)
+ {:ok, %{id: id}} = Repo.insert(changeset)
+ id
+ end
+ end
+
+ def conversation_id_to_context(id) do
+ with %Object{data: %{"id" => context}} <- Repo.get(Object, id) do
+ context
+ else _e ->
+ {:error, "No such conversation"}
+ end
+ end
end