From 99c0a11c584ac13c368a3d8372f9e914cef14a06 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Fri, 24 Jan 2020 22:08:10 +0300 Subject: [PATCH] added atom feed --- lib/pleroma/web/feed/feed_view.ex | 16 +++++- lib/pleroma/web/feed/tag_controller.ex | 11 ++-- .../web/templates/feed/feed/_activity.xml.eex | 2 +- .../feed/feed/_tag_activity.atom.eex | 51 +++++++++++++++++ .../templates/feed/feed/_tag_author.atom.eex | 18 ++++++ .../web/templates/feed/feed/tag.atom.eex | 22 ++++++++ .../feed/feed/{tag.xml.eex => tag.rss.eex} | 0 test/web/feed/tag_controller_test.exs | 55 ++++++++++++++++++- 8 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex create mode 100644 lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex create mode 100644 lib/pleroma/web/templates/feed/feed/tag.atom.eex rename lib/pleroma/web/templates/feed/feed/{tag.xml.eex => tag.rss.eex} (100%) diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index 2e7db1ebb..334802e0a 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -22,16 +22,28 @@ def pub_date(date) when is_binary(date) do def pub_date(%DateTime{} = date), do: Timex.format!(date, "{RFC822}") - def prepare_activity(activity) do + def prepare_activity(activity, opts \\ []) do object = activity_object(activity) + actor = + if opts[:actor] do + Pleroma.User.get_cached_by_ap_id(activity.actor) + end + %{ activity: activity, data: Map.get(object, :data), - object: object + object: object, + actor: actor } end + def most_recent_update(activities) do + with %{updated_at: updated_at} <- List.first(activities) do + NaiveDateTime.to_iso8601(updated_at) + end + end + def most_recent_update(activities, user) do (List.first(activities) || user).updated_at |> NaiveDateTime.to_iso8601() diff --git a/lib/pleroma/web/feed/tag_controller.ex b/lib/pleroma/web/feed/tag_controller.ex index 97ce147de..9b722336c 100644 --- a/lib/pleroma/web/feed/tag_controller.ex +++ b/lib/pleroma/web/feed/tag_controller.ex @@ -12,7 +12,7 @@ defmodule Pleroma.Web.Feed.TagController do import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3] def feed(conn, %{"tag" => raw_tag} = params) do - tag = parse_tag(raw_tag) + {format, tag} = parse_tag(raw_tag) activities = %{"type" => ["Create"], "whole_db" => true, "tag" => tag} @@ -22,19 +22,20 @@ def feed(conn, %{"tag" => raw_tag} = params) do conn |> put_resp_content_type("application/atom+xml") |> put_view(FeedView) - |> render("tag.xml", + |> render("tag.#{format}", activities: activities, tag: tag, feed_config: Config.get([:feed]) ) end + @spec parse_tag(binary() | any()) :: {format :: String.t(), tag :: String.t()} defp parse_tag(raw_tag) when is_binary(raw_tag) do case Enum.reverse(String.split(raw_tag, ".")) do - [format | tag] when format in ["atom", "rss"] -> Enum.join(tag, ".") - _ -> raw_tag + [format | tag] when format in ["atom", "rss"] -> {format, Enum.join(tag, ".")} + _ -> {"rss", raw_tag} end end - defp parse_tag(raw_tag), do: raw_tag + defp parse_tag(raw_tag), do: {"rss", raw_tag} end diff --git a/lib/pleroma/web/templates/feed/feed/_activity.xml.eex b/lib/pleroma/web/templates/feed/feed/_activity.xml.eex index 514eacaed..ac8a75009 100644 --- a/lib/pleroma/web/templates/feed/feed/_activity.xml.eex +++ b/lib/pleroma/web/templates/feed/feed/_activity.xml.eex @@ -9,7 +9,7 @@ <%= activity_context(@activity) %> - + <%= if @data["summary"] do %> <%= @data["summary"] %> diff --git a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex new file mode 100644 index 000000000..da4fa6d6c --- /dev/null +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex @@ -0,0 +1,51 @@ + + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + + <%= render @view_module, "_tag_author.atom", assigns %> + + <%= @data["id"] %> + <%= activity_title(@object, Keyword.get(@feed_config, :post_title, %{})) %> + <%= activity_content(@object) %> + + <%= if @activity.local do %> + + + <% else %> + + <% end %> + + <%= @data["published"] %> + <%= @data["published"] %> + + + <%= activity_context(@activity) %> + + + + <%= if @data["summary"] do %> + <%= @data["summary"] %> + <% end %> + + <%= for id <- @activity.recipients do %> + <%= if id == Pleroma.Constants.as_public() do %> + + <% else %> + <%= unless Regex.match?(~r/^#{Pleroma.Web.base_url()}.+followers$/, id) do %> + + <% end %> + <% end %> + <% end %> + + <%= for tag <- @data["tag"] || [] do %> + + <% end %> + + <%= for {emoji, file} <- @data["emoji"] || %{} do %> + + <% end %> + diff --git a/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex new file mode 100644 index 000000000..997c4936e --- /dev/null +++ b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex @@ -0,0 +1,18 @@ + + http://activitystrea.ms/schema/1.0/person + <%= @actor.ap_id %> + <%= @actor.ap_id %> + <%= @actor.nickname %> + <%= escape(@actor.bio) %> + + <%= if User.banner_url(@actor) do %> + + <% end %> + <%= if @actor.local do %> + true + <% end %> + + <%= @actor.nickname %> + <%= @actor.name %> + <%= escape(@actor.bio) %> + diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex new file mode 100644 index 000000000..a288539ed --- /dev/null +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -0,0 +1,22 @@ + + + + + <%= '#{tag_feed_url(@conn, :feed, @tag)}.rss' %> + #<%= @tag %> + + These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse. + <%= feed_logo() %> + <%= most_recent_update(@activities) %> + + <%= for activity <- @activities do %> + <%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> + <% end %> + diff --git a/lib/pleroma/web/templates/feed/feed/tag.xml.eex b/lib/pleroma/web/templates/feed/feed/tag.rss.eex similarity index 100% rename from lib/pleroma/web/templates/feed/feed/tag.xml.eex rename to lib/pleroma/web/templates/feed/feed/tag.rss.eex diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs index a56a18738..214698192 100644 --- a/test/web/feed/tag_controller_test.exs +++ b/test/web/feed/tag_controller_test.exs @@ -12,7 +12,60 @@ defmodule Pleroma.Web.Feed.TagControllerTest do clear_config([:feed]) - test "gets a feed", %{conn: conn} do + test "gets a feed (ATOM)", %{conn: conn} do + Pleroma.Config.put( + [:feed, :post_title], + %{max_length: 25, omission: "..."} + ) + + user = insert(:user) + {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) + + object = Pleroma.Object.normalize(activity1) + + object_data = + Map.put(object.data, "attachment", [ + %{ + "url" => [ + %{ + "href" => + "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4", + "mediaType" => "video/mp4", + "type" => "Link" + } + ] + } + ]) + + object + |> Ecto.Changeset.change(data: object_data) + |> Pleroma.Repo.update() + + {:ok, _activity2} = + Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) + + {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"}) + + response = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get(tag_feed_path(conn, :feed, "pleromaart.atom")) + |> response(200) + + xml = parse(response) + + assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart' + + assert xpath(xml, ~x"//feed/entry/title/text()"l) == [ + '42 This is :moominmamm...', + 'yeah #PleromaArt' + ] + + 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] + end + + test "gets a feed (RSS)", %{conn: conn} do Pleroma.Config.put( [:feed, :post_title], %{max_length: 25, omission: "..."}