Merge branch 'fix/parse-user-bio' into 'develop'

Parse user's bio on register

See merge request pleroma/pleroma!492
This commit is contained in:
lambda 2018-12-03 16:31:00 +00:00
commit 88b05aeabb
7 changed files with 64 additions and 20 deletions

View File

@ -4,6 +4,8 @@ defmodule Pleroma.User do
import Ecto.{Changeset, Query} import Ecto.{Changeset, Query}
alias Pleroma.{Repo, User, Object, Web, Activity, Notification} alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
alias Comeonin.Pbkdf2 alias Comeonin.Pbkdf2
alias Pleroma.Formatter
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
alias Pleroma.Web.{OStatus, Websub, OAuth} alias Pleroma.Web.{OStatus, Websub, OAuth}
alias Pleroma.Web.ActivityPub.{Utils, ActivityPub} alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
@ -802,4 +804,18 @@ def wait_and_refresh(timeout, %User{} = a, %User{} = b) do
:error :error
end end
end end
def parse_bio(bio, user \\ %User{info: %{source_data: %{}}}) do
mentions = Formatter.parse_mentions(bio)
tags = Formatter.parse_tags(bio)
emoji =
(user.info.source_data["tag"] || [])
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
{String.trim(name, ":"), url}
end)
CommonUtils.format_input(bio, mentions, tags, "text/plain") |> Formatter.emojify(emoji)
end
end end

View File

@ -55,7 +55,7 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do
user_params = user_params =
%{} %{}
|> add_if_present(params, "display_name", :name) |> add_if_present(params, "display_name", :name)
|> add_if_present(params, "note", :bio) |> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value)} end)
|> add_if_present(params, "avatar", :avatar, fn value -> |> add_if_present(params, "avatar", :avatar, fn value ->
with %Plug.Upload{} <- value, with %Plug.Upload{} <- value,
{:ok, object} <- ActivityPub.upload(value, type: :avatar) do {:ok, object} <- ActivityPub.upload(value, type: :avatar) do

View File

@ -132,7 +132,7 @@ def register_user(params) do
params = %{ params = %{
nickname: params["nickname"], nickname: params["nickname"],
name: params["fullname"], name: params["fullname"],
bio: params["bio"], bio: User.parse_bio(params["bio"]),
email: params["email"], email: params["email"],
password: params["password"], password: params["password"],
password_confirmation: params["confirm"] password_confirmation: params["confirm"]

View File

@ -448,27 +448,16 @@ defp build_info_cng(user, params) do
User.Info.profile_update(user.info, info_params) User.Info.profile_update(user.info, info_params)
end end
defp add_profile_emoji(user, params) do defp parse_profile_bio(user, params) do
if bio = params["description"] do if bio = params["description"] do
mentions = Formatter.parse_mentions(bio) Map.put(params, "bio", User.parse_bio(bio, user))
tags = Formatter.parse_tags(bio)
emoji =
(user.info.source_data["tag"] || [])
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
{String.trim(name, ":"), url}
end)
bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
else else
params params
end end
end end
def update_profile(%{assigns: %{user: user}} = conn, params) do def update_profile(%{assigns: %{user: user}} = conn, params) do
params = add_profile_emoji(user, params) params = parse_profile_bio(user, params)
info_cng = build_info_cng(user, params) info_cng = build_info_cng(user, params)
with changeset <- User.update_changeset(user, params), with changeset <- User.update_changeset(user, params),

View File

@ -1253,14 +1253,21 @@ test "returns the favorites of a user", %{conn: conn} do
describe "updating credentials" do describe "updating credentials" do
test "updates the user's bio", %{conn: conn} do test "updates the user's bio", %{conn: conn} do
user = insert(:user) user = insert(:user)
user2 = insert(:user)
conn = conn =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"note" => "I drink #cofe"}) |> patch("/api/v1/accounts/update_credentials", %{
"note" => "I drink #cofe with @#{user2.nickname}"
})
assert user = json_response(conn, 200) assert user = json_response(conn, 200)
assert user["note"] == "I drink #cofe"
assert user["note"] ==
"I drink <a href=\"http://localhost:4001/tag/cofe\">#cofe</a> with <span><a href=\"#{
user2.ap_id
}\">@<span>#{user2.nickname}</span></a></span>"
end end
test "updates the user's locking status", %{conn: conn} do test "updates the user's locking status", %{conn: conn} do

View File

@ -955,18 +955,21 @@ test "it returns a user's friends", %{conn: conn} do
describe "POST /api/account/update_profile.json" do describe "POST /api/account/update_profile.json" do
test "it updates a user's profile", %{conn: conn} do test "it updates a user's profile", %{conn: conn} do
user = insert(:user) user = insert(:user)
user2 = insert(:user)
conn = conn =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post("/api/account/update_profile.json", %{ |> post("/api/account/update_profile.json", %{
"name" => "new name", "name" => "new name",
"description" => "new description" "description" => "hi @#{user2.nickname}"
}) })
user = Repo.get!(User, user.id) user = Repo.get!(User, user.id)
assert user.name == "new name" assert user.name == "new name"
assert user.bio == "new description"
assert user.bio ==
"hi <span><a class='mention' href='#{user2.ap_id}'>@<span>#{user2.nickname}</span></a></span>"
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end end

View File

@ -257,6 +257,35 @@ test "it registers a new user and returns the user." do
UserView.render("show.json", %{user: fetched_user}) UserView.render("show.json", %{user: fetched_user})
end end
test "it registers a new user and parses mentions in the bio" do
data1 = %{
"nickname" => "john",
"email" => "john@gmail.com",
"fullname" => "John Doe",
"bio" => "test",
"password" => "bear",
"confirm" => "bear"
}
{:ok, user1} = TwitterAPI.register_user(data1)
data2 = %{
"nickname" => "lain",
"email" => "lain@wired.jp",
"fullname" => "lain iwakura",
"bio" => "@john test",
"password" => "bear",
"confirm" => "bear"
}
{:ok, user2} = TwitterAPI.register_user(data2)
expected_text =
"<span><a class='mention' href='#{user1.ap_id}'>@<span>john</span></a></span> test"
assert user2.bio == expected_text
end
@moduletag skip: "needs 'registrations_open: false' in config" @moduletag skip: "needs 'registrations_open: false' in config"
test "it registers a new user via invite token and returns the user." do test "it registers a new user via invite token and returns the user." do
{:ok, token} = UserInviteToken.create_token() {:ok, token} = UserInviteToken.create_token()