From: rinpatch Date: Sun, 13 Jan 2019 10:38:28 +0000 (+0300) Subject: Resolve merge conflict X-Git-Url: http://git.squeep.com/?a=commitdiff_plain;h=e4dc3f71aea900e566c0d66ddffc5cd57e3920dd;hp=19b6a8239387869c69c6885044ee488d097b723f;p=akkoma Resolve merge conflict --- diff --git a/config/config.exs b/config/config.exs index 1c55807b7..895dbb3ab 100644 --- a/config/config.exs +++ b/config/config.exs @@ -207,6 +207,8 @@ config :pleroma, :gopher, ip: {0, 0, 0, 0}, port: 9999 +config :pleroma, :metadata, opengraph: true + config :pleroma, :suggestions, enabled: false, third_party_engine: diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index d80ae6576..49f7075e6 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -183,4 +183,22 @@ defmodule Pleroma.Formatter do String.replace(result_text, uuid, replacement) end) end + + def truncate(text, opts \\ []) do + max_length = opts[:max_length] || 200 + omission = opts[:omission] || "..." + + cond do + not String.valid?(text) -> + text + + String.length(text) < max_length -> + text + + true -> + length_with_omission = max_length - String.length(omission) + + "#{String.slice(text, 0, length_with_omission)}#{omission}" + end + end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 681280539..3120b13b6 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -404,6 +404,10 @@ defmodule Pleroma.User do user.info.locked || false end + def get_by_id(id) do + Repo.get_by(User, id: id) + end + def get_by_ap_id(ap_id) do Repo.get_by(User, ap_id: ap_id) end @@ -439,11 +443,20 @@ defmodule Pleroma.User do Cachex.fetch!(:user_cache, key, fn _ -> get_by_ap_id(ap_id) end) end + def get_cached_by_id(id) do + key = "id:#{id}" + Cachex.fetch!(:user_cache, key, fn _ -> get_by_id(id) end) + end + def get_cached_by_nickname(nickname) do key = "nickname:#{nickname}" Cachex.fetch!(:user_cache, key, fn _ -> get_or_fetch_by_nickname(nickname) end) end + def get_cached_by_nickname_or_id(nickname_or_id) do + get_cached_by_nickname(nickname_or_id) || get_cached_by_id(nickname_or_id) + end + def get_by_nickname(nickname) do Repo.get_by(User, nickname: nickname) || if Regex.match?(~r(@#{Pleroma.Web.Endpoint.host()})i, nickname) do diff --git a/lib/pleroma/web/ostatus/metadata.ex b/lib/pleroma/web/ostatus/metadata.ex new file mode 100644 index 000000000..9935726fc --- /dev/null +++ b/lib/pleroma/web/ostatus/metadata.ex @@ -0,0 +1,82 @@ +defmodule Pleroma.Web.Metadata do + alias Phoenix.HTML + alias Pleroma.{Formatter, User} + alias Pleroma.Web.MediaProxy + + def build_tags(params) do + if(meta_enabled?(:opengraph), do: opengraph_tags(params), else: []) + |> Enum.map(&to_tag/1) + |> Enum.map(&HTML.safe_to_string/1) + |> Enum.join("\n") + end + + def meta_enabled?(type) do + Pleroma.Config.get([:metadata, type], false) + end + + # opengraph for single status + defp opengraph_tags(%{activity: activity, user: user}) do + with truncated_content = scrub_html_and_truncate(activity.data["object"]["content"]) do + [ + {:meta, + [ + property: "og:title", + content: "#{user.name} (@#{user.nickname}@#{pleroma_domain()}) post ##{activity.id}" + ], []}, + {:meta, [property: "og:url", content: activity.data["id"]], []}, + {:meta, [property: "og:description", content: truncated_content], []}, + {:meta, [property: "og:image", content: user_avatar_url(user)], []}, + {:meta, [property: "og:image:width", content: 120], []}, + {:meta, [property: "og:image:height", content: 120], []}, + {:meta, [property: "twitter:card", content: "summary"], []} + ] + end + end + + # opengraph for user card + defp opengraph_tags(%{user: user}) do + with truncated_bio = scrub_html_and_truncate(user.bio) do + [ + {:meta, + [ + property: "og:title", + content: "#{user.name} (@#{user.nickname}@#{pleroma_domain()}) profile" + ], []}, + {:meta, [property: "og:url", content: User.profile_url(user)], []}, + {:meta, [property: "og:description", content: truncated_bio], []}, + {:meta, [property: "og:image", content: user_avatar_url(user)], []}, + {:meta, [property: "og:image:width", content: 120], []}, + {:meta, [property: "og:image:height", content: 120], []}, + {:meta, [property: "twitter:card", content: "summary"], []} + ] + end + end + + def to_tag(data) do + with {name, attrs, _content = []} <- data do + HTML.Tag.tag(name, attrs) + else + {name, attrs, content} -> + HTML.Tag.content_tag(name, content, attrs) + + _ -> + raise ArgumentError, message: "make_tag invalid args" + end + end + + defp scrub_html_and_truncate(content) do + content + # html content comes from DB already encoded, decode first and scrub after + |> HtmlEntities.decode() + |> Pleroma.HTML.strip_tags() + |> Formatter.truncate() + end + + defp user_avatar_url(user) do + User.avatar_url(user) |> MediaProxy.url() + end + + def pleroma_domain do + Pleroma.Web.Endpoint.host() + end +end diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index 332cbef0e..be648a6ee 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -20,7 +20,11 @@ defmodule Pleroma.Web.OStatus.OStatusController do def feed_redirect(conn, %{"nickname" => nickname}) do case get_format(conn) do "html" -> - Fallback.RedirectController.redirector(conn, nil) + with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do + Fallback.RedirectController.redirector_with_meta(conn, %{user: user}) + else + nil -> {:error, :not_found} + end "activity+json" -> ActivityPubController.call(conn, :user) @@ -142,9 +146,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do case format = get_format(conn) do "html" -> - conn - |> put_resp_content_type("text/html") - |> send_file(200, Pleroma.Plugs.InstanceStatic.file_path("index.html")) + Fallback.RedirectController.redirector_with_meta(conn, %{activity: activity, user: user}) _ -> represent_activity(conn, format, activity, user) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index a5f4d8126..5ef99bec5 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -391,7 +391,11 @@ defmodule Pleroma.Web.Router do end pipeline :ostatus do - plug(:accepts, ["xml", "atom", "html", "activity+json"]) + plug(:accepts, ["html", "xml", "atom", "activity+json"]) + end + + pipeline :oembed do + plug(:accepts, ["json", "xml"]) end scope "/", Pleroma.Web do @@ -409,6 +413,12 @@ defmodule Pleroma.Web.Router do post("/push/subscriptions/:id", Websub.WebsubController, :websub_incoming) end + scope "/", Pleroma.Web do + pipe_through(:oembed) + + get("/oembed", OEmbed.OEmbedController, :url) + end + pipeline :activitypub do plug(:accepts, ["activity+json"]) plug(Pleroma.Web.Plugs.HTTPSignaturePlug) @@ -503,11 +513,26 @@ end defmodule Fallback.RedirectController do use Pleroma.Web, :controller + alias Pleroma.Web.Metadata def redirector(conn, _params) do conn |> put_resp_content_type("text/html") - |> send_file(200, Pleroma.Plugs.InstanceStatic.file_path("index.html")) + |> send_file(200, index_file_path()) + end + + def redirector_with_meta(conn, params) do + {:ok, index_content} = File.read(index_file_path()) + tags = Metadata.build_tags(params) + response = String.replace(index_content, "", tags) + + conn + |> put_resp_content_type("text/html") + |> send_resp(200, response) + end + + def index_file_path do + Pleroma.Plugs.InstanceStatic.file_path("index.html") end def registration_page(conn, params) do diff --git a/mix.exs b/mix.exs index ccf7790b0..d46998891 100644 --- a/mix.exs +++ b/mix.exs @@ -59,6 +59,7 @@ defmodule Pleroma.Mixfile do {:pbkdf2_elixir, "~> 0.12.3"}, {:trailing_format_plug, "~> 0.0.7"}, {:html_sanitize_ex, "~> 1.3.0"}, + {:html_entities, "~> 0.4"}, {:phoenix_html, "~> 2.10"}, {:calendar, "~> 0.17.4"}, {:cachex, "~> 3.0.2"}, diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 995cc00d6..8e9d2b69a 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -88,6 +88,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do conn = conn + |> put_req_header("accept", "application/xml") |> get(url) expected = @@ -114,6 +115,16 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> response(404) end + test "gets an activity in xml format", %{conn: conn} do + note_activity = insert(:note_activity) + [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) + + conn + |> put_req_header("accept", "application/xml") + |> get("/activities/#{uuid}") + |> response(200) + end + test "404s on deleted objects", %{conn: conn} do note_activity = insert(:note_activity) [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["object"]["id"])) @@ -130,15 +141,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> response(404) end - test "gets an activity", %{conn: conn} do - note_activity = insert(:note_activity) - [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) - - conn - |> get("/activities/#{uuid}") - |> response(200) - end - test "404s on private activities", %{conn: conn} do note_activity = insert(:direct_note_activity) [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) @@ -154,7 +156,20 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> response(404) end - test "gets a notice", %{conn: conn} do + test "renders notice metatags in html format", %{conn: conn} do + note_activity = insert(:note_activity) + conn = get(conn, "/notice/#{note_activity.id}") + body = html_response(conn, 200) + twitter_card_summary = "" + + description_content = + "" + + assert body =~ twitter_card_summary + assert body =~ description_content + end + + test "gets a notice in xml format", %{conn: conn} do note_activity = insert(:note_activity) conn