From b0fa6dcce0f7d16b520e4e78a580ef378b57c025 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Wed, 19 Dec 2018 09:47:41 +0300 Subject: [PATCH 1/3] fix parse mentions --- lib/pleroma/formatter.ex | 1 + test/formatter_test.exs | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 9401689cb9..8977ba7534 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -24,6 +24,7 @@ def parse_mentions(text) do Regex.scan(regex, text) |> List.flatten() + |> Enum.map(fn v -> String.replace(v, ~r/^@@/, "@") end) |> Enum.uniq() |> Enum.map(fn "@" <> match = full_match -> {full_match, User.get_cached_by_nickname(match)} diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 6cdfa4167a..44d13969b5 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -215,8 +215,10 @@ test "parses tags in the text" do end test "it can parse mentions and return the relevant users" do - text = "@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me" + text = + "@@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me and @o" + o = insert(:user, %{nickname: "o"}) gsimg = insert(:user, %{nickname: "gsimg"}) archaeme = insert(:user, %{nickname: "archaeme"}) archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"}) @@ -224,7 +226,8 @@ test "it can parse mentions and return the relevant users" do expected_result = [ {"@gsimg", gsimg}, {"@archaeme", archaeme}, - {"@archaeme@archae.me", archaeme_remote} + {"@archaeme@archae.me", archaeme_remote}, + {"@o", o} ] assert Formatter.parse_mentions(text) == expected_result -- GitLab From 20818ed9da3ada2c5882e9ce2f6e31b0d164e541 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Wed, 19 Dec 2018 14:15:39 +0300 Subject: [PATCH 2/3] fix parse mentions --- lib/pleroma/formatter.ex | 5 ++--- test/formatter_test.exs | 8 +++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 8977ba7534..c33ca36b6a 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -24,10 +24,9 @@ def parse_mentions(text) do Regex.scan(regex, text) |> List.flatten() - |> Enum.map(fn v -> String.replace(v, ~r/^@@/, "@") end) |> Enum.uniq() - |> Enum.map(fn "@" <> match = full_match -> - {full_match, User.get_cached_by_nickname(match)} + |> Enum.map(fn nickname -> + {nickname, User.get_cached_by_nickname(String.trim_leading(nickname, "@"))} end) |> Enum.filter(fn {_match, user} -> user end) end diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 44d13969b5..41a420ed2a 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -216,18 +216,20 @@ test "parses tags in the text" do test "it can parse mentions and return the relevant users" do text = - "@@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me and @o" + "@@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me and @o and @@@jimm" o = insert(:user, %{nickname: "o"}) + jimm = insert(:user, %{nickname: "jimm"}) gsimg = insert(:user, %{nickname: "gsimg"}) archaeme = insert(:user, %{nickname: "archaeme"}) archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"}) expected_result = [ - {"@gsimg", gsimg}, + {"@@gsimg", gsimg}, {"@archaeme", archaeme}, {"@archaeme@archae.me", archaeme_remote}, - {"@o", o} + {"@o", o}, + {"@@jimm", jimm} ] assert Formatter.parse_mentions(text) == expected_result -- GitLab From 9374e98ab54dd9cf6ebe1c897b66433fa6dd507c Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Wed, 19 Dec 2018 18:19:09 +0300 Subject: [PATCH 3/3] fix parse mentions --- lib/pleroma/formatter.ex | 14 ++++++++------ test/formatter_test.exs | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index c33ca36b6a..72fe9640ba 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -7,6 +7,9 @@ defmodule Pleroma.Formatter do @tag_regex ~r/((?<=[^&])|\A)(\#)(\w+)/u @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/ + # Modified from https://www.w3.org/TR/html5/forms.html#valid-e-mail-address + @mentions_regex ~r/@[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]*@?[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/u + def parse_tags(text, data \\ %{}) do Regex.scan(@tag_regex, text) |> Enum.map(fn ["#" <> tag = full_tag | _] -> {full_tag, String.downcase(tag)} end) @@ -17,16 +20,15 @@ def parse_tags(text, data \\ %{}) do end).() end + @doc "Parses mentions text and returns list {nickname, user}." + @spec parse_mentions(binary()) :: list({binary(), User.t()}) def parse_mentions(text) do - # Modified from https://www.w3.org/TR/html5/forms.html#valid-e-mail-address - regex = - ~r/@[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]*@?[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/u - - Regex.scan(regex, text) + Regex.scan(@mentions_regex, text) |> List.flatten() |> Enum.uniq() |> Enum.map(fn nickname -> - {nickname, User.get_cached_by_nickname(String.trim_leading(nickname, "@"))} + with nickname <- String.trim_leading(nickname, "@"), + do: {"@" <> nickname, User.get_cached_by_nickname(nickname)} end) |> Enum.filter(fn {_match, user} -> user end) end diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 41a420ed2a..584700b6a5 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -225,11 +225,11 @@ test "it can parse mentions and return the relevant users" do archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"}) expected_result = [ - {"@@gsimg", gsimg}, + {"@gsimg", gsimg}, {"@archaeme", archaeme}, {"@archaeme@archae.me", archaeme_remote}, {"@o", o}, - {"@@jimm", jimm} + {"@jimm", jimm} ] assert Formatter.parse_mentions(text) == expected_result -- GitLab