logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma
commit: e91f867cc9f372da2262a3ac95a23bc12266595a
parent: c00fba4f7dcf10c49bf1fa03be348e7c99a3fc47
Author: kaniini <nenolod@gmail.com>
Date:   Sat, 26 Jan 2019 15:47:52 +0000

Merge branch 'features/mastoapi-cards' into 'develop'

MastoAPI: Add Rich-Media support

See merge request pleroma/pleroma!664

Diffstat:

Mlib/pleroma/html.ex14++++++++++++++
Mlib/pleroma/web/mastodon_api/mastodon_api_controller.ex24++++++++++++++++++++++++
Mlib/pleroma/web/router.ex2+-
Mtest/support/http_request_mock.ex8++++++++
Mtest/web/mastodon_api/mastodon_api_controller_test.exs17+++++++++++++++++
Mtest/web/rich_media/controllers/rich_media_controller_test.exs17++++++-----------
6 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex @@ -58,6 +58,20 @@ defmodule Pleroma.HTML do "#{signature}#{to_string(scrubber)}" end) end + + def extract_first_external_url(object, content) do + key = "URL|#{object.id}" + + Cachex.fetch!(:scrubber_cache, key, fn _key -> + result = + content + |> Floki.filter_out("a.mention") + |> Floki.attribute("a", "href") + |> Enum.at(0) + + {:commit, result} + end) + end end defmodule Pleroma.HTML.Scrubber.TwitterText do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} alias Pleroma.Web + alias Pleroma.HTML alias Pleroma.Web.MastodonAPI.{ StatusView, @@ -1322,6 +1323,29 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def get_status_card(status_id) do + with %Activity{} = activity <- Repo.get(Activity, status_id), + true <- ActivityPub.is_public?(activity), + %Object{} = object <- Object.normalize(activity.data["object"]), + page_url <- HTML.extract_first_external_url(object, object.data["content"]), + {:ok, rich_media} <- Pleroma.Web.RichMedia.Parser.parse(page_url) do + page_url = rich_media[:url] || page_url + site_name = rich_media[:site_name] || URI.parse(page_url).host + + rich_media + |> Map.take([:image, :title, :description]) + |> Map.put(:type, "link") + |> Map.put(:provider_name, site_name) + |> Map.put(:url, page_url) + else + _ -> %{} + end + end + + def status_card(conn, %{"id" => status_id}) do + json(conn, get_status_card(status_id)) + end + def try_render(conn, target, params) when is_binary(target) do res = render(conn, target, params) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex @@ -258,7 +258,7 @@ defmodule Pleroma.Web.Router do get("/statuses/:id", MastodonAPIController, :get_status) get("/statuses/:id/context", MastodonAPIController, :get_context) - get("/statuses/:id/card", MastodonAPIController, :empty_object) + get("/statuses/:id/card", MastodonAPIController, :status_card) get("/statuses/:id/favourited_by", MastodonAPIController, :favourited_by) get("/statuses/:id/reblogged_by", MastodonAPIController, :reblogged_by) diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex @@ -653,6 +653,14 @@ defmodule HttpRequestMock do {:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)} end + def get("http://example.com/ogp", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}} + end + + def get("http://example.com/empty", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: "hello"}} + end + def get(url, query, body, headers) do {:error, "Not implemented the mock response for get #{inspect(url)}, #{query}, #{inspect(body)}, #{ diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -1623,5 +1623,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do |> post("/api/v1/statuses/#{activity_two.id}/pin") |> json_response(400) end + + test "Status rich-media Card", %{conn: conn, user: user} do + {:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp"}) + + response = + conn + |> get("/api/v1/statuses/#{activity.id}/card") + |> json_response(200) + + assert response == %{ + "image" => "http://ia.media-imdb.com/images/rock.jpg", + "provider_name" => "www.imdb.com", + "title" => "The Rock", + "type" => "link", + "url" => "http://www.imdb.com/title/tt0117500/" + } + end end end diff --git a/test/web/rich_media/controllers/rich_media_controller_test.exs b/test/web/rich_media/controllers/rich_media_controller_test.exs @@ -1,19 +1,14 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.RichMedia.RichMediaControllerTest do use Pleroma.Web.ConnCase import Pleroma.Factory + import Tesla.Mock setup do - Tesla.Mock.mock(fn - %{ - method: :get, - url: "http://example.com/ogp" - } -> - %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")} - - %{method: :get, url: "http://example.com/empty"} -> - %Tesla.Env{status: 200, body: "hello"} - end) - + mock(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok end