diff --git a/lib/pleroma/web/metadata.ex b/lib/pleroma/web/metadata.ex index f8906e03f..cf2b86aaa 100644 --- a/lib/pleroma/web/metadata.ex +++ b/lib/pleroma/web/metadata.ex @@ -1,65 +1,18 @@ defmodule Pleroma.Web.Metadata do alias Phoenix.HTML - alias Pleroma.{Formatter, User} - alias Pleroma.Web.MediaProxy + @parsers Pleroma.Config.get([:metadata, :providers], []) 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() - end + Enum.reduce(@parsers, "", fn parser, acc -> + rendered_html = + params + |> parser.build_tags() + |> Enum.map(&to_tag/1) + |> Enum.map(&HTML.safe_to_string/1) + |> Enum.join() - 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}" <> - if user.local do - "(@#{user.nickname}@{pleroma_domain})" - else - "(@#{user.nickname})" - end - ], []}, - {: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 - - defp opengraph_tags(_) do - [] + acc <> rendered_html + end) end def to_tag(data) do @@ -73,20 +26,4 @@ defmodule Pleroma.Web.Metadata do 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/metadata/opengraph.ex b/lib/pleroma/web/metadata/opengraph.ex new file mode 100644 index 000000000..5f8bed2fb --- /dev/null +++ b/lib/pleroma/web/metadata/opengraph.ex @@ -0,0 +1,66 @@ +defmodule Pleroma.Web.Metadata.Providers.OpenGraph do + alias Pleroma.Web.Metadata.Providers.Provider + alias Pleroma.{HTML, Formatter, User} + alias Pleroma.Web.MediaProxy + + @behaviour Provider + + @impl Provider + def build_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_string(user) + ], []}, + {: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 + + @impl Provider + def build_tags(%{user: user}) do + with truncated_bio = scrub_html_and_truncate(user.bio || "") do + [ + {:meta, + [ + property: "og:title", + content: user_name_string(user) + ], []}, + {: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 + + defp scrub_html_and_truncate(content) do + content + # html content comes from DB already encoded, decode first and scrub after + |> HtmlEntities.decode() + |> HTML.strip_tags() + |> Formatter.truncate() + end + + defp user_avatar_url(user) do + User.avatar_url(user) |> MediaProxy.url() + end + + defp user_name_string(user) do + "#{user.name}" <> + if user.local do + "(@#{user.nickname}@#{Pleroma.Web.Endpoint.host()})" + else + "(@#{user.nickname})" + end + end +end diff --git a/lib/pleroma/web/metadata/provider.ex b/lib/pleroma/web/metadata/provider.ex new file mode 100644 index 000000000..f64810fad --- /dev/null +++ b/lib/pleroma/web/metadata/provider.ex @@ -0,0 +1,3 @@ +defmodule Pleroma.Web.Metadata.Providers.Provider do + @callback build_tags(map()) :: list() +end