Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85629503
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pleroma/web/metadata/providers/open_graph.ex b/lib/pleroma/web/metadata/providers/open_graph.ex
index df0cca74a..3c010518a 100644
--- a/lib/pleroma/web/metadata/providers/open_graph.ex
+++ b/lib/pleroma/web/metadata/providers/open_graph.ex
@@ -1,148 +1,148 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Providers.OpenGraph do
alias Pleroma.User
alias Pleroma.Web.MediaProxy
alias Pleroma.Web.Metadata
alias Pleroma.Web.Metadata.Providers.Provider
alias Pleroma.Web.Metadata.Utils
@behaviour Provider
@media_types ["image", "audio", "video"]
@impl Provider
def build_tags(%{
object: object,
url: url,
user: user
}) do
attachments = build_attachments(object)
- scrubbed_content = Utils.scrub_html_and_truncate(object)
+ filtered_content = Utils.filter_html_and_truncate(object)
[
{:meta,
[
property: "og:title",
content: Utils.user_name_string(user)
], []},
{:meta, [property: "og:url", content: url], []},
{:meta,
[
property: "og:description",
- content: scrubbed_content
+ content: filtered_content
], []},
{:meta, [property: "og:type", content: "article"], []}
] ++
if attachments == [] or Metadata.activity_nsfw?(object) do
[
{:meta, [property: "og:image", content: MediaProxy.preview_url(User.avatar_url(user))],
[]},
{:meta, [property: "og:image:width", content: 150], []},
{:meta, [property: "og:image:height", content: 150], []}
]
else
attachments
end
end
@impl Provider
def build_tags(%{user: user}) do
- with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
+ with truncated_bio = Utils.filter_html_and_truncate(user.bio) do
[
{:meta,
[
property: "og:title",
content: Utils.user_name_string(user)
], []},
{:meta, [property: "og:url", content: user.uri || user.ap_id], []},
{:meta, [property: "og:description", content: truncated_bio], []},
{:meta, [property: "og:type", content: "article"], []},
{:meta, [property: "og:image", content: MediaProxy.preview_url(User.avatar_url(user))],
[]},
{:meta, [property: "og:image:width", content: 150], []},
{:meta, [property: "og:image:height", content: 150], []}
]
end
end
defp build_attachments(%{data: %{"attachment" => attachments}}) do
Enum.reduce(attachments, [], fn attachment, acc ->
rendered_tags =
Enum.reduce(attachment["url"], [], fn url, acc ->
# TODO: Whatsapp only wants JPEG or PNGs. It seems that if we add a second og:image
# object when a Video or GIF is attached it will display that in Whatsapp Rich Preview.
case Utils.fetch_media_type(@media_types, url["mediaType"]) do
"audio" ->
[
{:meta, [property: "og:audio", content: MediaProxy.url(url["href"])], []}
| acc
]
# Not using preview_url for this. It saves bandwidth, but the image dimensions will
# be wrong. We generate it on the fly and have no way to capture or analyze the
# image to get the dimensions. This can be an issue for apps/FEs rendering images
# in timelines too, but you can get clever with the aspect ratio metadata as a
# workaround.
"image" ->
[
{:meta, [property: "og:image", content: MediaProxy.url(url["href"])], []},
{:meta, [property: "og:image:alt", content: attachment["name"]], []}
| acc
]
|> maybe_add_dimensions(url)
"video" ->
[
{:meta, [property: "og:video", content: MediaProxy.url(url["href"])], []}
| acc
]
|> maybe_add_dimensions(url)
|> maybe_add_video_thumbnail(url)
_ ->
acc
end
end)
acc ++ rendered_tags
end)
end
defp build_attachments(_), do: []
# We can use url["mediaType"] to dynamically fill the metadata
defp maybe_add_dimensions(metadata, url) do
type = url["mediaType"] |> String.split("/") |> List.first()
cond do
!is_nil(url["height"]) && !is_nil(url["width"]) ->
metadata ++
[
{:meta, [property: "og:#{type}:width", content: "#{url["width"]}"], []},
{:meta, [property: "og:#{type}:height", content: "#{url["height"]}"], []}
]
true ->
metadata
end
end
# Media Preview Proxy makes thumbnails of videos without resizing, so we can trust the
# width and height of the source video.
defp maybe_add_video_thumbnail(metadata, url) do
cond do
Pleroma.Config.get([:media_preview_proxy, :enabled], false) ->
metadata ++
[
{:meta, [property: "og:image:width", content: "#{url["width"]}"], []},
{:meta, [property: "og:image:height", content: "#{url["height"]}"], []},
{:meta, [property: "og:image", content: MediaProxy.preview_url(url["href"])], []}
]
true ->
metadata
end
end
end
diff --git a/lib/pleroma/web/metadata/providers/twitter_card.ex b/lib/pleroma/web/metadata/providers/twitter_card.ex
index 79183df86..eaa9c26e6 100644
--- a/lib/pleroma/web/metadata/providers/twitter_card.ex
+++ b/lib/pleroma/web/metadata/providers/twitter_card.ex
@@ -1,134 +1,134 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
alias Pleroma.User
alias Pleroma.Web.MediaProxy
alias Pleroma.Web.Metadata
alias Pleroma.Web.Metadata.Providers.Provider
alias Pleroma.Web.Metadata.Utils
@behaviour Provider
@media_types ["image", "audio", "video"]
@impl Provider
def build_tags(%{activity_id: id, object: object, user: user}) do
attachments = build_attachments(id, object)
- scrubbed_content = Utils.scrub_html_and_truncate(object)
+ filtered_content = Utils.filter_html_and_truncate(object)
[
title_tag(user),
- {:meta, [property: "twitter:description", content: scrubbed_content], []}
+ {:meta, [property: "twitter:description", content: filtered_content], []}
] ++
if attachments == [] or Metadata.activity_nsfw?(object) do
[
image_tag(user),
{:meta, [property: "twitter:card", content: "summary"], []}
]
else
attachments
end
end
@impl Provider
def build_tags(%{user: user}) do
- with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
+ with truncated_bio = Utils.filter_html_and_truncate(user.bio) do
[
title_tag(user),
{:meta, [property: "twitter:description", content: truncated_bio], []},
image_tag(user),
{:meta, [property: "twitter:card", content: "summary"], []}
]
end
end
defp title_tag(user) do
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}
end
def image_tag(user) do
{:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))],
[]}
end
defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
Enum.reduce(attachments, [], fn attachment, acc ->
rendered_tags =
Enum.reduce(attachment["url"], [], fn url, acc ->
case Utils.fetch_media_type(@media_types, url["mediaType"]) do
"audio" ->
[
{:meta, [property: "twitter:card", content: "player"], []},
{:meta, [property: "twitter:player:width", content: "480"], []},
{:meta, [property: "twitter:player:height", content: "80"], []},
{:meta, [property: "twitter:player", content: player_url(id)], []}
| acc
]
# Not using preview_url for this. It saves bandwidth, but the image dimensions will
# be wrong. We generate it on the fly and have no way to capture or analyze the
# image to get the dimensions. This can be an issue for apps/FEs rendering images
# in timelines too, but you can get clever with the aspect ratio metadata as a
# workaround.
"image" ->
[
{:meta, [property: "twitter:card", content: "summary_large_image"], []},
{:meta,
[
property: "twitter:player",
content: MediaProxy.url(url["href"])
], []}
| acc
]
|> maybe_add_dimensions(url)
"video" ->
# fallback to old placeholder values
height = url["height"] || 480
width = url["width"] || 480
[
{:meta, [property: "twitter:card", content: "player"], []},
{:meta, [property: "twitter:player", content: player_url(id)], []},
{:meta, [property: "twitter:player:width", content: "#{width}"], []},
{:meta, [property: "twitter:player:height", content: "#{height}"], []},
{:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])],
[]},
{:meta,
[property: "twitter:player:stream:content_type", content: url["mediaType"]], []}
| acc
]
_ ->
acc
end
end)
acc ++ rendered_tags
end)
end
defp build_attachments(_id, _object), do: []
defp player_url(id) do
Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice_player, id)
end
# Videos have problems without dimensions, but we used to not provide WxH for images.
# A default (read: incorrect) fallback for images is likely to cause rendering bugs.
defp maybe_add_dimensions(metadata, url) do
cond do
!is_nil(url["height"]) && !is_nil(url["width"]) ->
metadata ++
[
{:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []},
{:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []}
]
true ->
metadata
end
end
end
diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex
index f5b79a82c..19864f259 100644
--- a/lib/pleroma/web/metadata/utils.ex
+++ b/lib/pleroma/web/metadata/utils.ex
@@ -1,45 +1,58 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Utils do
alias Pleroma.Emoji
alias Pleroma.Formatter
alias Pleroma.HTML
- def filter_html_and_truncate(%{data: %{"content" => content}} = _object) do
- content
- # html content comes from DB already encoded, decode first and scrub after
- |> Emoji.Formatter.demojify()
- |> HTML.filter_tags(Pleroma.HTML.Scrubber.BreaksOnly)
- |> HtmlEntities.decode()
- |> String.replace(~r/<br\s?\/?>/, " ")
- |> Formatter.truncate()
- end
+ def filter_html_and_truncate(%{data: %{"content" => content}} = _object),
+ do: do_filter_html_and_truncate(content)
- def scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do
- content
- |> Emoji.Formatter.demojify()
- |> HtmlEntities.decode()
- |> String.replace(~r/<br\s?\/?>/, " ")
- |> HTML.strip_tags()
- |> HtmlEntities.decode()
- |> Formatter.truncate(max_length)
- end
+ def filter_html_and_truncate(content, max_length \\ nil),
+ do: do_filter_html_and_truncate(content, max_length)
+
+ def scrub_html_and_truncate(%{data: %{"content" => content}} = _object),
+ do: do_scrub_html_and_truncate(content)
+
+ def scrub_html_and_truncate(content, max_length \\ nil),
+ do: do_scrub_html_and_truncate(content, max_length)
def user_name_string(user) do
"#{user.name} " <>
if user.local do
"(@#{user.nickname}@#{Pleroma.Web.Endpoint.host()})"
else
"(@#{user.nickname})"
end
end
@spec fetch_media_type(list(String.t()), String.t()) :: String.t() | nil
def fetch_media_type(supported_types, media_type) do
Enum.find(supported_types, fn support_type ->
String.starts_with?(media_type, support_type)
end)
end
+
+ defp do_filter_html_and_truncate(content, max_length \\ 200) when is_binary(content) do
+ # html content comes from DB already encoded, but demojify decodes for us
+ content
+ |> Emoji.Formatter.demojify()
+ |> HTML.filter_tags(Pleroma.HTML.Scrubber.BreaksOnly)
+ |> HtmlEntities.decode()
+ |> String.replace(~r/<br\s?\/?>/, " ")
+ |> Formatter.truncate(max_length)
+ end
+
+ defp do_scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do
+ # html content comes from DB already encoded, but demojify decodes for us
+ content
+ |> Emoji.Formatter.demojify()
+ |> HtmlEntities.decode()
+ |> String.replace(~r/<br\s?\/?>/, " ")
+ |> HTML.strip_tags()
+ |> HtmlEntities.decode()
+ |> Formatter.truncate(max_length)
+ end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Aug 8, 10:38 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1724020
Default Alt Text
(13 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment