Merge branch 'features/bio_rel_me' into 'develop'
Add rel=me to the User bio Closes #423 See merge request pleroma/pleroma!813
This commit is contained in:
commit
ace4231628
@ -22,6 +22,7 @@ defmodule Pleroma.User do
|
|||||||
alias Pleroma.Web.OAuth
|
alias Pleroma.Web.OAuth
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.RelMe
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@ -1232,8 +1233,14 @@ defmodule Pleroma.User do
|
|||||||
{String.trim(name, ":"), url}
|
{String.trim(name, ":"), url}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
# TODO: get profile URLs other than user.ap_id
|
||||||
|
profile_urls = [user.ap_id]
|
||||||
|
|
||||||
bio
|
bio
|
||||||
|> CommonUtils.format_input("text/plain", mentions_format: :full)
|
|> CommonUtils.format_input("text/plain",
|
||||||
|
mentions_format: :full,
|
||||||
|
rel: &RelMe.maybe_put_rel_me(&1, profile_urls)
|
||||||
|
)
|
||||||
|> elem(0)
|
|> elem(0)
|
||||||
|> Formatter.emojify(emoji)
|
|> Formatter.emojify(emoji)
|
||||||
end
|
end
|
||||||
|
51
lib/pleroma/web/rel_me.ex
Normal file
51
lib/pleroma/web/rel_me.ex
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.RelMe do
|
||||||
|
@hackney_options [
|
||||||
|
pool: :media,
|
||||||
|
timeout: 2_000,
|
||||||
|
recv_timeout: 2_000,
|
||||||
|
max_body: 2_000_000
|
||||||
|
]
|
||||||
|
|
||||||
|
if Mix.env() == :test do
|
||||||
|
def parse(url) when is_binary(url), do: parse_url(url)
|
||||||
|
else
|
||||||
|
def parse(url) when is_binary(url) do
|
||||||
|
Cachex.fetch!(:rel_me_cache, url, fn _ ->
|
||||||
|
{:commit, parse_url(url)}
|
||||||
|
end)
|
||||||
|
rescue
|
||||||
|
e -> {:error, "Cachex error: #{inspect(e)}"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(_), do: {:error, "No URL provided"}
|
||||||
|
|
||||||
|
defp parse_url(url) do
|
||||||
|
{:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: @hackney_options)
|
||||||
|
|
||||||
|
data =
|
||||||
|
Floki.attribute(html, "link[rel=me]", "href") ++ Floki.attribute(html, "a[rel=me]", "href")
|
||||||
|
|
||||||
|
{:ok, data}
|
||||||
|
rescue
|
||||||
|
e -> {:error, "Parsing error: #{inspect(e)}"}
|
||||||
|
end
|
||||||
|
|
||||||
|
def maybe_put_rel_me("http" <> _ = target_page, profile_urls) when is_list(profile_urls) do
|
||||||
|
{:ok, rel_me_hrefs} = parse(target_page)
|
||||||
|
|
||||||
|
true = Enum.any?(rel_me_hrefs, fn x -> x in profile_urls end)
|
||||||
|
|
||||||
|
"me"
|
||||||
|
rescue
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def maybe_put_rel_me(_, _) do
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
14
test/fixtures/rel_me_anchor.html
vendored
Normal file
14
test/fixtures/rel_me_anchor.html
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<article>
|
||||||
|
<h1>Lorem ipsum</h1>
|
||||||
|
<p>Lorem ipsum dolor sit ameph, …</p>
|
||||||
|
<a rel="me" href="https://social.example.org/users/lain">lain’s account</a>
|
||||||
|
</article>
|
||||||
|
</body>
|
||||||
|
</html>
|
14
test/fixtures/rel_me_link.html
vendored
Normal file
14
test/fixtures/rel_me_link.html
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Blog</title>
|
||||||
|
<link rel="me" href="https://social.example.org/users/lain"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<article>
|
||||||
|
<h1>Lorem ipsum</h1>
|
||||||
|
<p>Lorem ipsum dolor sit ameph, …</p>
|
||||||
|
</article>
|
||||||
|
</body>
|
||||||
|
</html>
|
13
test/fixtures/rel_me_null.html
vendored
Normal file
13
test/fixtures/rel_me_null.html
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<article>
|
||||||
|
<h1>Lorem ipsum</h1>
|
||||||
|
<p>Lorem ipsum dolor sit ameph, …</p>
|
||||||
|
</article>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1054,6 +1054,22 @@ defmodule Pleroma.UserTest do
|
|||||||
|
|
||||||
assert expected_text == User.parse_bio(bio, user)
|
assert expected_text == User.parse_bio(bio, user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "Adds rel=me on linkbacked urls" do
|
||||||
|
user = insert(:user, ap_id: "http://social.example.org/users/lain")
|
||||||
|
|
||||||
|
bio = "http://example.org/rel_me/null"
|
||||||
|
expected_text = "<a href=\"#{bio}\">#{bio}</a>"
|
||||||
|
assert expected_text == User.parse_bio(bio, user)
|
||||||
|
|
||||||
|
bio = "http://example.org/rel_me/link"
|
||||||
|
expected_text = "<a href=\"#{bio}\">#{bio}</a>"
|
||||||
|
assert expected_text == User.parse_bio(bio, user)
|
||||||
|
|
||||||
|
bio = "http://example.org/rel_me/anchor"
|
||||||
|
expected_text = "<a href=\"#{bio}\">#{bio}</a>"
|
||||||
|
assert expected_text == User.parse_bio(bio, user)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "bookmarks" do
|
test "bookmarks" do
|
||||||
|
55
test/web/rel_me_test.exs
Normal file
55
test/web/rel_me_test.exs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
defmodule Pleroma.Web.RelMeTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
setup do
|
||||||
|
Tesla.Mock.mock(fn
|
||||||
|
%{
|
||||||
|
method: :get,
|
||||||
|
url: "http://example.com/rel_me/anchor"
|
||||||
|
} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor.html")}
|
||||||
|
|
||||||
|
%{
|
||||||
|
method: :get,
|
||||||
|
url: "http://example.com/rel_me/link"
|
||||||
|
} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_link.html")}
|
||||||
|
|
||||||
|
%{
|
||||||
|
method: :get,
|
||||||
|
url: "http://example.com/rel_me/null"
|
||||||
|
} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}
|
||||||
|
end)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
test "parse/1" do
|
||||||
|
hrefs = ["https://social.example.org/users/lain"]
|
||||||
|
|
||||||
|
assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/null") == {:ok, []}
|
||||||
|
assert {:error, _} = Pleroma.Web.RelMe.parse("http://example.com/rel_me/error")
|
||||||
|
|
||||||
|
assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/link") == {:ok, hrefs}
|
||||||
|
assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/anchor") == {:ok, hrefs}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "maybe_put_rel_me/2" do
|
||||||
|
profile_urls = ["https://social.example.org/users/lain"]
|
||||||
|
attr = "me"
|
||||||
|
fallback = nil
|
||||||
|
|
||||||
|
assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/null", profile_urls) ==
|
||||||
|
fallback
|
||||||
|
|
||||||
|
assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/error", profile_urls) ==
|
||||||
|
fallback
|
||||||
|
|
||||||
|
assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/anchor", profile_urls) ==
|
||||||
|
attr
|
||||||
|
|
||||||
|
assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/link", profile_urls) ==
|
||||||
|
attr
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user