Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into fine_grained_moderation_privileges
This commit is contained in:
commit
1d95012758
|
@ -58,6 +58,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Fixed lowercase HTTP HEAD method in the Media Proxy Preview code
|
- Fixed lowercase HTTP HEAD method in the Media Proxy Preview code
|
||||||
- Removed useless notification call on Delete activities
|
- Removed useless notification call on Delete activities
|
||||||
- Improved performance for filtering out deactivated and invisible users
|
- Improved performance for filtering out deactivated and invisible users
|
||||||
|
- RSS and Atom feeds for users work again
|
||||||
|
- TwitterCard meta tags conformance
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Quack, the logging backend that pushes to Slack channels
|
- Quack, the logging backend that pushes to Slack channels
|
||||||
|
|
|
@ -14,14 +14,8 @@ defmodule Pleroma.Web.Feed.FeedView do
|
||||||
|
|
||||||
require Pleroma.Constants
|
require Pleroma.Constants
|
||||||
|
|
||||||
@spec pub_date(String.t() | DateTime.t()) :: String.t()
|
@days ~w(Mon Tue Wed Thu Fri Sat Sun)
|
||||||
def pub_date(date) when is_binary(date) do
|
@months ~w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
|
||||||
date
|
|
||||||
|> Timex.parse!("{ISO:Extended}")
|
|
||||||
|> pub_date
|
|
||||||
end
|
|
||||||
|
|
||||||
def pub_date(%DateTime{} = date), do: Timex.format!(date, "{RFC822}")
|
|
||||||
|
|
||||||
def prepare_activity(activity, opts \\ []) do
|
def prepare_activity(activity, opts \\ []) do
|
||||||
object = Object.normalize(activity, fetch: false)
|
object = Object.normalize(activity, fetch: false)
|
||||||
|
@ -41,13 +35,18 @@ def prepare_activity(activity, opts \\ []) do
|
||||||
|
|
||||||
def most_recent_update(activities) do
|
def most_recent_update(activities) do
|
||||||
with %{updated_at: updated_at} <- List.first(activities) do
|
with %{updated_at: updated_at} <- List.first(activities) do
|
||||||
NaiveDateTime.to_iso8601(updated_at)
|
to_rfc3339(updated_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def most_recent_update(activities, user) do
|
def most_recent_update(activities, user, :atom) do
|
||||||
(List.first(activities) || user).updated_at
|
(List.first(activities) || user).updated_at
|
||||||
|> NaiveDateTime.to_iso8601()
|
|> to_rfc3339()
|
||||||
|
end
|
||||||
|
|
||||||
|
def most_recent_update(activities, user, :rss) do
|
||||||
|
(List.first(activities) || user).updated_at
|
||||||
|
|> to_rfc2822()
|
||||||
end
|
end
|
||||||
|
|
||||||
def feed_logo do
|
def feed_logo do
|
||||||
|
@ -61,6 +60,10 @@ def feed_logo do
|
||||||
|> MediaProxy.url()
|
|> MediaProxy.url()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def email(user) do
|
||||||
|
user.nickname <> "@" <> Pleroma.Web.Endpoint.host()
|
||||||
|
end
|
||||||
|
|
||||||
def logo(user) do
|
def logo(user) do
|
||||||
user
|
user
|
||||||
|> User.avatar_url()
|
|> User.avatar_url()
|
||||||
|
@ -69,18 +72,34 @@ def logo(user) do
|
||||||
|
|
||||||
def last_activity(activities), do: List.last(activities)
|
def last_activity(activities), do: List.last(activities)
|
||||||
|
|
||||||
def activity_title(%{"content" => content}, opts \\ %{}) do
|
def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ %{}) do
|
||||||
content
|
title =
|
||||||
|
cond do
|
||||||
|
summary != "" -> summary
|
||||||
|
content != "" -> activity_content(data)
|
||||||
|
true -> "a post"
|
||||||
|
end
|
||||||
|
|
||||||
|
title
|
||||||
|> Pleroma.Web.Metadata.Utils.scrub_html()
|
|> Pleroma.Web.Metadata.Utils.scrub_html()
|
||||||
|> Pleroma.Emoji.Formatter.demojify()
|
|> Pleroma.Emoji.Formatter.demojify()
|
||||||
|> Formatter.truncate(opts[:max_length], opts[:omission])
|
|> Formatter.truncate(opts[:max_length], opts[:omission])
|
||||||
|> escape()
|
end
|
||||||
|
|
||||||
|
def activity_description(data) do
|
||||||
|
content = activity_content(data)
|
||||||
|
summary = data["summary"]
|
||||||
|
|
||||||
|
cond do
|
||||||
|
content != "" -> escape(content)
|
||||||
|
summary != "" -> escape(summary)
|
||||||
|
true -> escape(data["type"])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def activity_content(%{"content" => content}) do
|
def activity_content(%{"content" => content}) do
|
||||||
content
|
content
|
||||||
|> String.replace(~r/[\n\r]/, "")
|
|> String.replace(~r/[\n\r]/, "")
|
||||||
|> escape()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def activity_content(_), do: ""
|
def activity_content(_), do: ""
|
||||||
|
@ -112,4 +131,60 @@ def escape(html) do
|
||||||
|> html_escape()
|
|> html_escape()
|
||||||
|> safe_to_string()
|
|> safe_to_string()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_rfc3339(String.t() | NativeDateTime.t()) :: String.t()
|
||||||
|
def to_rfc3339(date) when is_binary(date) do
|
||||||
|
date
|
||||||
|
|> Timex.parse!("{ISO:Extended}")
|
||||||
|
|> to_rfc3339()
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_rfc3339(nd) do
|
||||||
|
nd
|
||||||
|
|> Timex.to_datetime()
|
||||||
|
|> Timex.format!("{RFC3339}")
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec to_rfc2822(String.t() | DateTime.t() | NativeDateTime.t()) :: String.t()
|
||||||
|
def to_rfc2822(datestr) when is_binary(datestr) do
|
||||||
|
datestr
|
||||||
|
|> Timex.parse!("{ISO:Extended}")
|
||||||
|
|> to_rfc2822()
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_rfc2822(%DateTime{} = date) do
|
||||||
|
date
|
||||||
|
|> DateTime.to_naive()
|
||||||
|
|> NaiveDateTime.to_erl()
|
||||||
|
|> rfc2822_from_erl()
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_rfc2822(nd) do
|
||||||
|
nd
|
||||||
|
|> Timex.to_datetime()
|
||||||
|
|> DateTime.to_naive()
|
||||||
|
|> NaiveDateTime.to_erl()
|
||||||
|
|> rfc2822_from_erl()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Builds a RFC2822 timestamp from an Erlang timestamp
|
||||||
|
[RFC2822 3.3 - Date and Time Specification](https://tools.ietf.org/html/rfc2822#section-3.3)
|
||||||
|
This function always assumes the Erlang timestamp is in Universal time, not Local time
|
||||||
|
"""
|
||||||
|
def rfc2822_from_erl({{year, month, day} = date, {hour, minute, second}}) do
|
||||||
|
day_name = Enum.at(@days, :calendar.day_of_the_week(date) - 1)
|
||||||
|
month_name = Enum.at(@months, month - 1)
|
||||||
|
|
||||||
|
date_part = "#{day_name}, #{day} #{month_name} #{year}"
|
||||||
|
time_part = "#{pad(hour)}:#{pad(minute)}:#{pad(second)}"
|
||||||
|
|
||||||
|
date_part <> " " <> time_part <> " +0000"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp pad(num) do
|
||||||
|
num
|
||||||
|
|> Integer.to_string()
|
||||||
|
|> String.pad_leading(2, "0")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,12 +20,12 @@ def build_tags(%{activity_id: id, object: object, user: user}) do
|
||||||
|
|
||||||
[
|
[
|
||||||
title_tag(user),
|
title_tag(user),
|
||||||
{:meta, [property: "twitter:description", content: scrubbed_content], []}
|
{:meta, [name: "twitter:description", content: scrubbed_content], []}
|
||||||
] ++
|
] ++
|
||||||
if attachments == [] or Metadata.activity_nsfw?(object) do
|
if attachments == [] or Metadata.activity_nsfw?(object) do
|
||||||
[
|
[
|
||||||
image_tag(user),
|
image_tag(user),
|
||||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
attachments
|
attachments
|
||||||
|
@ -37,20 +37,19 @@ def build_tags(%{user: user}) do
|
||||||
with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
|
with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
|
||||||
[
|
[
|
||||||
title_tag(user),
|
title_tag(user),
|
||||||
{:meta, [property: "twitter:description", content: truncated_bio], []},
|
{:meta, [name: "twitter:description", content: truncated_bio], []},
|
||||||
image_tag(user),
|
image_tag(user),
|
||||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp title_tag(user) do
|
defp title_tag(user) do
|
||||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}
|
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}
|
||||||
end
|
end
|
||||||
|
|
||||||
def image_tag(user) do
|
def image_tag(user) do
|
||||||
{:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))],
|
{:meta, [name: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], []}
|
||||||
[]}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
||||||
|
@ -60,10 +59,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
||||||
case Utils.fetch_media_type(@media_types, url["mediaType"]) do
|
case Utils.fetch_media_type(@media_types, url["mediaType"]) do
|
||||||
"audio" ->
|
"audio" ->
|
||||||
[
|
[
|
||||||
{:meta, [property: "twitter:card", content: "player"], []},
|
{:meta, [name: "twitter:card", content: "player"], []},
|
||||||
{:meta, [property: "twitter:player:width", content: "480"], []},
|
{:meta, [name: "twitter:player:width", content: "480"], []},
|
||||||
{:meta, [property: "twitter:player:height", content: "80"], []},
|
{:meta, [name: "twitter:player:height", content: "80"], []},
|
||||||
{:meta, [property: "twitter:player", content: player_url(id)], []}
|
{:meta, [name: "twitter:player", content: player_url(id)], []}
|
||||||
| acc
|
| acc
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -74,10 +73,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
||||||
# workaround.
|
# workaround.
|
||||||
"image" ->
|
"image" ->
|
||||||
[
|
[
|
||||||
{:meta, [property: "twitter:card", content: "summary_large_image"], []},
|
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
|
||||||
{:meta,
|
{:meta,
|
||||||
[
|
[
|
||||||
property: "twitter:player",
|
name: "twitter:player",
|
||||||
content: MediaProxy.url(url["href"])
|
content: MediaProxy.url(url["href"])
|
||||||
], []}
|
], []}
|
||||||
| acc
|
| acc
|
||||||
|
@ -90,14 +89,14 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
||||||
width = url["width"] || 480
|
width = url["width"] || 480
|
||||||
|
|
||||||
[
|
[
|
||||||
{:meta, [property: "twitter:card", content: "player"], []},
|
{:meta, [name: "twitter:card", content: "player"], []},
|
||||||
{:meta, [property: "twitter:player", content: player_url(id)], []},
|
{:meta, [name: "twitter:player", content: player_url(id)], []},
|
||||||
{:meta, [property: "twitter:player:width", content: "#{width}"], []},
|
{:meta, [name: "twitter:player:width", content: "#{width}"], []},
|
||||||
{:meta, [property: "twitter:player:height", content: "#{height}"], []},
|
{:meta, [name: "twitter:player:height", content: "#{height}"], []},
|
||||||
{:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])],
|
{:meta, [name: "twitter:player:stream", content: MediaProxy.url(url["href"])],
|
||||||
[]},
|
[]},
|
||||||
{:meta,
|
{:meta, [name: "twitter:player:stream:content_type", content: url["mediaType"]],
|
||||||
[property: "twitter:player:stream:content_type", content: url["mediaType"]], []}
|
[]}
|
||||||
| acc
|
| acc
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -123,8 +122,8 @@ defp maybe_add_dimensions(metadata, url) do
|
||||||
!is_nil(url["height"]) && !is_nil(url["width"]) ->
|
!is_nil(url["height"]) && !is_nil(url["width"]) ->
|
||||||
metadata ++
|
metadata ++
|
||||||
[
|
[
|
||||||
{:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []},
|
{:meta, [name: "twitter:player:width", content: "#{url["width"]}"], []},
|
||||||
{:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []}
|
{:meta, [name: "twitter:player:height", content: "#{url["height"]}"], []}
|
||||||
]
|
]
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||||
<id><%= @data["id"] %></id>
|
<id><%= @data["id"] %></id>
|
||||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||||
<content type="html"><%= activity_content(@data) %></content>
|
<content type="html"><%= activity_description(@data) %></content>
|
||||||
<published><%= @activity.data["published"] %></published>
|
<published><%= to_rfc3339(@activity.data["published"]) %></published>
|
||||||
<updated><%= @activity.data["published"] %></updated>
|
<updated><%= to_rfc3339(@activity.data["published"]) %></updated>
|
||||||
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||||
<%= activity_context(@activity) %>
|
<%= activity_context(@activity) %>
|
||||||
</ostatus:conversation>
|
</ostatus:conversation>
|
||||||
<link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
|
<link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
|
||||||
|
|
||||||
<%= if @data["summary"] do %>
|
<%= if @data["summary"] != "" do %>
|
||||||
<summary><%= escape(@data["summary"]) %></summary>
|
<summary><%= escape(@data["summary"]) %></summary>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,12 @@
|
||||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||||
<guid><%= @data["id"] %></guid>
|
<guid><%= @data["id"] %></guid>
|
||||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||||
<description><%= activity_content(@data) %></description>
|
<description><%= activity_description(@data) %></description>
|
||||||
<pubDate><%= @activity.data["published"] %></pubDate>
|
<pubDate><%= to_rfc2822(@activity.data["published"]) %></pubDate>
|
||||||
<updated><%= @activity.data["published"] %></updated>
|
|
||||||
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||||
<%= activity_context(@activity) %>
|
<%= activity_context(@activity) %>
|
||||||
</ostatus:conversation>
|
</ostatus:conversation>
|
||||||
|
|
||||||
<%= if @data["summary"] do %>
|
|
||||||
<description><%= escape(@data["summary"]) %></description>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= if @activity.local do %>
|
<%= if @activity.local do %>
|
||||||
<link><%= @data["id"] %></link>
|
<link><%= @data["id"] %></link>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
@ -27,7 +22,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= for attachment <- @data["attachment"] || [] do %>
|
<%= for attachment <- @data["attachment"] || [] do %>
|
||||||
<link type="<%= attachment_type(attachment) %>"><%= attachment_href(attachment) %></link>
|
<enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>" />
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if @data["inReplyTo"] do %>
|
<%= if @data["inReplyTo"] do %>
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
<author>
|
<author>
|
||||||
<id><%= @user.ap_id %></id>
|
|
||||||
<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>
|
|
||||||
<uri><%= @user.ap_id %></uri>
|
<uri><%= @user.ap_id %></uri>
|
||||||
|
<name><%= @user.nickname %></name>
|
||||||
|
<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>
|
||||||
|
<activity:displayName><%= @user.name %></activity:displayName>
|
||||||
|
<activity:image><%= User.avatar_url(@user) %></activity:image>
|
||||||
|
<activity:id><%= @user.ap_id %></activity:id>
|
||||||
|
<activity:published><%= to_rfc3339(@user.inserted_at) %></activity:published>
|
||||||
|
<activity:updated><%= to_rfc3339(@user.updated_at) %></activity:updated>
|
||||||
|
<activity:url><%= @user.ap_id %></activity:url>
|
||||||
<poco:preferredUsername><%= @user.nickname %></poco:preferredUsername>
|
<poco:preferredUsername><%= @user.nickname %></poco:preferredUsername>
|
||||||
<poco:displayName><%= @user.name %></poco:displayName>
|
<poco:displayName><%= @user.name %></poco:displayName>
|
||||||
<poco:note><%= escape(@user.bio) %></poco:note>
|
<poco:note><%= escape(@user.bio) %></poco:note>
|
||||||
<summary><%= escape(@user.bio) %></summary>
|
|
||||||
<name><%= @user.nickname %></name>
|
|
||||||
<link rel="avatar" href="<%= User.avatar_url(@user) %>"/>
|
|
||||||
<%= if User.banner_url(@user) do %>
|
|
||||||
<link rel="header" href="<%= User.banner_url(@user) %>"/>
|
|
||||||
<% end %>
|
|
||||||
<%= if @user.local do %>
|
|
||||||
<ap_enabled>true</ap_enabled>
|
|
||||||
<% end %>
|
|
||||||
</author>
|
</author>
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
<managingEditor>
|
<managingEditor><%= "#{email(@user)} (#{escape(@user.name)})" %></managingEditor>
|
||||||
<guid><%= @user.ap_id %></guid>
|
|
||||||
<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>
|
<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>
|
||||||
<uri><%= @user.ap_id %></uri>
|
<activity:displayName><%= @user.name %></activity:displayName>
|
||||||
|
<activity:image><%= User.avatar_url(@user) %></activity:image>
|
||||||
|
<activity:id><%= @user.ap_id %></activity:id>
|
||||||
|
<activity:published><%= to_rfc3339(@user.inserted_at) %></activity:published>
|
||||||
|
<activity:updated><%= to_rfc3339(@user.updated_at) %></activity:updated>
|
||||||
<poco:preferredUsername><%= @user.nickname %></poco:preferredUsername>
|
<poco:preferredUsername><%= @user.nickname %></poco:preferredUsername>
|
||||||
<poco:displayName><%= @user.name %></poco:displayName>
|
<poco:displayName><%= @user.name %></poco:displayName>
|
||||||
<poco:note><%= escape(@user.bio) %></poco:note>
|
<poco:note><%= escape(@user.bio) %></poco:note>
|
||||||
<description><%= escape(@user.bio) %></description>
|
|
||||||
<name><%= @user.nickname %></name>
|
|
||||||
<link rel="avatar"><%= User.avatar_url(@user) %></link>
|
|
||||||
<%= if User.banner_url(@user) do %>
|
|
||||||
<link rel="header"><%= User.banner_url(@user) %></link>
|
|
||||||
<% end %>
|
|
||||||
<%= if @user.local do %>
|
|
||||||
<ap_enabled>true</ap_enabled>
|
|
||||||
<% end %>
|
|
||||||
</managingEditor>
|
|
||||||
|
|
|
@ -6,7 +6,17 @@
|
||||||
|
|
||||||
<id><%= @data["id"] %></id>
|
<id><%= @data["id"] %></id>
|
||||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||||
<content type="html"><%= activity_content(@data) %></content>
|
<content type="html"><%= activity_description(@data) %></content>
|
||||||
|
<published><%= to_rfc3339(@activity.data["published"]) %></published>
|
||||||
|
<updated><%= to_rfc3339(@activity.data["published"]) %></updated>
|
||||||
|
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
||||||
|
<%= activity_context(@activity) %>
|
||||||
|
</ostatus:conversation>
|
||||||
|
<link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
|
||||||
|
|
||||||
|
<%= if @data["summary"] != "" do %>
|
||||||
|
<summary><%= @data["summary"] %></summary>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%= if @activity.local do %>
|
<%= if @activity.local do %>
|
||||||
<link type="application/atom+xml" href='<%= @data["id"] %>' rel="self"/>
|
<link type="application/atom+xml" href='<%= @data["id"] %>' rel="self"/>
|
||||||
|
@ -15,18 +25,6 @@
|
||||||
<link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
|
<link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<published><%= @activity.data["published"] %></published>
|
|
||||||
<updated><%= @activity.data["published"] %></updated>
|
|
||||||
|
|
||||||
<ostatus:conversation ref="<%= activity_context(@activity) %>">
|
|
||||||
<%= activity_context(@activity) %>
|
|
||||||
</ostatus:conversation>
|
|
||||||
<link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
|
|
||||||
|
|
||||||
<%= if @data["summary"] do %>
|
|
||||||
<summary><%= @data["summary"] %></summary>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= for id <- @activity.recipients do %>
|
<%= for id <- @activity.recipients do %>
|
||||||
<%= if id == Pleroma.Constants.as_public() do %>
|
<%= if id == Pleroma.Constants.as_public() do %>
|
||||||
<link rel="mentioned"
|
<link rel="mentioned"
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
<guid isPermalink="true"><%= activity_context(@activity) %></guid>
|
<guid isPermalink="true"><%= activity_context(@activity) %></guid>
|
||||||
<link><%= activity_context(@activity) %></link>
|
<link><%= activity_context(@activity) %></link>
|
||||||
<pubDate><%= pub_date(@activity.data["published"]) %></pubDate>
|
<pubDate><%= to_rfc2822(@activity.data["published"]) %></pubDate>
|
||||||
|
|
||||||
<description><%= activity_content(@data) %></description>
|
<description><%= activity_description(@data) %></description>
|
||||||
<%= for attachment <- @data["attachment"] || [] do %>
|
<%= for attachment <- @data["attachment"] || [] do %>
|
||||||
<enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>"/>
|
<enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>"/>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
<author>
|
<author>
|
||||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
|
||||||
<id><%= @actor.ap_id %></id>
|
|
||||||
<uri><%= @actor.ap_id %></uri>
|
<uri><%= @actor.ap_id %></uri>
|
||||||
<name><%= @actor.nickname %></name>
|
<name><%= @actor.nickname %></name>
|
||||||
<summary><%= escape(@actor.bio) %></summary>
|
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||||
<link rel="avatar" href="<%= User.avatar_url(@actor) %>"/>
|
<activity:displayName><%= @actor.name %></activity:displayName>
|
||||||
<%= if User.banner_url(@actor) do %>
|
<activity:image><%= User.avatar_url(@actor) %></activity:image>
|
||||||
<link rel="header" href="<%= User.banner_url(@actor) %>"/>
|
<activity:id><%= @actor.ap_id %></activity:id>
|
||||||
<% end %>
|
<activity:published><%= to_rfc3339(@actor.inserted_at) %></activity:published>
|
||||||
<%= if @actor.local do %>
|
<activity:updated><%= to_rfc3339(@actor.updated_at) %></activity:updated>
|
||||||
<ap_enabled>true</ap_enabled>
|
<activity:url><%= @actor.ap_id %></activity:url>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<poco:preferredUsername><%= @actor.nickname %></poco:preferredUsername>
|
<poco:preferredUsername><%= @actor.nickname %></poco:preferredUsername>
|
||||||
<poco:displayName><%= @actor.name %></poco:displayName>
|
<poco:displayName><%= @actor.name %></poco:displayName>
|
||||||
<poco:note><%= escape(@actor.bio) %></poco:note>
|
<poco:note><%= escape(@actor.bio) %></poco:note>
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed
|
||||||
<feed xml:lang="<%= Gettext.language_tag() %>" xmlns="http://www.w3.org/2005/Atom"
|
xmlns="http://www.w3.org/2005/Atom"
|
||||||
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
||||||
xmlns:georss="http://www.georss.org/georss"
|
|
||||||
xmlns:activity="http://activitystrea.ms/spec/1.0/"
|
xmlns:activity="http://activitystrea.ms/spec/1.0/"
|
||||||
xmlns:media="http://purl.org/syndication/atommedia"
|
|
||||||
xmlns:poco="http://portablecontacts.net/spec/1.0"
|
xmlns:poco="http://portablecontacts.net/spec/1.0"
|
||||||
xmlns:ostatus="http://ostatus.org/schema/1.0"
|
xmlns:ostatus="http://ostatus.org/schema/1.0"
|
||||||
xmlns:statusnet="http://status.net/schema/api/1/">
|
xmlns:statusnet="http://status.net/schema/api/1/">
|
||||||
|
|
||||||
<id><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></id>
|
<id><%= Routes.tag_feed_url(@conn, :feed, @tag) <> ".atom" %></id>
|
||||||
<title>#<%= @tag %></title>
|
<title>#<%= @tag %></title>
|
||||||
|
|
||||||
<subtitle><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></subtitle>
|
<subtitle><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></subtitle>
|
||||||
<logo><%= feed_logo() %></logo>
|
<logo><%= feed_logo() %></logo>
|
||||||
<updated><%= most_recent_update(@activities) %></updated>
|
<updated><%= most_recent_update(@activities) %></updated>
|
||||||
<link rel="self" href="<%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom' %>" type="application/atom+xml"/>
|
<link rel="self" href="<%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom' %>" type="application/atom+xml"/>
|
||||||
|
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
<%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %>
|
<%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<rss version="2.0" xmlns:webfeeds="http://webfeeds.org/rss/1.0">
|
<rss version="2.0"
|
||||||
|
xmlns:webfeeds="http://webfeeds.org/rss/1.0"
|
||||||
|
xmlns:thr="http://purl.org/syndication/thread/1.0">
|
||||||
<channel>
|
<channel>
|
||||||
|
|
||||||
|
|
||||||
<title>#<%= @tag %></title>
|
<title>#<%= @tag %></title>
|
||||||
<description><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></description>
|
<description><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></description>
|
||||||
<link><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></link>
|
<link><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></link>
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
<id><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
|
<id><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>
|
||||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||||
<updated><%= most_recent_update(@activities, @user) %></updated>
|
<subtitle><%= escape(@user.bio) %></subtitle>
|
||||||
|
<updated><%= most_recent_update(@activities, @user, :atom) %></updated>
|
||||||
<logo><%= logo(@user) %></logo>
|
<logo><%= logo(@user) %></logo>
|
||||||
<link rel="self" href="<%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
|
<link rel="self" href="<%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<rss version="2.0">
|
<rss version="2.0"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
||||||
|
xmlns:activity="http://activitystrea.ms/spec/1.0/"
|
||||||
|
xmlns:ostatus="http://ostatus.org/schema/1.0"
|
||||||
|
xmlns:poco="http://portablecontacts.net/spec/1.0">
|
||||||
<channel>
|
<channel>
|
||||||
<guid><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %></guid>
|
|
||||||
<title><%= @user.nickname <> "'s timeline" %></title>
|
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||||
<updated><%= most_recent_update(@activities, @user) %></updated>
|
|
||||||
<image><%= logo(@user) %></image>
|
|
||||||
<link><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link>
|
<link><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link>
|
||||||
|
<atom:link href="<%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %>"
|
||||||
|
rel="self" type="application/rss+xml" />
|
||||||
|
<description><%= escape(@user.bio) %></description>
|
||||||
|
<image>
|
||||||
|
<url><%= logo(@user) %></url>
|
||||||
|
<title><%= @user.nickname <> "'s timeline" %></title>
|
||||||
|
<link><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link>
|
||||||
|
</image>
|
||||||
|
|
||||||
<%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %>
|
<%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %>
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ test "gets a feed (ATOM)", %{conn: conn} do
|
||||||
]
|
]
|
||||||
|
|
||||||
assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
|
assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
|
||||||
assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id]
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|
@ -138,8 +137,8 @@ test "gets a feed (RSS)", %{conn: conn} do
|
||||||
]
|
]
|
||||||
|
|
||||||
assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [
|
assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [
|
||||||
FeedView.pub_date(activity2.data["published"]),
|
FeedView.to_rfc2822(activity2.data["published"]),
|
||||||
FeedView.pub_date(activity1.data["published"])
|
FeedView.to_rfc2822(activity1.data["published"])
|
||||||
]
|
]
|
||||||
|
|
||||||
assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [
|
assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [
|
||||||
|
|
|
@ -74,7 +74,7 @@ test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_
|
||||||
|> SweetXml.parse()
|
|> SweetXml.parse()
|
||||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||||
|
|
||||||
assert activity_titles == ['42 & Thi...', 'This & t...']
|
assert activity_titles == ['2hu', '2hu & as']
|
||||||
assert resp =~ FeedView.escape(object.data["content"])
|
assert resp =~ FeedView.escape(object.data["content"])
|
||||||
assert resp =~ FeedView.escape(object.data["summary"])
|
assert resp =~ FeedView.escape(object.data["summary"])
|
||||||
assert resp =~ FeedView.escape(object.data["context"])
|
assert resp =~ FeedView.escape(object.data["context"])
|
||||||
|
@ -90,7 +90,7 @@ test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_
|
||||||
|> SweetXml.parse()
|
|> SweetXml.parse()
|
||||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||||
|
|
||||||
assert activity_titles == ['This & t...']
|
assert activity_titles == ['2hu & as']
|
||||||
end
|
end
|
||||||
|
|
||||||
test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
|
test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
|
||||||
|
@ -105,7 +105,7 @@ test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id
|
||||||
|> SweetXml.parse()
|
|> SweetXml.parse()
|
||||||
|> SweetXml.xpath(~x"//item/title/text()"l)
|
|> SweetXml.xpath(~x"//item/title/text()"l)
|
||||||
|
|
||||||
assert activity_titles == ['42 & Thi...', 'This & t...']
|
assert activity_titles == ['2hu', '2hu & as']
|
||||||
assert resp =~ FeedView.escape(object.data["content"])
|
assert resp =~ FeedView.escape(object.data["content"])
|
||||||
assert resp =~ FeedView.escape(object.data["summary"])
|
assert resp =~ FeedView.escape(object.data["summary"])
|
||||||
assert resp =~ FeedView.escape(object.data["context"])
|
assert resp =~ FeedView.escape(object.data["context"])
|
||||||
|
@ -121,7 +121,7 @@ test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id
|
||||||
|> SweetXml.parse()
|
|> SweetXml.parse()
|
||||||
|> SweetXml.xpath(~x"//item/title/text()"l)
|
|> SweetXml.xpath(~x"//item/title/text()"l)
|
||||||
|
|
||||||
assert activity_titles == ['This & t...']
|
assert activity_titles == ['2hu & as']
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns 404 for a missing feed", %{conn: conn} do
|
test "returns 404 for a missing feed", %{conn: conn} do
|
||||||
|
|
|
@ -22,10 +22,10 @@ test "it renders twitter card for user info" do
|
||||||
res = TwitterCard.build_tags(%{user: user})
|
res = TwitterCard.build_tags(%{user: user})
|
||||||
|
|
||||||
assert res == [
|
assert res == [
|
||||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||||
{:meta, [property: "twitter:description", content: "born 19 March 1994"], []},
|
{:meta, [name: "twitter:description", content: "born 19 March 1994"], []},
|
||||||
{:meta, [property: "twitter:image", content: avatar_url], []},
|
{:meta, [name: "twitter:image", content: avatar_url], []},
|
||||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ test "it uses summary twittercard if post has no attachment" do
|
||||||
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||||
{:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
|
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
|
||||||
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
{:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
||||||
[]},
|
[]},
|
||||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||||
] == result
|
] == result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -73,15 +73,15 @@ test "it uses summary as description if post has one" do
|
||||||
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||||
{:meta,
|
{:meta,
|
||||||
[
|
[
|
||||||
property: "twitter:description",
|
name: "twitter:description",
|
||||||
content: "Public service announcement on caffeine consumption"
|
content: "Public service announcement on caffeine consumption"
|
||||||
], []},
|
], []},
|
||||||
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
{:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
||||||
[]},
|
[]},
|
||||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||||
] == result
|
] == result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -123,11 +123,11 @@ test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabl
|
||||||
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||||
{:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
|
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
|
||||||
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
{:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
||||||
[]},
|
[]},
|
||||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||||
] == result
|
] == result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -179,26 +179,26 @@ test "it renders supported types of attachments and skips unknown types" do
|
||||||
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||||
{:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
|
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
|
||||||
{:meta, [property: "twitter:card", content: "summary_large_image"], []},
|
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
|
||||||
{:meta, [property: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
|
{:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
|
||||||
{:meta, [property: "twitter:player:width", content: "1280"], []},
|
{:meta, [name: "twitter:player:width", content: "1280"], []},
|
||||||
{:meta, [property: "twitter:player:height", content: "1024"], []},
|
{:meta, [name: "twitter:player:height", content: "1024"], []},
|
||||||
{:meta, [property: "twitter:card", content: "player"], []},
|
{:meta, [name: "twitter:card", content: "player"], []},
|
||||||
{:meta,
|
{:meta,
|
||||||
[
|
[
|
||||||
property: "twitter:player",
|
name: "twitter:player",
|
||||||
content: Router.Helpers.o_status_url(Endpoint, :notice_player, activity.id)
|
content: Router.Helpers.o_status_url(Endpoint, :notice_player, activity.id)
|
||||||
], []},
|
], []},
|
||||||
{:meta, [property: "twitter:player:width", content: "800"], []},
|
{:meta, [name: "twitter:player:width", content: "800"], []},
|
||||||
{:meta, [property: "twitter:player:height", content: "600"], []},
|
{:meta, [name: "twitter:player:height", content: "600"], []},
|
||||||
{:meta,
|
{:meta,
|
||||||
[
|
[
|
||||||
property: "twitter:player:stream",
|
name: "twitter:player:stream",
|
||||||
content: "https://pleroma.gov/about/juche.webm"
|
content: "https://pleroma.gov/about/juche.webm"
|
||||||
], []},
|
], []},
|
||||||
{:meta, [property: "twitter:player:stream:content_type", content: "video/webm"], []}
|
{:meta, [name: "twitter:player:stream:content_type", content: "video/webm"], []}
|
||||||
] == result
|
] == result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue