diff options
Diffstat (limited to 'lib/pleroma/web')
-rw-r--r-- | lib/pleroma/web/ostatus/metadata.ex | 82 | ||||
-rw-r--r-- | lib/pleroma/web/ostatus/ostatus_controller.ex | 10 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 29 |
3 files changed, 115 insertions, 6 deletions
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, "<!--server-generated-meta-->", 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 |