commit: 50409326a853db7bd9f538f0ddbec805c134920f
parent: ac2893a945a753ad05d46234ba80e14f3ce62c97
Author: Roger Braun <rbraun@Bobble.local>
Date: Fri, 15 Sep 2017 14:17:36 +0200
Refactor posting and make character limit configurable.
Diffstat:
14 files changed, 187 insertions(+), 178 deletions(-)
diff --git a/config/config.exs b/config/config.exs
@@ -43,7 +43,8 @@ version = with {version, 0} <- System.cmd("git", ["rev-parse", "HEAD"]) do
config :pleroma, :instance,
version: version,
name: "Pleroma",
- email: "example@example.com"
+ email: "example@example.com",
+ limit: 5000
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
@@ -1,6 +1,9 @@
defmodule Pleroma.Web.CommonAPI do
- alias Pleroma.{Repo, Activity, Object}
+ alias Pleroma.{Repo, Activity, Object, User}
alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Formatter
+
+ import Pleroma.Web.CommonAPI.Utils
def delete(activity_id, user) do
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
@@ -44,13 +47,22 @@ defmodule Pleroma.Web.CommonAPI do
end
end
- # This is a hack for twidere.
- def get_by_id_or_ap_id(id) do
- activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id)
- if activity.data["type"] == "Create" do
- activity
- else
- Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+ @instance Application.get_env(:pleroma, :instance)
+ @limit Keyword.get(@instance, :limit)
+ def post(user, %{"status" => status} = data) do
+ with status <- String.trim(status),
+ length when length in 1..@limit <- String.length(status),
+ attachments <- attachments_from_ids(data["media_ids"]),
+ mentions <- Formatter.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),
+ tags <- Formatter.parse_tags(status),
+ object <- make_note_data(user.ap_id, to, context, content_html, attachments, inReplyTo, tags) do
+ res = ActivityPub.create(to, user, context, object)
+ User.update_note_count(user)
+ res
end
end
end
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
@@ -0,0 +1,129 @@
+defmodule Pleroma.Web.CommonAPI.Utils do
+ alias Pleroma.{Repo, Object, Formatter, User, Activity}
+ alias Pleroma.Web.ActivityPub.Utils
+ alias Calendar.Strftime
+
+ # This is a hack for twidere.
+ def get_by_id_or_ap_id(id) do
+ activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id)
+ if activity.data["type"] == "Create" do
+ activity
+ else
+ Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+ end
+ end
+
+ def get_replied_to_activity(id) when not is_nil(id) do
+ Repo.get(Activity, id)
+ end
+ def get_replied_to_activity(_), do: nil
+
+ def attachments_from_ids(ids) do
+ Enum.map(ids || [], fn (media_id) ->
+ Repo.get(Object, media_id).data
+ end)
+ end
+
+ def to_for_user_and_mentions(user, mentions, inReplyTo) do
+ default_to = [
+ user.follower_address,
+ "https://www.w3.org/ns/activitystreams#Public"
+ ]
+
+ 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 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 add_attachments(text, attachments) do
+ attachment_text = Enum.map(attachments, fn
+ (%{"url" => [%{"href" => href} | _]}) ->
+ name = URI.decode(Path.basename(href))
+ "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
+ _ -> ""
+ end)
+ Enum.join([text | attachment_text], "<br>\n")
+ end
+
+ def format_input(text, mentions) do
+ HtmlSanitizeEx.strip_tags(text)
+ |> Formatter.linkify
+ |> String.replace("\n", "<br>\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) ->
+ short_match = String.split(match, "@") |> tl() |> hd()
+ String.replace(text, uuid, "<a href='#{ap_id}'>@#{short_match}</a>")
+ end)
+ end
+
+ def make_note_data(actor, to, context, content_html, attachments, inReplyTo, tags) do
+ object = %{
+ "type" => "Note",
+ "to" => to,
+ "content" => content_html,
+ "context" => context,
+ "attachment" => attachments,
+ "actor" => actor,
+ "tag" => tags |> Enum.map(fn ({_, tag}) -> tag end)
+ }
+
+ if inReplyTo do
+ object
+ |> Map.put("inReplyTo", inReplyTo.data["object"]["id"])
+ |> Map.put("inReplyToStatusId", inReplyTo.id)
+ else
+ object
+ end
+ end
+
+ def format_naive_asctime(date) do
+ date |> DateTime.from_naive!("Etc/UTC") |> format_asctime
+ end
+
+ def format_asctime(date) do
+ Strftime.strftime!(date, "%a %b %d %H:%M:%S %z %Y")
+ end
+
+ def date_to_asctime(date) do
+ with {:ok, date, _offset} <- date |> DateTime.from_iso8601 do
+ format_asctime(date)
+ else _e ->
+ ""
+ end
+ end
+
+ defp shortname(name) do
+ if String.length(name) < 30 do
+ name
+ else
+ String.slice(name, 0..30) <> "…"
+ end
+ end
+end
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -133,15 +133,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def post_status(%{assigns: %{user: user}} = conn, %{"status" => status} = params) do
- l = status |> String.trim |> String.length
-
params = params
|> Map.put("in_reply_to_status_id", params["in_reply_to_id"])
- if l > 0 && l < 5000 do
- {:ok, activity} = TwitterAPI.create_status(user, params)
- render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
- end
+ {:ok, activity} = CommonAPI.post(user, params)
+ render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
end
def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex
@@ -4,7 +4,7 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
alias Pleroma.{Object, User, Activity}
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
- alias Pleroma.Web.TwitterAPI
+ alias Pleroma.Web.CommonAPI
@doc """
Get the context for this note. Uses this:
@@ -92,7 +92,7 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
mentions <- get_mentions(entry),
to <- make_to_list(actor, mentions),
date <- XML.string_from_xpath("//published", entry),
- note <- TwitterAPI.Utils.make_note_data(actor.ap_id, to, context, content_html, attachments, inReplyToActivity, []),
+ note <- CommonAPI.Utils.make_note_data(actor.ap_id, to, context, content_html, attachments, inReplyToActivity, []),
note <- note |> Map.put("id", id) |> Map.put("tag", tags),
note <- note |> Map.put("published", date),
note <- add_external_url(note, entry),
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -6,15 +6,16 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
json(conn, "ok")
end
+ @instance Application.get_env(:pleroma, :instance)
def config(conn, _params) do
case get_format(conn) do
"xml" ->
response = """
<config>
<site>
- <name>#{Web.base_url}</name>
+ <name>#{Keyword.get(@instance, :name)}</name>
<site>#{Web.base_url}</site>
- <textlimit>5000</textlimit>
+ <textlimit>#{Keyword.get(@instance, :limit)}</textlimit>
</site>
</config>
"""
@@ -24,22 +25,23 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
_ ->
json(conn, %{
site: %{
- name: Web.base_url,
+ name: Keyword.get(@instance, :name),
server: Web.base_url,
- textlimit: 5000
+ textlimit: Keyword.get(@instance, :limit)
}
})
end
end
def version(conn, _params) do
+ version = Keyword.get(@instance, :version)
case get_format(conn) do
"xml" ->
- response = "<version>Pleroma Dev</version>"
+ response = "<version>#{version}</version>"
conn
|> put_resp_content_type("application/xml")
|> send_resp(200, response)
- _ -> json(conn, "Pleroma Dev")
+ _ -> json(conn, version)
end
end
end
diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
@@ -2,7 +2,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
alias Pleroma.{Activity, User}
- alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, Utils}
+ alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView}
+ alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Formatter
defp user_by_ap_id(user_list, ap_id) do
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -6,43 +6,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
alias Pleroma.Web.{OStatus, CommonAPI}
alias Pleroma.Formatter
- import Pleroma.Web.TwitterAPI.Utils
-
@httpoison Application.get_env(:pleroma, :httpoison)
- def to_for_user_and_mentions(user, mentions, inReplyTo) do
- default_to = [
- user.follower_address,
- "https://www.w3.org/ns/activitystreams#Public"
- ]
-
- 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
- Repo.get(Activity, id)
- end
-
- def get_replied_to_activity(_), do: nil
-
def create_status(%User{} = user, %{"status" => status} = data) do
- with attachments <- attachments_from_ids(data["media_ids"]),
- mentions <- Formatter.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),
- tags <- Formatter.parse_tags(status),
- object <- make_note_data(user.ap_id, to, context, content_html, attachments, inReplyTo, tags) do
- res = ActivityPub.create(to, user, context, object)
- User.update_note_count(user)
- res
- end
+ CommonAPI.post(user, data)
end
def fetch_friend_statuses(user, opts \\ %{}) do
diff --git a/lib/pleroma/web/twitter_api/utils.ex b/lib/pleroma/web/twitter_api/utils.ex
@@ -1,101 +0,0 @@
-defmodule Pleroma.Web.TwitterAPI.Utils do
- alias Pleroma.{Repo, Object, Formatter, User, Activity}
- alias Pleroma.Web.ActivityPub.Utils
- alias Calendar.Strftime
-
- def attachments_from_ids(ids) do
- Enum.map(ids || [], fn (media_id) ->
- Repo.get(Object, media_id).data
- end)
- end
-
- defp shortname(name) do
- if String.length(name) < 30 do
- name
- else
- String.slice(name, 0..30) <> "…"
- end
- end
-
- def add_attachments(text, attachments) do
- attachment_text = Enum.map(attachments, fn
- (%{"url" => [%{"href" => href} | _]}) ->
- name = URI.decode(Path.basename(href))
- "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
- _ -> ""
- end)
- Enum.join([text | attachment_text], "<br>\n")
- end
-
- def format_input(text, mentions) do
- HtmlSanitizeEx.strip_tags(text)
- |> Formatter.linkify
- |> String.replace("\n", "<br>\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) ->
- short_match = String.split(match, "@") |> tl() |> hd()
- String.replace(text, uuid, "<a href='#{ap_id}'>@#{short_match}</a>")
- 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
-
- # TODO: Move this to a more fitting space
- def make_note_data(actor, to, context, content_html, attachments, inReplyTo, tags) do
- object = %{
- "type" => "Note",
- "to" => to,
- "content" => content_html,
- "context" => context,
- "attachment" => attachments,
- "actor" => actor,
- "tag" => tags |> Enum.map(fn ({_, tag}) -> tag end)
- }
-
- if inReplyTo do
- object
- |> Map.put("inReplyTo", inReplyTo.data["object"]["id"])
- |> Map.put("inReplyToStatusId", inReplyTo.id)
- else
- object
- end
- end
-
- def format_naive_asctime(date) do
- date |> DateTime.from_naive!("Etc/UTC") |> format_asctime
- end
-
- def format_asctime(date) do
- Strftime.strftime!(date, "%a %b %d %H:%M:%S %z %Y")
- end
-
- def date_to_asctime(date) do
- with {:ok, date, _offset} <- date |> DateTime.from_iso8601 do
- format_asctime(date)
- else _e ->
- ""
- end
- end
-end
diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex
@@ -1,7 +1,7 @@
defmodule Pleroma.Web.TwitterAPI.UserView do
use Pleroma.Web, :view
alias Pleroma.User
- alias Pleroma.Web.TwitterAPI.Utils
+ alias Pleroma.Web.CommonAPI.Utils
def render("show.json", %{user: user = %User{}} = assigns) do
render_one(user, Pleroma.Web.TwitterAPI.UserView, "user.json", assigns)
diff --git a/test/web/common_api/common_api_utils_test.exs b/test/web/common_api/common_api_utils_test.exs
@@ -0,0 +1,16 @@
+defmodule Pleroma.Web.CommonAPI.UtilsTest do
+ alias Pleroma.Web.CommonAPI.Utils
+ use Pleroma.DataCase
+
+ test "it adds attachment links to a given text and attachment set" do
+ name = "Sakura%20Mana%20%E2%80%93%20Turned%20on%20by%20a%20Senior%20OL%20with%20a%20Temptating%20Tight%20Skirt-s%20Full%20Hipline%20and%20Panty%20Shot-%20Beautiful%20Thick%20Thighs-%20and%20Erotic%20Ass-%20-2015-%20--%20Oppaitime%208-28-2017%206-50-33%20PM.png"
+
+ attachment = %{
+ "url" => [%{"href" => name}]
+ }
+
+ res = Utils.add_attachments("", [attachment])
+
+ assert res == "<br>\n<a href=\"#{name}\" class='attachment'>Sakura Mana – Turned on by a Se…</a>"
+ end
+end
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
@@ -1,7 +1,8 @@
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
alias Pleroma.Builders.{UserBuilder, ActivityBuilder}
- alias Pleroma.Web.TwitterAPI.{TwitterAPI,UserView,Utils}
+ alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView}
+ alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.{Activity, User, Object, Repo}
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
alias Pleroma.Web.ActivityPub.ActivityPub
diff --git a/test/web/twitter_api/twitter_api_utils_test.exs b/test/web/twitter_api/twitter_api_utils_test.exs
@@ -1,16 +0,0 @@
-defmodule Pleroma.Web.TwitterAPI.UtilsTest do
- alias Pleroma.Web.TwitterAPI.Utils
- use Pleroma.DataCase
-
- test "it adds attachment links to a given text and attachment set" do
- name = "Sakura%20Mana%20%E2%80%93%20Turned%20on%20by%20a%20Senior%20OL%20with%20a%20Temptating%20Tight%20Skirt-s%20Full%20Hipline%20and%20Panty%20Shot-%20Beautiful%20Thick%20Thighs-%20and%20Erotic%20Ass-%20-2015-%20--%20Oppaitime%208-28-2017%206-50-33%20PM.png"
-
- attachment = %{
- "url" => [%{"href" => name}]
- }
-
- res = Utils.add_attachments("", [attachment])
-
- assert res == "<br>\n<a href=\"#{name}\" class='attachment'>Sakura Mana – Turned on by a Se…</a>"
- end
-end
diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs
@@ -2,7 +2,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
use Pleroma.DataCase
alias Pleroma.User
- alias Pleroma.Web.TwitterAPI.{UserView, Utils}
+ alias Pleroma.Web.TwitterAPI.UserView
+ alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Builders.UserBuilder
import Pleroma.Factory