Merge branch 'features/add-credo-to-ci' into 'develop'
[akkoma] / lib / pleroma / web / metadata / twitter_card.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
6 alias Pleroma.User
7 alias Pleroma.Web.Metadata
8 alias Pleroma.Web.Metadata.Providers.Provider
9 alias Pleroma.Web.Metadata.Utils
10
11 @behaviour Provider
12
13 @impl Provider
14 def build_tags(%{
15 activity_id: id,
16 object: object,
17 user: user
18 }) do
19 attachments = build_attachments(id, object)
20 scrubbed_content = Utils.scrub_html_and_truncate(object)
21 # Zero width space
22 content =
23 if scrubbed_content != "" and scrubbed_content != "\u200B" do
24 "“" <> scrubbed_content <> "”"
25 else
26 ""
27 end
28
29 [
30 {:meta,
31 [
32 property: "twitter:title",
33 content: Utils.user_name_string(user)
34 ], []},
35 {:meta,
36 [
37 property: "twitter:description",
38 content: content
39 ], []}
40 ] ++
41 if attachments == [] or Metadata.activity_nsfw?(object) do
42 [
43 {:meta,
44 [property: "twitter:image", content: Utils.attachment_url(User.avatar_url(user))], []},
45 {:meta, [property: "twitter:card", content: "summary_large_image"], []}
46 ]
47 else
48 attachments
49 end
50 end
51
52 @impl Provider
53 def build_tags(%{user: user}) do
54 with truncated_bio = Utils.scrub_html_and_truncate(user.bio || "") do
55 [
56 {:meta,
57 [
58 property: "twitter:title",
59 content: Utils.user_name_string(user)
60 ], []},
61 {:meta, [property: "twitter:description", content: truncated_bio], []},
62 {:meta, [property: "twitter:image", content: Utils.attachment_url(User.avatar_url(user))],
63 []},
64 {:meta, [property: "twitter:card", content: "summary"], []}
65 ]
66 end
67 end
68
69 defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
70 Enum.reduce(attachments, [], fn attachment, acc ->
71 rendered_tags =
72 Enum.reduce(attachment["url"], [], fn url, acc ->
73 media_type =
74 Enum.find(["image", "audio", "video"], fn media_type ->
75 String.starts_with?(url["mediaType"], media_type)
76 end)
77
78 # TODO: Add additional properties to objects when we have the data available.
79 case media_type do
80 "audio" ->
81 [
82 {:meta, [property: "twitter:card", content: "player"], []},
83 {:meta, [property: "twitter:player:width", content: "480"], []},
84 {:meta, [property: "twitter:player:height", content: "80"], []},
85 {:meta, [property: "twitter:player", content: player_url(id)], []}
86 | acc
87 ]
88
89 "image" ->
90 [
91 {:meta, [property: "twitter:card", content: "summary_large_image"], []},
92 {:meta,
93 [
94 property: "twitter:player",
95 content: Utils.attachment_url(url["href"])
96 ], []}
97 | acc
98 ]
99
100 # TODO: Need the true width and height values here or Twitter renders an iFrame with
101 # a bad aspect ratio
102 "video" ->
103 [
104 {:meta, [property: "twitter:card", content: "player"], []},
105 {:meta, [property: "twitter:player", content: player_url(id)], []},
106 {:meta, [property: "twitter:player:width", content: "480"], []},
107 {:meta, [property: "twitter:player:height", content: "480"], []}
108 | acc
109 ]
110
111 _ ->
112 acc
113 end
114 end)
115
116 acc ++ rendered_tags
117 end)
118 end
119
120 defp player_url(id) do
121 Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice_player, id)
122 end
123 end